2017-01-02 2 views
0

je veux lire toutes les lignes d'un fichier qui ressemble à ceci:lignes de lecture de fichier avec fgets et comparer chaque ligne avec strncmp en c

readEveryLine 
{  
    "Bart [m]" -> "Marge [f]"; 
    "Lisa [f]" -> "Homer [m]"; 
    ...  
} 

Je veux utiliser:

  1. fgets() pour lire le fichier ligne par ligne
  2. strncmp() pour comparer toutes les lignes avec une chaîne donnée ou voir qu'il a juste le format

ce que j'ai:

donc le problème
while(fgets(*file_string, MAX_INPUT_STDIN, file) != NULL) 
{  
    changeLastC(*file_string); // function to change \n into \0 

    if (strncmp(*file_string, "readEveryLine\0", 14) == 0) 
    { 
     if (strncmp(*file_string, "{\0", 2) == 0) 
     { 
     // check the first -> relation 
     } 
    } 
    else 
    { 
     printf("Error Parsing\n"); 
    } 
} 

est que cela me donne juste une Erreur d'analyse et je ne savent plus ce que je fait de mal ici.

Merci beaucoup de m'avoir aidé!

ici j'ai fait quelques choses maintenant (l'analyse des deux premières lignes fonctionne maintenant): peut-être que quelqu'un a un bon conseil pour moi ce que je pourrais faire mieux. Merci beaucoup.

if ((fp = fopen("df.dot","r")) == NULL) 
{ 
    printf("Error: File Open\n"); 
    return 1; 
} 


int row = 0; // check row 1 

while (fgets(buffer, MAX_PARSING, fp)) 
{   
    if ((row == 0) && strncmp(buffer, "readEveryLine\n", 14) == 0) 
    { 
    printf("%s", buffer); 
    } 
    else 
    { 
    printf("Parsing Error 1\n"); 
    } 
} 


int row1 = 1; // check row 2 

while (fgets(buffer, MAX_PARSING, fp)) 
{  
    if ((row1 == 1) && strncmp(buffer, "{\n", 2) == 0) 
    { 
    printf("%s", buffer); 
    } 
    else 
    { 
    printf("Parsing Error 2\n"); 
    } 
} 


int row2 = 2; // check other rows (dynamic, could be even more or less) 

while (fgets(buffer, MAX_PARSING, fp)) 
{ 
    if ((row2 == 2) && strncmp(buffer, " ", 2) == 0) 
    { 
    const char *p1 = strstr(fp, "\"")+1; 
    const char *p2 = strstr(p1, " [m]\""); 
    const char *p3 = strstr(p1, " [f]\""); 

    // extract male persons 
    if (p1 && p2) 
    { 
     size_t len1 = p2 - p1; 
     char* res1 = (char*)malloc(sizeof(char)*(len1 + 1)); 
     strncpy(res1, p1, len1); 

     res1[len1] = '\0'; 

     // give res1 for functionMale() to work on that string 
    } 

    // extract female persons 
    else if (p1 && p3) 
    { 
     size_t len2 = p3 - p1; 
     char* res2 = (char*)malloc(sizeof(char)*(len2 + 1)); 
     strncpy(res2, p1, len2); 

     res2[len2] = '\0'; 

     // give res2 for functionFemale() to work on that string 
    } 

    else if (strcmp(buffer, " -> ") == 0) 
    { 
     // work in progress (quite complicated to do this i think) 
     // it has to be a realtion between two people 
    } 

    else if (strcmp(buffer, ";") == 0) 
    { 
     // work in progress 
     // this sign can either exist like this: 
     // "Bart [m]" -> "Marge [f]"; 

     // or like this: 
     // "Marge [f]"; 
    } 

    break; 
    } 
    else 
    { 
    printf("Parsing Error 3\n"); 
    } 

    row2++; 

} 

// et le signe dernier doit être} \ n

+0

1) Afficher la définition de 'string' et' changeLastC() ', 2) Assurez-vous que les avertissements du compilateur sont entièrement activés. 3) Pourquoi attendre que '" readEveryLine \ n "' soit égal à "readEveryLine" '? Sinon, le problème n'est pas bien spécifié. – chux

+2

Pourquoi diable voulez-vous utiliser 'strncmp'? La fonction correcte à cet effet est 'strcmp'. – rici

+0

@chux, Il n'y a pas de '\ n' en fin de ligne. D'après le commentaire, '\ n' est changé en' \ 0' par la fonction 'changeLastC()' – Gerhardh

Répondre

0

Votre algorithme est déjà cassé. Vous utilisez le même contenu de *file_string pour le comparer à deux chaînes différentes. Si vous trouvez un match pour "readEveryLine" vous avez besoin de lire la ligne suivante de votre dossier avant d'obtenir le prochain match pour strncmp(). Sinon, la ligne du fichier doit correspondre à la fois "readEveryLine"et"{" pour passer votre deuxième condition if, ce qui est impossible.

Editer: Maintenant que vous avez fait quelques améliorations, je pense toujours que cela ne fonctionnera pas avec votre approche. Les boucles ne sortiront pas quand elles le devraient et votre if-else-cascade ne semble pas être une bonne idée. Dans votre approche, vous risquez d'avoir à lire trop de lignes alors qu'une seule ligne devrait être analysée. Peut-être que vous devriez lire un peu sur les machines d'état.

Voici une approche rapide comment je résoudre le problème:

enum { STATE_HEADER1, STATE_HEADER2, STATE_BODY, STATE_END} state; 
int done = 0; 
state = STATE_HEADER1; 

while (fgets(buffer, MAX_PARSING, fp) && !done) {   
    if (state == STATE_HEADER1) { 
    if (strcmp(buffer, "readEveryLine\n") == 0) { 
     printf("%s", buffer); 
     state = STATE_HEADER2; 
    } 
    else { 
     printf("Parsing Error 1\n"); 
     done = 1; 
    }   
    } 
    else if (state == STATE_HEADER2) { 
    if (strcmp(buffer, "{\n") == 0) { 
     printf("%s", buffer); 
     state = STATE_BODY; 
    } 
    else { 
     printf("Parsing Error 2\n"); 
     done = 1; 
    } 
    } 
    else if (state == STATE_BODY) { 
    if (strcmp(buffer, " ") == 0) { 
     const char *p1 = strstr(buffer, "\""); 
     const char *pm = strstr(p1, " [m]\""); 
     const char *pf = strstr(p1, " [f]\""); 
      char *res; 
     const char *ptemp; 
     int is_male; 

     if (p1 && pf) { 
     p1 ++; 
     is_male = 0; 
     size_t len1 = pf - p1; 
     res = malloc(len1 + 1); 
     strcpy(res, p1); 
     ptemp = pf+3; // point after closing \" 

     // give res for functionFemale() to work on that string 
     } 
     else if (p1 && pm) { 
     p1 ++; 
     is_male = 1; 
     size_t len1 = pm - p1; 
     res = malloc(len1 + 1); 
     strcpy(res, p1); 
     ptemp = pm+3; // point after closing \" 

     // give res for functionMale() to work on that string 
     } 
     else { 
     done = 1; 
     printf("Parsing Error 2\n"); 
     } 

     // Now we have res and is_male holding name and gender. 

     if (!done) 
     { 
     if (strncmp(ptemp, " -> ", 4) == 0) { 

    // Handle this variant: 
    // this sign can either exist like this: 
    // "Bart [m]" -> "Marge [f]"; 

      // Do similar stuff as above for first name 

      // Get second name + gender 
      // Also check trailing ';' here 
     } 
     else if (strcmp(temp, ";\n") == 0) { 

// Handle this variant: 
// or like this: 
// "Marge [f]"; 

     } 

     } // found " " 
     else { 
     if (strcmp(buffer, "}\n") == 0) { 
      state = STATE_END; 
      done = 1; 
      printf("That's it folks...\n"); 
     } 
     else { 
      done = 1; 
      printf("Parsing Error 3\n"); 
     } 
     } 
    } 
    } // STATE_BODY 
} // while (fgets) 

if (state == STATE_END) } 
    // Success. :) 
} else { 
    // Something didn't match. 
} 

// close file, cleanup, etc. 

Je ne compile pas encore, mais vous devriez avoir l'idée.

+0

sonne clair. le problème est, que je ne sais pas comment analyser la ligne suivante, faire une autre condition si, puis analyser la troisième ligne, faire la prochaine condition si et ainsi de suite. Merci beaucoup pour votre aide. – MBD

+0

Par exemple si j'utilise une boucle while comme ceci: while (fgets (file_string, 19, file)) et utilise ce tampon pour la première ligne alors je ne sais pas si je devrais utiliser une boucle pour chaque ligne et un nouveau buffer. Je pense que je me trompe avec ça. Merci beaucoup pour votre aide. – MBD

+0

Essayez-le avec du pseudo-code. Essayez de l'expliquer à votre canard en caoutchouc ou votre animal de compagnie, ce que vous voulez faire. Vous pouvez également essayer de le faire sur papier. S'il y a des phrases comme "d'abord ..., alors ..." vous avez besoin d'une séquence d'actions séparées. Pas de boucle. S'il y a des phrases comme "Pour chaque ligne ...", alors vous avez besoin d'une boucle. Avec ceci, il devrait être clair que vous n'avez pas besoin d'une boucle pour les 2 premières lignes de votre fichier. Mais vous avez besoin d'une boucle pour toute ligne suivante. Et quelques handlnig pour la dernière ligne ("} \ n"). Je vous suggère de creuser à nouveau dans votre livre de texte en C et de digérer un peu plus les boucles _when_ et _how_. – Gerhardh