2016-11-03 2 views
0

Dans le code ci-dessous, le fichier test.txt a les données suivantes:
192.168.1.1-90
192.168.2.2-80strtok et le stockage dans les tableaux: sortie pas comme prévu

La sortie de cette n'est pas comme prévu. je me attends à la sortie soit
192.168.1.1
192.168.2.2
Toute aide serait grandement appréciée.

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ 
    FILE *fp; 
    char *result[10][4]; 
    int i=0; 
    const char s[2] = "-"; 
    char *value,str[128]; 
    fp = fopen("test.txt", "r"); 
    if (fp == NULL) 
    printf("File doesn't exist\n"); 
    else{ 
    while(!feof(fp)){ 

     if(fgets(str,sizeof(str),fp)){ 

     /* get the first value */ 
     value = strtok(str, s); 
     result[i][0]=value; 
     printf("IP : %s\n",result[i][0]); //to be removed after testing 


     /* get second value */ 
     value = strtok(NULL, s); 
     result[i][1]=value; 
     printf("PORT : %s\n",result[i][1]); //to be removed after testing 
     i++; 
    }} 
    for (int k=0;k<2;k++){ 
     for (int j=0;j<2;j++){ 
      printf("\n%s\n",result[k][j]); 
     } 
    } 

} 
     return(0); 
} 
+0

Vous avez la sortie attendue mais ajoutez également la sortie réelle (erronée). – kaylum

+2

La boucle 'while' remplace constamment le même tampon' str'. Ce n'est probablement pas ce que tu veux. Et aussi voir [Pourquoi est-ce que tant que (! Feof (fichier)) "toujours mal?] (Http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – kaylum

+0

Si faire POSIX, remplace 'strtok (str, s)' par 'strdup (strtok (str, s))'. Veillez également à libérer 'result [i] [x]' s'il n'est pas utilisé plus que. – alk

Répondre

0

Vous pouvez essayer cette solution. Il utilise la mémoire dynamique à la place, mais fait ce que votre après.

Le code:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define BUFFSIZE 128 

void exit_if_null(void *ptr, const char *msg); 

int 
main(int argc, char const *argv[]) { 
    FILE *filename; 
    char buffer[BUFFSIZE]; 
    char *sequence; 
    char **ipinfo; 
    int str_size = 10, str_count = 0, i; 

    filename = fopen("ips.txt", "r"); 

    if (filename == NULL) { 
     fprintf(stderr, "%s\n", "Error Reading File!"); 
     exit(EXIT_FAILURE); 
    } 

    ipinfo = malloc(str_size * sizeof(*ipinfo)); 
    exit_if_null(ipinfo, "Initial Allocation"); 

    while (fgets(buffer, BUFFSIZE, filename) != NULL) { 
     sequence = strtok(buffer, "-\n"); 

     while (sequence != NULL) { 
      if (str_size == str_count) { 
       str_size *= 2; 
       ipinfo = realloc(ipinfo, str_size * sizeof(*ipinfo)); 
       exit_if_null(ipinfo, "Reallocation"); 
      } 

      ipinfo[str_count] = malloc(strlen(sequence)+1); 
      exit_if_null(ipinfo[str_count], "Initial Allocation"); 

      strcpy(ipinfo[str_count], sequence); 

      str_count++; 

      sequence = strtok(NULL, "-\n"); 
     } 
    } 

    for (i = 0; i < str_count; i++) { 
     printf("%s\n", ipinfo[i]); 
     free(ipinfo[i]); 
     ipinfo[i] = NULL; 
    } 

    free(ipinfo); 
    ipinfo = NULL; 

    fclose(filename); 

    return 0; 
} 

void 
exit_if_null(void *ptr, const char *msg) { 
    if (!ptr) { 
     printf("Unexpected null pointer: %s\n", msg); 
     exit(EXIT_FAILURE); 
    } 
} 
0

L'essentiel à comprendre est que char *strtok(char *str, const char *delim) interne modifie la chaîne pointée par str et utilise pour enregistrer le résultat. Le pointeur renvoyé pointe donc vers quelque part dans str.

Dans votre code, le contenu de str est actualisé chaque fois que vous analysez une nouvelle ligne dans le fichier, mais l'adresse reste la même. Donc, après votre boucle while, le contenu de str est la dernière ligne du fichier, en quelque sorte modifié par . À ce moment, result[0][0] et result[1][0] pointent tous deux vers la même adresse, ce qui correspond au début de str. Donc, vous imprimez la même chose deux fois à la fin.

Ceci est illustré plus en détail dans les commentaires ajoutés à votre code.

int main() 
{ 
    FILE *fp; 
    char *result[10][4]; 
    int i=0; 
    const char s[2] = "-"; 
    char *value,str[128]; 
    fp = fopen("test.txt", "r"); 
    if (fp == NULL) 
     printf("File doesn't exist\n"); 
    else{ 
     while(!feof(fp)){ 

      if(fgets(str,sizeof(str),fp)){ 

       /* get the first value */ 
       value = strtok(str, s); 
       // ADDED: value now points to somewhere in str 
       result[i][0]=value; 
       // ADDED: result[i][0] points to the same address for i = 0 and 1 
       printf("IP : %s\n",result[i][0]); //to be removed after testing 


       /* get second value */ 
       value = strtok(NULL, s); 
       // ADDED: value now points to somewhere in str 
       result[i][1]=value; 
       // ADDED: result[i][1] points to the same address for i = 0 and 1 
       printf("PORT : %s\n",result[i][1]); //to be removed after testing 
       i++; 
      }} 
     // ADDED: now result[0][0]==result[1][0], result[0][1]==result[1][1], you can test that 
     for (int k=0;k<2;k++){ 
      for (int j=0;j<2;j++){ 
       printf("\n%s\n",result[k][j]); 
      } 
     } 

    } 
    return(0); 
} 

Pour obtenir le résultat attendu, vous devez copier la chaîne pointée par le pointeur retourné par strtok à un autre endroit à chaque fois, plutôt que de simplement copier le pointeur lui-même.