IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Entrée sortie fichiers


Sujet :

C

  1. #61
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Sinon, pour ce qui est de la recherche du problème, j'ai pris plusieurs semaines pour prendre mon temps d'écrire le code et de chercher les éventuelles erreurs. Je n'ai pas trouvé ce qui ne marchait pas.
    Parce que tu ne fais pas de tests unitaires. Teste chacune de tes fonctions pour voir si elles font vraiment ce que tu attends d'elles, en commençant par les plus élémentaires et en allant vers les plus complexes. C'est impossible que toutes tes fonctions soient correctes, sinon le programme marcherait. C'est logique. Je vois des milliers d'erreurs dans ton code mais je ne révèlerai aucune d'entre elles avant que n'aies fais ce que je t'ai demandé. C'est pour ton bien que je fais ça, par pour te faire perdre ton temps. Si tu ne sais pas comment on fait un test unitaire, je peux te faire une petite démo, si tu y tiens. Au fait, quel compilateur ou EDI utilises-tu ?

  2. #62
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    J'utilise gcc.
    J'ai déjà essayé plein de fois de faire des tests pour déterminer les erreurs, mais le problème c'est que pour vous faire des tests ça peut paraître simple mais pour moi ça implique refaire des petits programmes qui contiendront eux aussi des erreurs et ça m'embarque dans une spirale infinie. J'ai enlevé toutes les erreurs de frappe (parenthèses manquantes, etc) que j'ai trouvées, mais je n'arrive pas à voir les erreurs de segmentation fault, c'est l'erreur que je reçois tout le temps.
    Enfin je vais essayer quand même :

    J'utilise pour mes tests le texte suivant :

    Jan 12 10:08:06 zejnkefj
    Jan 12 10:10:06 jnrgjnrgjng
    Jan 12 10:12:06 ezrzfggtgbtgbn
    Jan 12 10:14:06 hhhhhhhhhhhhhhht
    Jan 12 10:16:06 fezgrgrht
    Feb 12 10:18:06 dds
    Mar 12 10:20:06 dddsfds
    Mar 12 10:20:06 zdfefefs
    May 12 10:24:06 dffsdfd
    Jun 12 10:26:06 feefdfvbdgb
    Jul 12 10:28:06 bgbdgfkjnifnifgnjnkfgjnkfg
    Sep 12 10:30:06 qfqsddswxgtre
    Oct 12 10:32:06 eee
    Voici le test unitaire pour tester uniquement les deux premières fonctions string_to_time_t et get_date :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
     
    #define _ENDOFLINE '\n' /*Marque de fin de ligne*/
     
     
    time_t string_to_time_t(const char *s)
    {
            time_t rawtime;
            struct tm *timeinfo;
            char month_s[4] ;
            int month,day,hour,minute,second;
     
            if (sscanf(s, "%3s %d %d:%d:%d", month_s, &day, &hour, &minute, &second) != 5)
    		fprintf(stderr,"Error 001: unknown date format\n");
    	else
    	{    
    	        char *month_names[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    	        int i = 0;
    	        while ( i < 12 &&  strcmp(month_s,month_names[i]) != 0 )
    	                i++;
    		if (i >= 12)
    			 fprintf(stderr,"Error 002: unknown date format\n");
    		else
    		{			
    	        month=i;
     
    	        time (&rawtime);
    	       	timeinfo=localtime(&rawtime);
    	        timeinfo->tm_mon=month;
    	        timeinfo->tm_mday=day;
    	        timeinfo->tm_hour=hour;
    	        timeinfo->tm_min=minute;
    	        timeinfo->tm_sec=second;
    	        return mktime(timeinfo);
    		}
    	}
    }
     
    time_t get_date(FILE *fp)
    {
    	static char s[16];
    	return string_to_time_t(fgets(s,16,fp));
    }
     
    int main(int argc, char **argv)
    {
    	FILE *fp = fopen("texttest","rb");
    	if (fp == NULL)
    		fprintf(stderr,"File can't be opened\n");
    	else
    		printf("La date est : %lu\n",(unsigned long)get_date(fp));
    	fclose(fp);
    	return 0;
    }
    Résultat : ça marche.

    Ensuite, le test de la fonction goto_beginning_of_next_line :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
     
    #define _ENDOFLINE '\n' /*Marque de fin de ligne*/
     
     
     
    int goto_beginning_of_next_line(FILE *fp)
    {
            int c;
            do
                    c=fgetc(fp) ;
            while ((c != _ENDOFLINE) &&  (c != EOF));
            if (c == _ENDOFLINE)
                    return 0;
            else
                    return 1;
    }
     
     
     
     
    int main(int argc, char **argv)
    {
    	int i,j;
    	char c;
    	FILE *fp = fopen("texttest","rb");
    	if (fp == NULL)
    		fprintf(stderr,"File can't be opened\n");
    	else
    		for(i=0;i<10;i++)
    		{
    			goto_beginning_of_next_line(fp);	
    			for(j=0;j<16;j++)
    				putchar(c = getc(fp));
    		printf("\n");
    		}			
    	fclose(fp);
    	return 0;
    }
    résultat : ça marche aussi.



    Pour continuer, voici le test de la fonction goto_beginning_of_current_line :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
     
    #define _ENDOFLINE '\n' /*Marque de fin de ligne*/
     
    void goto_beginning_of_current_line(FILE *fp)
    {
        int c = '\0' ;
     
        while (ftell(fp) != 0 && c != _ENDOFLINE)
        {
            fseek(fp,-1,SEEK_CUR);
            c=fgetc(fp); // c ne peut jamais être EOF ici, si ?
            if (c != _ENDOFLINE)
                    fseek(fp,-1,SEEK_CUR);
        }
    }
     
    int main(int argc, char **argv)
    {
    	int i,j;
    	char c;
    	FILE *fp = fopen("texttest","rb");
    	if (fp == NULL)
    		fprintf(stderr,"File can't be opened\n");
    	else
    		for(i=0;i<10;i++)
    		{
    			fseek(fp,i*20,SEEK_SET);
    			goto_beginning_of_current_line(fp);	
    			for(j=0;j<16;j++)
    				putchar(c = getc(fp));
    		printf("\n");
    		}			
    	fclose(fp);
    	return 0;
    }
    résultat : ça marche.

    J'ai vérifié avec les propriétés système du fichier que la fonction filesize marchait aussi.
    Par ailleurs, le main ne contient pas d'erreurs non plus, car je l'ai utilisé tout du long et ça marche.

    Enfin, en utilisant le fichier suivant,
    Jan 12 10:08:06 zejnkefj
    Jan 12 10:08:06 jnrgjnrgjng
    Jan 12 10:08:06 ezrzfggtgbtgbn
    Jan 12 10:08:06 hhhhhhhhhhhhhhht
    Jan 12 10:08:06 fezgrgrht
    Jan 12 10:08:06 dds
    Jan 12 10:08:06 dddsfds
    Jan 12 10:08:06 zdfefefs
    Jan 12 10:08:06 dffsdfd
    Jan 12 10:08:06 feefdfvbdgb
    Jan 12 10:08:06 bgbdgfkjnifnifgnjnkfgjnkfg
    Jan 12 10:08:06 qfqsddswxgtre
    Jan 12 10:08:06 eee
    je teste l'avant-dernière fonction de mon programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
     
    #define _ENDOFLINE '\n' /*Marque de fin de ligne*/
     
     
    time_t string_to_time_t(const char *s)
    {
            time_t rawtime;
            struct tm *timeinfo;
            char month_s[4] ;
            int month,day,hour,minute,second;
     
            if (sscanf(s, "%3s %d %d:%d:%d", month_s, &day, &hour, &minute, &second) != 5)
    		fprintf(stderr,"Error 001: unknown date format\n");
    	else
    	{    
    	        char *month_names[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    	        int i = 0;
    	        while ( i < 12 &&  strcmp(month_s,month_names[i]) != 0 )
    	                i++;
    		if (i >= 12)
    			 fprintf(stderr,"Error 002: unknown date format\n");
    		else
    		{			
    	        month=i;
     
    	        time (&rawtime);
    	       	timeinfo=localtime(&rawtime);
    	        timeinfo->tm_mon=month;
    	        timeinfo->tm_mday=day;
    	        timeinfo->tm_hour=hour;
    	        timeinfo->tm_min=minute;
    	        timeinfo->tm_sec=second;
    	        return mktime(timeinfo);
    		}
    	}
    }
     
    time_t get_date(FILE *fp)
    {
    	static char s[16];
    	return string_to_time_t(fgets(s,16,fp));
    }
     
     
    int goto_beginning_of_next_line(FILE *fp)
    {
            int c;
            do
                    c=fgetc(fp) ;
            while ((c != _ENDOFLINE) &&  (c != EOF));
            if (c == _ENDOFLINE)
                    return 0;
            else
                    return 1;
    }
     
    void goto_beginning_of_current_line(FILE *fp)
    {
        int c = '\0' ;
     
        while (ftell(fp) != 0 && c != _ENDOFLINE)
        {
            fseek(fp,-1,SEEK_CUR);
            c=fgetc(fp); // c ne peut jamais être EOF ici, si ?
            if (c != _ENDOFLINE)
                    fseek(fp,-1,SEEK_CUR);
        }
    }
     
     
    void goto_first_occurrence(FILE *fp, time_t t)
    {
            time_t test = t;
            goto_beginning_of_current_line(fp);
            while (ftell(fp) != 0 && test == t)
            {
                    fseek(fp,-1,SEEK_CUR);
                    goto_beginning_of_current_line(fp);
                    test=get_date(fp);
                    goto_beginning_of_current_line(fp);
            }
            if (test != t)
                    goto_beginning_of_next_line;
    }
     
     
     
     
     
    int main(int argc, char **argv)
    {
    	int i,j;
    	char c;
    	FILE *fp = fopen("texttest","rb");
    	if (fp == NULL)
    		fprintf(stderr,"File can't be opened\n");
    	else
     
    		fseek(fp,0,SEEK_END);
    		goto_first_occurrence(fp, string_to_time_t("Jan 12 10:08:06"));	
    		for(j=0;j<20;j++)
    			putchar(c = getc(fp));
    		printf("\n");
     
    	fclose(fp);
    	return 0;
    }
    ça marche aussi.

    Bref, tout marche, sauf la fonction search_date que je n'arrive pas à défragmenter en fonctions plus petites, et pour laquelle je reçois un segmentation fault que je ne sais pas expliquer.

  3. #63
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    C'est bien. Ca me rassure. Au moins on est sûr que c'est vraiment dans la fonction search_date et uniquement cette fonction qu'il y a des problèmes. C'est le protocole qu'il faut toujours respecter sur le forum si on veut pouvoir trouver efficacement de l'aide.

    Bon, dans goto_first_occurrence il y a quand même une toute petite faute.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void goto_first_occurrence(FILE *fp, time_t t)
    {
    	time_t test = t;
    	goto_beginning_of_current_line(fp);
    	while (ftell(fp) != 0 && test == t)
    	{
            	fseek(fp,-1,SEEK_CUR);
    		goto_beginning_of_current_line(fp);
            	test=get_date(fp);
            	goto_beginning_of_current_line(fp);
    	}
    	if (test != t)
    		goto_beginning_of_next_line(fp);
    }
    Dans search_date cette partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        fseek(fp,max,SEEK_SET);
        goto_beginning_of_current_line(fp);
        t_max=get_date(fp);
    Le fseek va te positionner après le dernier caractère du fichier, qui est un '\n' puisque le fichier est constitué de lignes. Suite au goto_beginning_of_current_line, tu restes là où tu es ! Car t'es déjà juste après un '\n'.

    Un autre truc qui me paraît bizarre : lorsque tu ne trouves aucune occurrence de la date dans le fichier, tu places le curseur en fin de fichier. C'est bien ce que tu souhaites ?

  4. #64
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Effectivement, il manque un petit fp, merci.
    Voyez-vous d'autres erreurs que mes tests n'ont pas détecté ?

    Pour ce qui concerne la deuxième erreur, ceci marche-t-il ?

    fseek(fp,max-1,SEEK_SET);
    goto_beginning_of_current_line(fp);
    t_max=get_date(fp);

    Je ne suis pas sûr de comprendre le sens de votre question. Je pense avoir assez bien détaillé ce que je souhaite obtenir dans mon post de 12h27.
    S'il n'y a pas d'occurrence de la date dans le fichier, mais que la date à chercher est comprise entre les deux extrémités du log, alors je souhaite que fp pointe sur la date directement après la date à chercher.
    J'avais l'impression que max était justement la ligne suivante, à la fin du while, non ?

    Par ailleurs, j'aimerais remplacer le calcul du k, comme simple milieu, par un calcul un peu plus évolué se fondant sur les barycentres, car j'ai parfois de longs log et la date que je cherche est souvent récente, donc il pourrait être malin de tester directement un k proche de la date.
    Voici ce que j'ai fait, mais ça ne marche pas (boucle infinie). Voyez-vous pourquoi ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    long function2(FILE*fp, long min, long max, time_t t_target)
    {
    	time_t t_min,t_max ;
    	fseek(fp, min, SEEK_SET);
    	goto_beginning_of_current_line (fp);
    	t_min=get_date(fp);
    	fseek(fp, max-1, SEEK_SET);
    	goto_beginning_of_current_line (fp);
    	t_max=get_date(fp);
    	float weight = (float)(t_target - t_min) / (float)(t_max - t_min);
    	long difference = max - min;
    	return ((long) weight * difference);
    }

  5. #65
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Je sais que ce thread est long, et j'en suis désolée. Mais j'ai l'impression que la fin approche. De fait, ça compile déjà. Merci infiniment encore une fois à tous et particulièrement à Melem de m'avoir permis d'en arriver là. Pouvez-vous m'aider à répondre aux dernières petites questions que je me pose, et à vérifier qu'il n'y a pas d'erreur que des tests mal faits ne sauraient révéler, afin de pouvoir clore ce topic une fois pour toute ?
    Merci.

  6. #66
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    déjà il te manque une parenthèse pour le dernier cast..

    Quand tu écris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	return ((long) weight * difference);
    tu castes weight AVANT d'avoir effectué la multiplication.. Comme c'est un poids, ça te donnera toujours 0...

    Il faudrait donc écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	return ((long) (weight * difference) );
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  7. #67
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    ah d'accord merci beaucoup pour cette remarque, je pensais que la priorité par défaut était dans l'autre sens.
    J'aurais quand même du ajouter des parenthèses par précaution.
    Mais ça ne marche apparemment toujours pas, il y a encore une boucle infinie.
    Voyez-vous une autre erreur ?
    Autrement, je peux vous copier tout mon programme, peut-être que j'ai simplement mal inséré ma nouvelle fonction dans le programme existant. Le voulez-vous ?

  8. #68
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Ok, je pense que j'ai compris l'erreur de function2, il faut tester si max est le dernier octet du fichier, et lui soustraire 1 si c'est le cas. Dites-moi si je me trompe. Il reste par ailleurs quelques questions sans réponse dans le post 64.

    Permettez-moi également (désolé d'avance) de revenir sur le problème de la portabilité. Tel quel, cela ne marche que sur Linux, on est bien d'accord? Pourrait-on faire un programme qui écrit un saut de ligne en mode texte, puis regarde comment il a été sauvegardé en mode binaire, afin de modifier en conséquence le define du début ? Par ailleurs, tel qu'il est, ce define est un caractère, faudrait-il donc modifier tous les tests (avec strcmp?) pour que ça marche même quand c'est \r\n (et également certains reculs, qui au lieu de -1 seraient -2) ?

  9. #69
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Non, il y a encore parfois des boucles infinies .
    Pouvez-vous m'aider s'il vous plait?

  10. #70
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Je viens également de me rendre compte d'un autre problème : si je cherche une date de plus d'un mois (puisque l'on est en janvier), mon get_date va compléter avec l'année en cours, et donc search_date renverra un résultat erroné. Voyez-vous comment contourner ce problème ?
    Les questions commencent à s'accumuler, excusez-moi.

  11. #71
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Réserve le barycentre pour une autre fois. Pour le moment, concentre-toi sur le vrai problème. Je viens de tester le code et, après les remarques que j'ai déjà donné, ça marche si on cherche une date qui se trouve dans le fichier, et si la date est une date de l'année en cours. Ça aurait déjà du te mettre sur la voie. Pour faire fonctionner avec une date qui n'est pas forcément dans le fichier, il suffit d'ajouter goto_beginning_of_current_line(fp); à la fin de search_date, après le fseek, c'est quand même évident non ?

    si je cherche une date de plus d'un mois (puisque l'on est en janvier), mon get_date va compléter avec l'année en cours, et donc search_date renverra un résultat erroné. Voyez-vous comment contourner ce problème ?
    Tu peux ajouter un test dans string_to_time_t comme (là je vais vraiment présenter une méthode ultra simple mais à toi de rendre ton programme plus solide) : si le mois de la chaîne à convertir est > le mois en cours, il s'agit d'une date déjà passée, c'est-à-dire de l'année dernière.

    Et voilà, tous tes problèmes sont réglés. Voici le code complet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <stdlib.h>
     
    #define _ENDOFLINE '\n' /*Marque de fin de ligne*/
     
     
     
     
     
    time_t string_to_time_t(const char *s)
    {
            time_t rawtime;
            struct tm *timeinfo;
            char month_s[4] ;
            int month,day,hour,minute,second;
     
            if (sscanf(s, "%3s %d %d:%d:%d", month_s, &day, &hour, &minute, &second) != 5)
    		fprintf(stderr,"Error 001: unknown date format\n");
    	else
    	{
    	        char *month_names[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    	        int i = 0;
    	        while ( i < 12 &&  strcmp(month_s,month_names[i]) != 0 )
    	                i++;
    		if (i >= 12)
    			 fprintf(stderr,"Error 002: unknown date format\n");
    		else
    		{
    	        month=i;
     
    	        time (&rawtime);
    	       	timeinfo=localtime(&rawtime);
     
                    if (month > timeinfo->tm_mon)
                        timeinfo->tm_year--;
    	        timeinfo->tm_mon=month;
    	        timeinfo->tm_mday=day;
    	        timeinfo->tm_hour=hour;
    	        timeinfo->tm_min=minute;
    	        timeinfo->tm_sec=second;
    	        return mktime(timeinfo);
    		}
    	}
    }
     
     
     
     
     
    time_t get_date(FILE *fp, char *s)
    {
    	return string_to_time_t(fgets(s,16,fp));
    }
     
     
     
     
     
    int goto_beginning_of_next_line(FILE *fp)
    {
    	int c;
    	do
    		c=fgetc(fp) ;
    	while ((c != _ENDOFLINE) &&  (c != EOF));
    	if (c == _ENDOFLINE)
    		return 0;
    	else
    		return 1;
    }
     
     
     
     
    void goto_beginning_of_current_line(FILE *fp)
    {
        int c = '\0' ;
     
        while (ftell(fp) != 0 && c != _ENDOFLINE)
        {
            fseek(fp,-1,SEEK_CUR);
    	c=fgetc(fp); // c ne peut jamais être EOF ici, si ?
    	if (c != _ENDOFLINE)
            	fseek(fp,-1,SEEK_CUR);
        }
    }
     
     
     
    long filesize(FILE * f)
    {
        long pos, size;
     
        pos = ftell(f);
        fseek(f, 0, SEEK_END);
        size = ftell(f);
        fseek(f, pos, SEEK_SET);
     
        return size;
    }
     
    void goto_first_occurrence(FILE *fp, time_t t)
    {
    	time_t test = t;
    	char s[16];
    	goto_beginning_of_current_line(fp);
    	while (ftell(fp) != 0 && test == t)
    	{
            	fseek(fp,-1,SEEK_CUR);
                goto_beginning_of_current_line(fp);
            	test=get_date(fp, s);
            	goto_beginning_of_current_line(fp);
    	}
    	if (test != t)
    		goto_beginning_of_next_line(fp);
    }
     
    int search_date(FILE *fp, time_t t_target)
    {
    	long min=0, max=filesize(fp), k= max/2;
    	time_t t_min, t_max, t_test;
    	char s[16];
     
    	if (max == 0)
    	{
    		fseek(fp,0,SEEK_SET);
    		return 1;
    	}
     
    	fseek(fp,min,SEEK_SET);
    	t_min=get_date(fp, s);
    	fseek(fp,max-1,SEEK_SET);
    	goto_beginning_of_current_line(fp);
    	t_max=get_date(fp, s);
     
    	if(t_target<t_min)
    	{
    		fseek(fp,0,SEEK_SET);
    		return 0;
    	}
    	if(t_target>t_max)
    	{
    		fseek(fp,0,SEEK_SET);
    		return 2;
    	}
     
    	while (abs(max-min) > 1)
    	{
    		fseek(fp, k, SEEK_SET);
    		goto_beginning_of_current_line(fp);
    		t_test = get_date(fp, s);
     
    		if(t_target == t_test)
    		{
    			goto_first_occurrence(fp,t_test);
    			return 0;
    		}
    		else
    		{
    			if(t_target < t_test)
    				max=k;
    			else
    				min=k;
    			k = (min + max) / 2;
    		}
    	}
    	fseek(fp,max,SEEK_SET);
    	goto_beginning_of_current_line(fp);
     
    	return 0;
    }
     
     
    int main(int argc, char **argv)
    {
    	FILE *fp = fopen("log","rb");
    	if (fp == NULL)
    		fprintf(stderr,"File can't be opened\n");
    	else
    	{
                    time_t time=string_to_time_t("Jan 12 10:12:07");
    	        search_date(fp,time);  // BUG
    	        // affichage de la ligne obtenue :
    	        int c;
                    do
            	        putchar(c = getc(fp));
                    while (c != _ENDOFLINE && c != EOF);
    	        fclose(fp);
    	        return 0;
           }
    }
    J'ai légèrement modifié la fonction get_date parce que c'est plus stylé comme ça. Je ne supportais plus de voir l'ancienne version, c'était trop moche.

  12. #72
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Je ne saurais comment assez vous remercier une fois de plus pour votre aide.
    Vous avez raison, ce get_date est plus joli.
    Et votre méthode pour les mois de l'année dernière me semble également très bien, je vais l'adopter.
    En revanche j'ai un peu de mal à comprendre l'utilité du goto_beginning_of_current_line(fp); à la fin de search_date, après le fseek. C'est sûr qu'il ne peut pas faire de mal, mais j'ai l'impression qu'on était déjà en début de ligne à ce moment là : quand on sort du while, max=min+1. Ceci n'arrive que si min est un curseur sur une ligne et max sur la ligne suivante, autrement on aurait retourné la ligne de min et de max dans le while. C'est donc qu'il y a un \n entre les deux, donc max est déjà en début de ligne.
    ->Pouvez-vous me dire ce qui est faux dans mon raisonnement?
    ->Sinon, j'avais modifié goto_beginning_of_current_line par rapport à celle que vous aviez proposé. Le mien est plus court, mais l'ai-je rendu faux dans certains cas particuliers?
    ->Permettez-moi également (désolé d'avance) de revenir sur le problème de la portabilité. Tel quel, cela ne marche que sur Linux, on est bien d'accord? Pourrait-on faire un programme qui écrit un saut de ligne en mode texte, puis regarde comment il a été sauvegardé en mode binaire, afin de modifier en conséquence le define du début ? Par ailleurs, tel qu'il est, ce define est un caractère, faudrait-il donc modifier tous les tests (avec strcmp?) pour que ça marche même quand c'est \r\n (et également certains reculs, qui au lieu de -1 seraient -2) ?

    -> Pour ce qui est du barycentre, voici où j'en suis (j'ai ajouté des /// à la fin des lignes que j'ai modifiées pour utiliser le barycentre. A noter que tel quel, le programme rend un résultat pour function1, donc le problème semble être dans function2 et pas dans l'insertion de ces deux fonctions au reste du programme. Voyez-vous ce qui provoque la boucle infinie ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
     
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
     
    #define _ENDOFLINE '\n' /*Marque de fin de ligne*/
     
     
     
     
     
    time_t string_to_time_t(const char *s)
    {
            time_t rawtime;
            struct tm *timeinfo;
            char month_s[4] ;
            int month,day,hour,minute,second;
     
            if (sscanf(s, "%3s %d %d:%d:%d", month_s, &day, &hour, &minute, &second) != 5)
    		fprintf(stderr,"Error 001: unknown date format\n");
    	else
    	{    
    	        char *month_names[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    	        int i = 0;
    	        while ( i < 12 &&  strcmp(month_s,month_names[i]) != 0 )
    	                i++;
    		if (i >= 12)
    			 fprintf(stderr,"Error 002: unknown date format\n");
    		else
    		{			
    	        month=i;
     
    	        time (&rawtime);
    	       	timeinfo=localtime(&rawtime);
     
                    if (month > timeinfo->tm_mon)
                        timeinfo->tm_year--;
    	        timeinfo->tm_mon=month;
    	        timeinfo->tm_mday=day;
    	        timeinfo->tm_hour=hour;
    	        timeinfo->tm_min=minute;
    	        timeinfo->tm_sec=second;
    	        return mktime(timeinfo);
    		}
    	}
    }
     
     
     
     
     
    time_t get_date(FILE *fp, char *s)
    {
    	return string_to_time_t(fgets(s,16,fp));
    }
     
     
     
     
     
    int goto_beginning_of_next_line(FILE *fp)
    {
    	int c;
    	do
    		c=fgetc(fp) ;
    	while ((c != _ENDOFLINE) &&  (c != EOF));
    	if (c == _ENDOFLINE)
    		return 0;
    	else
    		return 1;
    }
     
     
     
     
     
    /*
    old version:
    void goto_beginning_of_current_line(FILE *fp)
    {
    	int c;
    	if (ftell(fp) != 0)
    	{
    		fseek(fp,1,SEEK_CUR);
    		do
    		{
    			fseek(fp,-2,SEEK_CUR);
    			c=fgetc(fp);
    		}
    		while ( ftell(fp) - 2 >= 0 && c != '\n' );
    		if( ftell(fp) == 1 )
    			fseek(fp,-1,SEEK_CUR);
    	}
    }
    */
     
    void goto_beginning_of_current_line(FILE *fp)
    {
        int c = '\0' ;
     
        while (ftell(fp) != 0 && c != _ENDOFLINE)
        {
            fseek(fp,-1,SEEK_CUR);
    	c=fgetc(fp); 
    	if (c != _ENDOFLINE)
            	fseek(fp,-1,SEEK_CUR);
        }
    }
     
     
     
    long filesize(FILE * f)
    {
        long pos, size;
     
        pos = ftell(f);
        fseek(f, 0, SEEK_END);
        size = ftell(f);
        fseek(f, pos, SEEK_SET);
     
        return size;
    }
     
    void goto_first_occurrence(FILE *fp, time_t t)
    {
    	time_t t_test = t;
    	char s[16];
    	goto_beginning_of_current_line(fp);
    	while (ftell(fp) != 0 && t_test == t)
    	{
            	fseek(fp,-1,SEEK_CUR);
    		goto_beginning_of_current_line(fp);
            	t_test = get_date(fp,s);
            	goto_beginning_of_current_line(fp);
    	}
    	if (t_test != t)
    		goto_beginning_of_next_line(fp);
    }
     
    long function1(FILE*fp, long min, long max, time_t t_target) //////////////
    {
    	return ((min +max) / 2);
    }
     
     
     
    long function2(FILE*fp, long min, long max, time_t t_target) ////////
    {
    	time_t t_min,t_max ;
    	char s[16];
    	fseek(fp, min, SEEK_SET);
    	goto_beginning_of_current_line (fp);
    	t_min=get_date(fp,s);
    	if (max == filesize(fp))
    		max--;
    	fseek(fp, max-1, SEEK_SET);
    	goto_beginning_of_current_line (fp);
    	t_max=get_date(fp,s);
    	float weight = (float)(t_target - t_min) / (float)(t_max - t_min);
    	long difference = max - min;
    	return ((long) (weight * difference));
    }
     
    void print_current_line(FILE* fp)
    {
    	goto_beginning_of_current_line(fp);
    	int c;
            do
            	putchar(c = getc(fp));
            while (c != _ENDOFLINE && c != EOF);
    }
     
     
     
    int search_date(FILE *fp, time_t t_target, long (*functionpointer)(FILE*,long,long,time_t)) /////////
    {
    	long min=0, max=filesize(fp), k= (*functionpointer)(fp,min,max,t_target); //////////////
    	time_t t_min, t_max, t_test;
    	char s[16];
     
    	if (max == 0)
    	{
    		fseek(fp,0,SEEK_SET);
    		return 1;
    	}
     
    	fseek(fp,min,SEEK_SET);
    	t_min=get_date(fp,s);
    	fseek(fp,max-1,SEEK_SET);
    	goto_beginning_of_current_line(fp);
    	t_max=get_date(fp,s);
     
    	if(t_target<t_min)
    	{
    		fseek(fp,0,SEEK_SET);
    		return 0;
    	}
    	if(t_target>t_max)
    	{
    		fseek(fp,0,SEEK_SET);
    		return 2;
    	}	
     
    	int acc=0; /////////////
    	while (abs(max-min) > 1)
    	{
    		fseek(fp, k, SEEK_SET);
    		goto_beginning_of_current_line(fp);
    		t_test = get_date(fp,s);
     
    		if(t_target == t_test)
    		{
    			goto_first_occurrence(fp,t_test);
    			printf("nombre de boucles: %i\n",acc); ////////////
    			return 0;
     
    		}
    		else
    		{
    			if(t_target < t_test)
    				max=k;
    			else
    				min=k;
    			k= (*functionpointer)(fp,min,max,t_target); /////////
    		}
    		acc++;	/////////////////
    	}
    	fseek(fp,max,SEEK_SET);
    	printf("nombre de boucles: %i\n",acc); ///////////////////
    	return 0;
    }	
     
     
    int main(int argc, char **argv)
    {
    	FILE *fp = fopen("txt","rb");
    	if (fp == NULL)
    	{
    		fprintf(stderr,"File can't be opened\n");
    		return 1;
    	}
     
    	//char *s=argv[1];
    	//time_t time=string_to_time_t(s);  
    	time_t time=string_to_time_t("Nov  2 19:24:33");
     
    	long (*functionpointer1) (FILE*,long, long,time_t)= &function1; //////////////
    	long (*functionpointer2) (FILE*,long, long,time_t)= &function2; //////////////
    	printf("search date result %i\n",search_date(fp,time,functionpointer1)); //////////////
    	print_current_line(fp);
    	printf("search date result %i\n",search_date(fp,time,functionpointer2)); //////////////
    	print_current_line(fp);
     
            fclose(fp);
    	return 0;
    }
    Promis, j'arrêterai de vous embêter avec mes questions une fois que j'aurai eu les réponses à ces quatre là.
    Dans tous les cas, merci beaucoup de m'avoir permis d'en arriver là.

  13. #73
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    En revanche j'ai un peu de mal à comprendre l'utilité du goto_beginning_of_current_line(fp); à la fin de search_date, après le fseek. C'est sûr qu'il ne peut pas faire de mal, mais j'ai l'impression qu'on était déjà en début de ligne à ce moment là : quand on sort du while, max=min+1. Ceci n'arrive que si min est un curseur sur une ligne et max sur la ligne suivante, autrement on aurait retourné la ligne de min et de max dans le while. C'est donc qu'il y a un \n entre les deux, donc max est déjà en début de ligne.
    ->Pouvez-vous me dire ce qui est faux dans mon raisonnement?
    min et max sont les limites du segment qu'on utilise pour la recherche dichotomique. Supposons que c'est toujours max qui décroît. Au début, il se trouve à la fin du fichier (et min à l'offset 0). Ensuite il va en 1/2 du fichier, puis en 1/4, en 1/8, etc. Qu'est-ce qui nous garanti que ces offset 1/2 du fichier, 1/4, 1/8, etc. sont des débuts de ligne ?

    Sinon, j'avais modifié goto_beginning_of_current_line par rapport à celle que vous aviez proposé. Le mien est plus court, mais l'ai-je rendu faux dans certains cas particuliers?
    Non il est bon.

    Permettez-moi également (désolé d'avance) de revenir sur le problème de la portabilité. Tel quel, cela ne marche que sur Linux, on est bien d'accord? Pourrait-on faire un programme qui écrit un saut de ligne en mode texte, puis regarde comment il a été sauvegardé en mode binaire, afin de modifier en conséquence le define du début ? Par ailleurs, tel qu'il est, ce define est un caractère, faudrait-il donc modifier tous les tests (avec strcmp?) pour que ça marche même quand c'est \r\n (et également certains reculs, qui au lieu de -1 seraient -2) ?
    Non, ça marche sur n'importe quel système qui utilise '\n' en dernier caractère du marqueur de fin de ligne, puisque c'est finalement alors ce caractère qui clôture une ligne. Donc que le marqueur de fin de ligne soit \n, \r\n, \r\r\n, etc., ça marchera toujours. Si la fin de ligne est \n\r par contre par exemple (mais je ne connais pas de système qui utilise cette séquence là), ça ne marchera pas. En fait, peut importe le système, tu n'as qu'à remplacer le #define et le code fonctionnera pour ce système. Le degré de non-portabilité de ce programme est donc en fait infinitésimal.

    Pour ce qui est du barycentre, voici où j'en suis (j'ai ajouté des /// à la fin des lignes que j'ai modifiées pour utiliser le barycentre. A noter que tel quel, le programme rend un résultat pour function1, donc le problème semble être dans function2 et pas dans l'insertion de ces deux fonctions au reste du programme. Voyez-vous ce qui provoque la boucle infinie ?
    Le problème c'est que dans function2 tu fais appelles à fseek donc à la fin de la fonction tu perds la position où tu te trouvais avant d'appeler cette fonction. Il suffit juste d'appeler ftell à l'entrée de la fonction pour sauvegarder la position et revenir à cette position (fseek) avant de quitter la fonction. Mais une meilleure solution, c'est de fournir t_min et t_max en paramètres comme ça on ne touche pas au fichier dans la fonction. Enfin, c'est min + weigh*difference qu'il faut retourner.

  14. #74
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Merci encore pour toutes ces réponses, très pédagogiques. Permettez-moi quand même, avant de considérer ce thread comme clot, d'insister sur mon raisonnement de ma première question : je suis d'accord que dans le cas général, les offsets 1/2, 1/4, etc, ne sont pas nécessairement des débuts de ligne. Toutefois l'endroit où vous m'avez proposé d'insérer goto_beginning_of_next_line n'est pas dans le cas général (il est en effet déjà présent d'une certaine manière dans le while avec goto_beginning_of_current_line), mais à la fin du while. Or, si vous relisez mon message précédent, j'ai l'impression qu'à la fin du while, max est nécessairement un début de ligne. Pouvez-vous relire ce que j'ai écrit dans mon précédent message, et me dire précisément à quel endroit du raisonnement se situe la faute ? (ou me donner un contre-exemple concret qui montre l'utilité de l'aller à la ligne à cet endroit là)
    Merci.

  15. #75
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    while (abs(max-min) > 1)
    {
        fseek(fp, k, SEEK_SET);
        goto_beginning_of_current_line(fp);
        ...
    }
    ...
    Là tu fais un goto_beginning_of_current_line lorsque la boucle continue. Si la boucle ne doit plus continuer, tu remplaces k par max, mais tu as toujours besoin du goto_beginning_of_current_line. C'est pas clair ?

  16. #76
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Si, cette partie de votre explication est claire, et je suis d'accord avec vous.
    Mais n'êtes vous pas d'accord qu'à la fin du while (si on y arrive sans avoir rencontré un return), on a max=min+1, et que par ailleurs la date cherchée se trouve entre la ligne de min et la ligne de max, et que l'on peut donc en conclure qu'il y a entre max et min un \n ?

  17. #77
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Mais n'êtes vous pas d'accord qu'à la fin du while (si on y arrive sans avoir rencontré un return), on a max=min+1,
    Oui, ou max = min.

    et que par ailleurs la date cherchée se trouve entre la ligne de min et la ligne de max
    Il est tout à fait possible que min et max soient sur la même ligne. C'est même le cas qui a la plus grande probabilité de se produire.

  18. #78
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Pourtant, si min et max sont sur la même ligne, alors ils "renvoient" la même date, et puisqu'en outre la date cherchée se trouve entre min et max, alors on est dans le cas t_target == t_test, donc on ne lit pas les lignes qui succèdent le while, car il y a un return dans ce if(t_target == t_test). Non?

  19. #79
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    S'ils sont sur la même ligne ils renvoient la même date évidemment, mais c'est pas forcément la date cherchée. Pour preuve intuitive la date peut ne pas se trouver dans le fichier. Ta plus grosse erreur c'est de croire que la date cherchée est toujours comprise entre min et max. Absolument pas. Comme je viens de le dire, la date elle-même peut ne pas se trouver dans le fichier, et c'est justement dans ce cas qu'on aura min = max ou max + 1 à la fin.

  20. #80
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Le cas où la date n'est pas dans le fichier n'est-il pas traité dans les cas if(t_target<t_min)
    et if(t_target>t_max), qui précèdent le while et se terminent par un return ? Si oui, alors j'ai vraiment du mal à comprendre pourquoi l'ajout de goto_beginning_of_next_line après le while sera utile. Excusez mon obstination et merci de m'aider à comprendre où est la faute dans mon raisonnement.

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/04/2012, 22h30
  2. Réponses: 15
    Dernier message: 01/11/2008, 16h57
  3. Entrée / sortie dans un fichier binaire
    Par mejrs dans le forum Débuter
    Réponses: 1
    Dernier message: 24/05/2008, 17h48
  4. Réponses: 17
    Dernier message: 07/05/2008, 11h16
  5. Réponses: 11
    Dernier message: 13/10/2004, 01h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo