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 :

Recherche dans fichier pour inventaire


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2015
    Messages : 41
    Points : 35
    Points
    35
    Par défaut Recherche dans fichier pour inventaire
    Bonjour,
    j'essaie de créer une application pour faire l'inventaire sur une douchette de chez opticon.
    Mais le problème est que quand je scan un code barre j'appelle une fonction qui me dis si le code barre existe dans un fichier (que je charge sur la douchette).
    la fonction me renvoie un message qui me dis que le code barre existe alors que dans le fichier il y est pas.
    Quand je trouve mon code barre dans le fichier je demande de me l'afficher est a chaque fois j'obtiens ce code barre :
    2600003264997 alors que c'est pas celui qui est scanner.
    le code barre pour le quelle j'obtient le problème est le : 20173852

    Fichier source : ( fichier .txt)
    0000000000032
    0000000000048
    2600003264997
    2600003298466
    2600003315361

    Fonction de recherche
    Code C : 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
     
    int getbarcode( char barcode)
    {
    	FILE *fichier = NULL;
    	fichier = fopen(fichier_source[0], "r");
    	int traitement=-1;
    	 if (fichier != NULL)
        {
    		char line [ TAILLE_MAX ]; /* or other suitable maximum line size */
    		while ( fgets ( line, sizeof line, fichier ) != NULL ) /* read a line */
    		{
    			if ( *line == barcode)
    			{	
    				printf("\n%s",line);
    				traitement = 1;
    				break;
    			}
    		}
            fclose(fichier);
        }
        else
        {
            // On affiche un message d'erreur si on veut
            printf("\nImpossible d'ouvrir le fichier");
        }
     
     
    	return traitement;	
    }


    Fonction qui scan le code barre et appel la fonction de recherche
    Code C : 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
     
     
    void scancodebarre( void )
    {
        putchar('\f');
        printf("Scanner code barre");
     
    	int key;
        char string[ 40+1 ];
        int codeId;
    	char barcode = 0;
     
     
    	FILE* fichier = NULL;
    	fichier = fopen("INVENT.txt", "w");
        for(;;)
        {
            string[0] = '\0';
            printf("\fEcrit ou scan..");
            key = ScanOrKeyboardInputSymbol( string, 1, 13, INPUT_NUM, 0, 1, 14, &codeId );
            switch( key )
            {
                case KEYBOARD:
                    barcode  =  string[0];
    				// printf("\n");
    				// fprintf(fichier,"%d;1\n",barcode);
    				// printf("%d;1\n",barcode);
                    break;
                case SCANNED:
                    barcode  =  string[0];
    				// printf("\n");
    				// fprintf(fichier,"%d;1\n",barcode);
    				// printf("%d;1\n",barcode);
                    break;
                default:
                    break;
            }
    		resetkey();
    		int traitement = -1;
    		traitement = getbarcode(barcode);
    		if (traitement == 0)
    		{
    			printf("\ncode barre inconnu");
    		} 
    		else if (traitement ==1)
    		{
    			printf("\ncode barre connu");
    		} 
    		resetkey();
    		WaitForKey();
     
    		if(KeyboardInput(string,1,40,INPUT_ALL,0,1,14,2,CLR_KEY,ENT_KEY) == CLR_KEY){
    			break;
    		}
     
        }
     
    	fclose(fichier);
    	printf("\fFin inventaire");
        WaitForKey();
    }
    est ce que vous pouvez m'aider a comprendre pourquoi j'ai ce problème ?
    j'ai aussi un autre problème qui est que j'ai le choix de scanner ou d'écrire le code barre mais quand j'écris le code barre je n'est pas de message qui me dis si le code barre existe ou pas.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    String étant ton code-barre scanné, ta fonction ne fait que vérifier que le premier caractère correspond..
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2015
    Messages : 41
    Points : 35
    Points
    35
    Par défaut
    D'accord ,
    que dois-je passer a la fonction getbarcode pour qu'elle compare tous mon code barre et non le 1er caractère.

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gtapes Voir le message
    Code C : 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
    int getbarcode( char barcode /* le codebarre ne fait donc qu'un seul caractère !!! */)
    {
    	FILE *fichier = NULL;
    	fichier = fopen(fichier_source[0], "r");
    	int traitement=-1;
    	 if (fichier != NULL)
        {
    		char line [ TAILLE_MAX ]; /* or other suitable maximum line size */
    		while ( fgets ( line, sizeof line, fichier ) != NULL ) /* read a line */
    		{
    			if ( *line == barcode)  // Ben oui, comparer *line (le premier caractère de la varaible "line") avec le caractère placé dans "barcode" a de grandes chances de trouver une correspondance
    			{	
    				printf("\n%s",line);
    				traitement = 1;
    				break;
    			}
    		}
            fclose(fichier);
        }
        else
        {
            // On affiche un message d'erreur si on veut
            printf("\nImpossible d'ouvrir le fichier");
        }
    	
    	
    	return traitement;	
    }
    est ce que vous pouvez m'aider a comprendre pourquoi j'ai ce problème ?
    Bonjour
    Voir mes commentaires en rouge dans ton code. Tu devrais aller réouvrir ton cours sur le chapitre des chaines de caractères...

    Citation Envoyé par gtapes Voir le message
    que dois-je passer a la fonction getbarcode pour qu'elle compare tous mon code barre et non le 1er caractère.
    Sais pas trop. Ptet que lui passer tout le codebarre à comparer serait une idée à creuser...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Une chaîne de caractères et non simplement un caractère

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2015
    Messages : 41
    Points : 35
    Points
    35
    Par défaut
    D'accord ,
    si j'ai bien compris je dois lui passer un tableau de char. Donc la fonction getbarcode doit ressembler à ceci :

    Code C : 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
     
    int getbarcode(char barcode[])
    {
    	printf("\n\n%s;\n", barcode);
    	FILE *fichier = NULL;
    	fichier = fopen(fichier_source, "r");
    	int traitement=0;
    	 if (fichier != NULL)
        {
    		char line [ TAILLE_MAX ]; /* or other suitable maximum line size */
    		while ( fgets ( line, sizeof line, fichier ) != NULL ) /* read a line */
    		{
    			if ( line == barcode)
    			{
    				traitement = 1;
    				break;
    			}
    		}
            fclose(fichier);
        }
        else
        {
            // On affiche un message d'erreur si on veut
            printf("\nImpossible d'ouvrir le fichier");
        }
    	return traitement;	
    }

  7. #7
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 623
    Points : 1 554
    Points
    1 554
    Par défaut
    Hello,

    Deux choses:

    1) la comparaison de deux strings en C se fait en utilisant (entre autres) strcmp(), pas ==. Ce que tu fais dans ton code, c'est comparer les adresses des variables

    2) fgets() va mettre le \n dans la ligne lue, tu dois le supprimer sinon la comparaison avec barcode ne sera jamais vraie (sauf si il y a également un \n à la fin de barcode, évidemment)
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2015
    Messages : 41
    Points : 35
    Points
    35
    Par défaut
    j'ai rajouté le code pour remplacer le "\n" dans la ligne mais le problème est qu'il ne me trouve que le dernier code barre dans le fichier est pas les autres.
    Fichier source : ( fichier .txt)
    0000000000032
    0000000000048
    2600003264997
    2600003298466
    2600003315361

    Code C : 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
     
    int getbarcode(char barcode[])
    {
    	FILE *fichier = NULL;
    	fichier = fopen(fichier_source[0], "r");
    	int traitement=0;
    	char *positionEntree = NULL;
     
    	 if (fichier != NULL)
        {
    		char line [ TAILLE_MAX ]; /* or other suitable maximum line size */		
    		while ( fgets ( line, sizeof line, fichier ) != NULL ) /* read a line */
    		{
    			positionEntree = strchr(line, '\n'); // On recherche l'"Entrée"
     
            if (positionEntree != NULL) // Si on a trouvé le retour à la ligne
            {
                *positionEntree = '\0'; // On remplace ce caractère par \0
            }		
    			if ( strcmp(line , barcode) == 0)
    			{
    				traitement = 1;
    				break;
    			}
    		}
            fclose(fichier);
        }
        else
        {
            // On affiche un message d'erreur si on veut
            printf("\nImpossible d'ouvrir le fichier");
        }
    	return traitement;	
    }

  9. #9
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,
    Une petite précision, tout de même, concernant strcmp.
    strcmp effectue la comparaison en utilisant l'ordre lexicographique en renvoyant une valeur soit :
    • Négative si la chaîne x se classe avant chaîne y
    • Nulle si la chaîne x et chaînes y sont identiques
    • Et positives si la chaîne x se classe après la chaîne y

    Donc, pour vraiment effectuer, un teste d'égalité des deux chaînes, il faut prendre en compte la négation de la valeur a renvoyé en d'autres termes, il faut écrire quelque chose du genre : (!strcmp((x),(y))) ou
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #define isEgal(x, y) (!strcmp((x),(y)))
    if( isEgal(......))
       ........

    Vous avez également la possibilité d'utiliser la fonction strncmp qui fait la même chose que strcmp, mais en explorant uniquement les "n" premiers caractères.
    à bientôt.
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2015
    Messages : 41
    Points : 35
    Points
    35
    Par défaut
    Merci de votre aide , mon problème est résolut j'ai juste remplace le "\n" dans la recherche par "\r".

    Par contre j'ai un nouveau problème qui lors du transfère du fichier de la douchette vers le PC.
    si le fichier existe sur le PC il me rajoute a la suite le contenue du fichier de la douchette.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void download( void )
    {
        putchar('\f');
        printf("T\202l\202charger fichier");
    	comopen( COM2 );
    	test = neto_transmit("INVENT.txt", test, "123456", ENT_KEY, 3);
     
    	printf("T\202l\202hargement ok");
    	printf("appuyer sur une \ntouche pour revenir au menu");
     
        comclose( COM2 );
        WaitForKey();
    }

  11. #11
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    [...]Donc, pour vraiment effectuer, un teste d'égalité des deux chaînes, il faut prendre en compte la négation de la valeur a renvoyé[...]

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Donc, pour vraiment effectuer, un teste d'égalité des deux chaînes, il faut prendre en compte la négation de la valeur a renvoyé en d'autres termes, il faut écrire quelque chose du genre : (!strcmp((x),(y)))
    Je pige que dalle. C'est pas bon son if (strcmp(line , barcode) == 0) ??? Ca ne fait pas "vraiment" un test d'égalité entre les deux chaines ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  13. #13
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    C'est évident.. Y'a le test d'égalité viandard et pis y'a le non viandard, quoi.


  14. #14
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Vous êtes durs
    Je ne vois aucun exemple de strcmp plus haut et c'est carrément contre naturel de tester ==0 (soit false) dans un cas d'égalité quand tu débutes. Du coup les précisions ne me semblent pas superflues ici.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  15. #15
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut

    Citation Envoyé par Sve@r Voir le message
    Je pige que dalle. C'est pas bon son if (strcmp(line , barcode) == 0) ??? Ca ne fait pas "vraiment" un test d'égalité entre les deux chaines ???
    Décidément, vous n'avez pas compris parce que, j'ai très mal formulé ce que j'ai écrit. Je ne dis pas que l'instruction suivante if (strcmp(line , barcode) == 0) est fausse, je dis juste que la fonction strcmp renvoie une valeur négative si la chaîne X est inférieure à chaîne Y ; positive si la chaîne X est supérieure à la chaîne Y et nulle si les deux chaînes sont égaux (au sens lexicographique). il est donc plus astucieux de tester l'égalité des deux chaînes en prenons la négation de la valeur renvoyer par la fonction.
    Code C : 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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define isEgal(x,y) (!strcmp((x),(y)))
     
    int main( void ){
     
        char buff_A[] = "Bonjour\0";
        char buff_B[] = "Bonjour\0";
     
        if( isEgal(buff_A, buff_B) ){          
            (void)fprintf(stderr, "OK\n");
        }else{
            (void)fprintf(stderr, "No Ok\n");
        }
        return EXIT_SUCCESS;
    }
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  16. #16
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2015
    Messages : 41
    Points : 35
    Points
    35
    Par défaut
    Comme je veux juste savoir si mes deux chaines sont égaux ( je ne prend pas en compte le supérieur et le inférieure) je peux garde mon test :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if ( strcmp(line , barcode) == 0)
    			{
    				traitement = 1;
    				break;
    			}

    j'ai un autre problème qui est que lorsque j'écrit une ligne via
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    	fprintf(fichier,"%s;1\r",string);
    sur le bloc note j'ai tous mes valeurs écrite sur la même ligne
    alors que sur notepad++ j'ai bien un saut de ligne après chaque valeur écrite.
    comme faire pour avoir le même rendu sur bloc note car le client utilise bloc note et non notepad++ ?

    j'ai un autre problème une fois que j'ai transféré un fichier de la douchette vers le PC , je n'est pas la possibilité de renvoyer un fichier vers la douchette.

    chargement fichier sur la douchette
    Code C : 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
     
    void load( void )
    {
        putchar('\f');
        printf("Chargement en cours");
    	comopen( COM2 );
    	do
            {
                printf("\nReceiving..");
                test = neto_receive( fichier_source, "123456", ENT_KEY, 3);			
            } while( test < 0);
    		printf("Chargement termin\202\n");
    		printf("appuyer sur une \ntouche pour revenir au menu");
     
            comclose( COM2 );    // Saves power
    		WaitForKey();
    }

    envoie fichier PC
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void download( void )
    {
        putchar('\f');
        printf("T\202l\202charger fichier");
    	comopen( COM2 );
    	test = neto_transmit("INVENT.txt", test, "123456", ENT_KEY, 3);
     
    	printf("\nT\202l\202chargement ok\n");
    	printf("appuyer sur une \ntouche pour revenir au menu");
     
        comclose( COM2 );
        WaitForKey();
    }

    main
    Code C : 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
     
    const stxtMenu mnuSetFont[] = {
        {(char*)mnucodebarre, 	scancodebarre},
    	{(char*)mnudownload, 	download},
    	{(char*)mnuload,			load},
    };
     
    void main( void )
    {
        int nIndex = 0;
     
     
        systemsetting("SZ"); 
     
        for(;;)
        {
            ShowTextMenu( &nIndex,
                          "Cr\202ation inventaire",
                          (stxtMenu*)mnuSetFont,
                          sizeof(mnuSetFont) / sizeof(stxtMenu),
                          MENU_FIXED );
     
            if( nIndex == -1 )	// CLR_KEY was pressed
            {
                printf("\fCLR key is\n pressed\n\nPress a key");
                WaitForKey();
                nIndex = 0; // reset selection to the first item
            }
    		setfont( LARGE_FONT, NULL);
        }
    }

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Décidément, vous n'avez pas compris parce que, j'ai très mal formulé ce que j'ai écrit. Je ne dis pas que l'instruction suivante if (strcmp(line , barcode) == 0) est fausse, je dis juste que la fonction strcmp renvoie une valeur négative si la chaîne X est inférieure à chaîne Y ; positive si la chaîne X est supérieure à la chaîne Y et nulle si les deux chaînes sont égaux (au sens lexicographique). il est donc plus astucieux de tester l'égalité des deux chaînes en prenons la négation de la valeur renvoyer par la fonction.
    Astucieux mais contre-intuitif et moins lisible, car ! implique (à tord en C, à raison dans d'autres langages comme C#) une logique Booléenne que la fonction n'a pas.

    Cela me rappelle mes débuts avec le C, où j'usais et abusais du fait que if(var) soit un test valide en C quel que soit le type de var. Normalement, on perd cette habitude quand on perd à la fois l'obsession de la vitesse à l'instruction près et l'illusion qu'un code plus court est automatiquement plus rapide. Quand on murit en tant que programmeur, on finit par se rendre compte que différencier if(var), if(var!=0) et if(var!=NULL) augmente la lisibilité et la maintenabilité du code en documentant le type de var.
    Avec le temps, on apprend à remplacer l'astuce par la rigueur.
    Et là, on voit que tester explicitement la nullité du retour de strcmp() est plus propre et plus lisible que tester sa négation Booléenne.

    Le coup de la macro (ou fonction inline, etc.) isEgal reste une bonne idée par contre, si on lui trouve un nom un peu moins franglais.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        char buff_A[] = "Bonjour\0";
        char buff_B[] = "Bonjour\0";
    Intéressant ce '\0' écrit dans la chaine. Donc pour info, quand tu écris "Bonjour", le compilo transforme ça en {'B', 'o', 'n', 'j', 'o', 'u', 'r', '\0'}.
    Donc ici, buff_A et buff_B ont tous deux {'B', 'o', 'n', 'j', 'o', 'u', 'r', '\0', '\0'} et sont donc définis à 9 caractères là où 8 aurait suffit. Ceci dit, cela ne change rien au résultat vu que c'est le premier '\0' qui compte...

    Citation Envoyé par gtapes Voir le message
    Comme je veux juste savoir si mes deux chaines sont égales ( je ne prends pas en compte le supérieur et le inférieure) je peux garder mon test :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if ( strcmp(line , barcode) == 0)
    			{
    				traitement = 1;
    				break;
    			}
    Donc déjà tu vas commencer par indenter proprement ton code et arrêter de mettre 4 tabulations là où une seule suffit. Sans déconner, 3 tabulations pour les accolades, une 4° pour les instructions associées : ton premier bloc et tu es déjà à 32 caractères à droite de ton écran. Ca donnera quoi quand tu auras 3 blocs imbriquées ???
    Citation Envoyé par gtapes Voir le message
    Code C : 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
    if (fichier != NULL)
        {
    		char line [ TAILLE_MAX ]; /* or other suitable maximum line size */		
    		while ( fgets ( line, sizeof line, fichier ) != NULL ) /* read a line */
    		{
    			positionEntree = strchr(line, '\n'); // On recherche l'"Entrée"
     
            if (positionEntree != NULL) // Si on a trouvé le retour à la ligne
            {
                *positionEntree = '\0'; // On remplace ce caractère par \0
            }		
    			if ( strcmp(line , barcode) == 0)
    			{
    				traitement = 1;
    				break;
    			}
    		}
            fclose(fichier);
        }
    Effectivement, je vois ce que ça donnne !!!

    Par ailleurs (mais là c'est plus un avis personnel) ton aération (un espace avant la parenthèse et un espace après) est moyenne (idem pour la virgule). Voici (encore une fois c'est un avis purement personnel) ce que je préconise:
    • un espace entre le mot clef "if", "for", "while" et la parenthèse ouvrante
    • un espace après la virgule mais pas avant (comme en français d'ailleurs)
    • pas d'espace entre le nom d'une fonction et la parenthèse ouvrante
    • un espace avant et après l'opérateur de comparaison
    • pas d'espace dans les affectations

    Ce qui donnerait ici if (strcmp(line, barcode) == 0) et if ((positionEntree=strchr(line, '\n')) != NULL) lors de ta suppression du '\n'.

    Citation Envoyé par gtapes Voir le message
    j'ai un autre problème qui est que lorsque j'écrit une ligne via
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    	fprintf(fichier,"%s;1\r",string);
    sur le bloc note j'ai tous mes valeurs écrite sur la même ligne
    alors que sur notepad++ j'ai bien un saut de ligne après chaque valeur écrite.
    comme faire pour avoir le même rendu sur bloc note car le client utilise bloc note et non notepad++ ?
    Bienvenue dans le monde des fichiers textes Unix vs Windows. Je voulais déjà en parler quand j'ai vu que tu avais remplacé '\n' par '\r' (mauvaise idée) puis j'ai laissé pisser (là aussi mauvaise idée) donc j'en parle maintenant.
    Sur Unix, un fichier texte termine chaque ligne par un '\n' symbolisant le "<return>" classique qui vient naturellement quand on tape un texte. Sur Windows, chaque ligne se termine par deux caractères '\r\n' symbolisant 1) le "retour charriot" (à prendre dans le sens littéral à l'époque des machines à écrire quand la secrétaire ramenait le charriot à l'aide de la manette) et 2) le "next line" (là aussi symbolisant le rouleau qui faisait avancer le papier d'une ligne). Cette double opération se justifiait à l'époque car on pouvait ainsi les dissocier et par exemple faire revenir le charriot sans faire avancer le papier (pour par exemple réécrire en blanc sur la même ligne et ainsi effacer le texte écrit) mais je m'explique moins d'avoir retranscrit cette double opération à l'identique sur des fichiers informatiques. Mais le fait est là, ça y est et c'est comme ça.
    Et donc maintenant on se bat depuis 30 ans lors des transferts entre Unix et Windows où dans un monde un item (un "end of line") est représenté par un caractère (logique, sensé, normal) et où dans l'autre monde un item (le même "end of line") est représenté par deux caractères (abracadabrant, grotesque, idiot). Et donc quand on veut transférer des fichiers textes entre Unix et Windows par ftp, il faut spécifier "ascii" pour que le logiciel transforme un truc en l'autre truc (et spécifier "binary" quand on veut transférer des images/vidéos/musiques pour là laisser tout '\r\n' éventuel tel quel).

    Et en C c'est la même chose, surtout sous Windows. Dans ce monde, quand tu ouvre un fichier image, vidéo, musique (qu'on regroupe sous le vocable "binaire") il te faut spécifier "rb" ou "wb" à la place de "r" ou "w". Dans ce cas, les opérations de lecture/écriture ne changent rien à ce que tu lis/écrit. Alors que si tu ouvres un fichier en mode "r" ou "w", les fonctions considèrent que tu lis/écris un fichier texte et à la lecture transforment le double '\r\n' en '\n' ; et à l'écriture convertissent le '\n' en '\r\n'. A noter que le mode "rb et "wb" est accepté sous Unix (pour des raisons de compatibilité) mais que cela ne change rien vu que sous Unix, un fichier texte ne se différencie en rien d'un fichier binaire (dans les deux cas c'est de l'octet à suivre avec la notion naturelle "un seul octet par item").

    Donc il te faut ouvrir ton fichier en mode "w" (comme tu l'as fait), mais écrire '\n' et non '\r'. Et ensuite ton fichier sera lisible par ton notepad, éditeur plus que basique.
    Et si tu travailles sous Unix, mais que tu transfères ensuite ton fichier sous Windows par une clef USB, ben tu ne peux pas le lire sans d'abord le convertir. Tu as sous Unix un outil nommé unix2dos" qui fait ça (et tu as aussi l'outil inverse "dos2unix" quand tu veux convertir des fichiers Windows) et sinon sous Windows alors notepad++ fait ça via le menu "EOL conversion".

    Et donc pour en revenir à ton code qui ne fonctionnait pas avec '\n' mais qui fonctionne avec '\r' je pense que c'est parce que ton fichier est mal écrit à l'origine (ou qu'il a été mal transféré). Et donc ma philosophie serait de te remettre un fichier correct plutôt qu'adapter ton code à un fichier incorrect.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  19. #19
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,
    Citation Envoyé par Médinoc Voir le message
    Astucieux mais contre-intuitif et moins lisible, car ! implique (à tord en C, à raison dans d'autres langages comme C#) une logique Booléenne que la fonction n'a pas.
    Vous soulevez un point fort intéressant. Peut-être que je me trompe, mais quand on utilise un opérateur relationnel "==", le résultat obtenu du test d'égalité produit comme résultat une valeur du type entier (soit 0 ou 1) qui d’ailleurs peut tout à fait être utilisé pour effectuer des calculs (addition, etc.). De mémoire, le langage de programmation C considère les valeurs zéro sous toutes ses formes comme étant fausses et "un" comme vrai. Cela est dû au fait que le langage de programmation C ne dispose pas d’un véritable type booléen à proprement parler.

    Dans le cas de l'expression strcmp(line , barcode) == 0 actuelle, mise dans une structure conditionnelle (ici if); elle devient non plus une expression dont le résultat est du type entier, mais plutôt une expression booléenne. Pourquoi ? Tout simplement parce que les structures de contrôle (comme if) sont en réalité des structures conditionnelles qui dépendent d’une évaluation d’expression booléenne et d’une part toute expression/opération est considérée comme étant booléen à l’instant où l’on a deux entités uniques distinctes ; je peux également dire que toute expression de comparaison ou de tests fait partie de ce qui caractérise et définit des expressions logiques et donc ici, on a bien une expression booléenne.

    Il faut se l’avouer : l’emploi "==" est une pratique répandue et également (peut-être) pour de nombreuses raisons que vous évoquez, à savoir plus de lisibilité et de maintenabilité, mais dans les faits, elle met en évidence non pas un test de nullité, mais bien un test booléen d’une part et de l’autre un test booléen pour celui qui lit l’instruction.

    Autre chose fort intéressante également dans ce que vous dites, "Et là, on voit que tester explicitement la nullité du retour de strcmp() est plus propre et plus lisible que tester sa négation booléenne.". On ne teste pas la négation booléenne, car la fonction ne renvoie pas une valeur booléenne comme vous l’avez évoqué, mais ici, on teste l’inverse du résultat de la valeur envoyée dans une structure conditionnelle qui à son tour donne un sens à la comparaison des deux chaînes (une logique pertinente). L’inverse de la valeur renvoyée par la fonction (zéro) donne vrai parce que la comparaison des deux chaînes retourne 0 et donc elles sont égales. Toute autre valeur est considérée non-égale parce que, soit la chaîne X est supérieure à la chaîne Y, ou l’inverse. Au final, if(!strcmp(line , barcode))et if(strcmp(line , barcode)==0) sont équivalentes et toutes deux n’impliquent en rien une logique booléenne à la fonction strcmp. Ce qui implique à tord une logique booléenne à une fonction qui ne l’est pas, serait par exemple l’instruction ci-dessous.
    Code C : 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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef enum{
    	TRUE = 1,
    	FALSE = (!TRUE)
    }BOOL;
     
    int main( void ){
     
    	char x[] = "aaa";
    	char y[] = "aaa";
     
     
    	if( strcmp(x,y) == TRUE ){
    		(void)fprintf(stderr, 
    			"Les deux chaînes sont égales\n");
    	}else{
    		(void)fprintf(stderr, 
    			"Les chaînes ne sont pas égales\n");
    	}
    	return EXIT_SUCCESS;
    }

    Question rigueur, on pourrait se poser la question de savoir ce que signifie réellement le zéro "magique", comparé avec la valeur que retourne la fonction strcmp (surtout, que la fonction est susceptible de renvoyer une valeur autre que zéro), le zéro magique veut-il dire false, true, que les deux chaînes sont égales, un pointeur nul ...?.

    Je comprends tout à fait qu’il est plus difficile de comprendre pour ceux qui n’ont pas l’habitude de voir l’emploi de la négation de la sorte , mais cela n’est pas une mauvaise chose ou un manque de rigueur, loin de là. On ne cherche pas non plus à obtenir un code court ou plus rapide. N’oublions pas que l’implémentation du système/mode d’évaluation des expressions est laissée à la discrétion des concepteurs du compilateur que l’on utilise (celui-ci peut très bien implanter une évaluation d’expression par court-circuit). D’ailleurs que l’on applique des optimisations ou non, les instructions générées par if(!strcmp(line , barcode)) ou if(strcmp(line , barcode)==0) sont en réalité écrites sous forme d’une comparaison suivie d’un saut conditionnel (sans rentrer dans les détails)..

    Bref, pour moi, les deux instructions sont équivalentes ; le choix est laissé à celui qui écrit les instructions et pourquoi il écrit if(!strcmp(line , barcode) ) plutôt que if(strcmp(line , barcode)==0). Celui qui lit l’instruction ou qui compte apporter des modifications au code doit se référer à la documentation du code/fonction pour comprendre ce qui a été écrit et savoir s’il est nécéssaire de l’améliorer ou de le laisse comme tel.
    J’avoue personnellement que j’utilise "==" plus que la négation sur des forums, mais dans des circonstances autres que sur les forums, j’utilise la négation non pas abusivement, mais de façon logique, tout ce qui est optimisation vient après.

    De toute façon, chacun peut se faire son opinion sur la question, mais personnellement, je trouve cela plus astucieux, pertinent et logique que d'effectuer un test la nullité avec une valeur magique qui peut signifier beaucoup de choses. En ce qui concerne le nom des macro ou variable effectivement un nom plus pertinent serait meilleur.

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  20. #20
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 623
    Points : 1 554
    Points
    1 554
    Par défaut
    Hello,

    Le zéro renvoyé par strcmp() n'a rien de magique.

    strcmp() compare octet par octet les deux variables qui les sont passées. Tant que la différence entre les deux octets vaut zéro, la comparaison se prolonge. Si les deux variables sont identiques, la dernière comparaison donnera une différence de zéro, c'est ce qui est renvoyé. A l'inverse, si à un moment quelconque la comparaison donne un résultat différent de zéro, c'est ce résultat qui est renvoyé (d'où le terme: un nombre < 0 ou supérieur à 0). Ainsi 'A' cmp 'C' renverra -2 et 'C' cmp 'A' renverra 2
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

Discussions similaires

  1. Besoin d'aide écriture dans fichier
    Par boniface dans le forum Modules
    Réponses: 3
    Dernier message: 29/01/2007, 18h06
  2. Recherche dans fichier
    Par Débéa dans le forum Général Python
    Réponses: 2
    Dernier message: 26/07/2006, 14h51
  3. recherche dans fichier xml
    Par piro dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 24/03/2006, 08h11
  4. Réponses: 4
    Dernier message: 28/10/2005, 09h59
  5. Recherche dans fichiers
    Par Tchinkatchuk dans le forum Linux
    Réponses: 2
    Dernier message: 17/06/2005, 10h32

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