2011-03-18 4 views
3

J'ai un fichier d'entiers séparés par des tabulations (un fichier .txt) et je souhaite les lire avec C, ligne par ligne. Donc, disons que chaque ligne a 5 entiers. Comment puis-je accomplir cela?Comment lire dans un fichier texte des entiers séparés par des tabulations dans C?

Ma première tentative a été la suivante. Il était juste de lire dans un seul entier, mais même cela ne fonctionne pas:

FILE *fp; 
    char blah[255]; 
    int *some_int; 
fp = fopen("test.txt", "rt"); 
while (fgets(blah, 255, fp) != NULL) 
{ 
    sscanf(blah, "%d", some_int); 
    printf("%d\n", *some_int); 
} 
+0

Je vais mettre à jour avec ma tentative initiale .. – soxarered

+1

'some_int' est un pointeur non initié. Pourquoi avez-vous pris some_int est de type 'int *'? N'importe quelle raison. – Mahesh

+0

Chaque ligne a-t-elle le même nombre de chiffres? Si oui, ce nombre est-il une constante de compilation ou une valeur d'exécution? –

Répondre

3

est ici une façon personne ne suggère d'autre, qui ne pas utiliser fscanf afin que vous puissiez avoir la gestion des erreurs sain d'esprit:

char buffer[BUFSIZE]; 
size_t size = 5; 
int *data = malloc(size * sizeof *line); 

if(line == NULL) error(); 

while(fgets(buffer, sizeof buffer, fp) 
    { 
    size_t i = 0; 
    char *next = buffer; 
    while(*next && *next != '\n') 
     { 
     data[i++] = strtol(next, &next, 0); 
     // check for errors 
     } 
    } 

En fait, au lieu d'essayer d'utiliser *scanf « s "%d" lire les caractères , utilisez la fonction qu'elle appelle (probablement) pour effectuer la conversion: strtol. Où *scanf passe par la chaîne pour correspondre à la chaîne de format, mais ne vous laisse pas "enregistrer votre place" entre les appels de fonction, strtol fait, qui est ce que vous avez besoin de lire un nombre arbitraire d'entiers.

Je n'ai pas écrit tout votre code pour vous - vous devez faire le traitement des erreurs matérielles. erreurs possibles:

  1. , dans ce cas, vous pouvez essayer de faire data plus grand avec realloc. Alternativement, vous pouvez parcourir la mémoire tampon et compter le nombre de numéros à l'avance, puis en allouer autant que vous n'avez pas besoin de réallouer plus tard.
  2. fgets n'a pas lu la ligne entière (vérifiez que le dernier caractère avant '\0' est '\n'). Dans ce cas, vous voudrez probablement recharger le tampon et continuer à lire les chiffres. Soyez prudent dans ce cas - vous devrez probablement revenir en arrière et recalculer le dernier numéro - fgets pourrait l'avoir coupé. (Ceci est un désavantage d'utiliser fgets.)
  3. Entrée erronée - gérer comme vous le souhaitez.
1

je ferais quelque chose comme ceci:

int storedVals[MAX_STORED_VALS]; 
int bf; 
int ii=0; 

while (!feof(fp) && ii<MAX_STORED_VALS) { 
    if (fscanf(fp," %d",&bf)) { 
    storedVals[ii++]=bf; 
    } 
} 

fscanf fait automatiquement élimination des espaces. Donc, tant qu'il y a un espace dans votre chaîne d'analyse, il va se débarrasser de zéro ou plus de \ t (onglets) et de \ n (nouvelles lignes) pour trouver l'entier suivant. Bien sûr, cela ne fait pas grand-chose en matière de correction d'erreur.

+0

Juste confirmation, les vecteurs sont-ils disponibles en C? Je pensais qu'il s'agissait d'une fonctionnalité C++. – soxarered

+0

Oop. D'accord, ils ne sont qu'une chose C++. – JCooper

+0

Je l'ai modifié, mais maintenant vous devez soit connaître le nombre de valeurs auxquelles vous devez vous attendre, soit créer votre propre vecteur ou structure de données semblable à une liste pour stocker des valeurs. – JCooper

2
#include <stdio.h> 
int main(){ 
    FILE *fp; 
    int scanned = 0; 
    int some_ints[5]; 
    fp = fopen("test.txt", "r"); 
    while ((scanned = fscanf(fp, "%d %d %d %d %d", some_ints, some_ints+1, some_ints+2, some_ints+3, some_ints+4)) != EOF) { 
     if(scanned ==5){ 
      printf("%d %d %d %d %d\n", some_ints[0], some_ints[1], some_ints[2], some_ints[3], some_ints[4]); 
     } 
     else { 
      printf("Whoops! Input format is incorrect!\n"); 
      break; 
     } 
    } 
} 
+0

Je ne sais pas si les données OP sont dans un nombre fixe de lignes par fichier, mais je préfère de loin la combinaison 'fgets' /' sscanf' de l'OP pour la sécurité et la gestion des erreurs (mais il devrait le rendre plus robuste) juste 'fscanf'. De plus, votre code produira des résultats erronés s'il y a trop peu de nombres dans le fichier (cela réimprimera les anciens numéros). –

+0

@Chris Lutz Je supposais que l'entrée était dans le bon format. Je l'ai édité pour vérifier et m'assurer qu'il a toujours réussi à lire 5 nombres entiers. –

Questions connexes