2010-11-21 6 views
5

J'ai écrit le programme suivant pour lire ligne par ligne à partir d'un fichier et le stocker dans le tableau de mots. La sortie devrait être deux mots aléatoires du tableau. Mais étonnamment le tableau de mots contient seulement le dernier mot lu à plusieurs reprises. Toute aide sur ce qui a mal tourné?Lire à partir d'un fichier et le stocker dans le tableau

int main(){ 
int i = 0; 
char line_buffer[BUFSIZ]; 
char* words[20]; 
FILE *fp = fopen("input.txt", "r"); 
    while (fgets(line_buffer, sizeof(line_buffer), fp)) { 
    //printf("%s", line_buffer); 
    words[i] = line_buffer; 
    i = i + 1; 
} 
printf("%d", i); 
int j = rand()%8; 
    int k = (j+1)%8; 
printf("%s %s", words[j], words[k]); 
fclose(fp); 
return 0; 
} 

input.txt

nematode knowledge 
empty bottle 
nevertheless 
claustrophobia 
metamorphosis 
acknowledgement 
impossibility 
never gave up 
+8

Ne jamais vous abandonner! Jamais ... oh, désolé. –

+0

J'ai enlevé la balise Python –

+0

J'ai remarqué:) ... –

Répondre

6

Vous lisez chaque ligne de données dans le même tampon, de sorte que la dernière ligne écrase toutes les lignes précédentes. Vous devrez allouer de l'espace pour chaque ligne par un moyen ou un autre - soit l'allocation de mémoire dynamique avec malloc() (ou éventuellement strdup()), ou en utilisant un tableau de taille fixe (qui limite la quantité de données que votre programme peut gérer en toute sécurité). Vous devrez également gérer les retours à la ligne dans les données lues.

Vous obtenez un certain crédit pour utiliser fgets() et ne pas utiliser gets(); c'est une décision 100% correcte.


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

enum { MAXLINES = 30 }; 

int main(void) 
{ 
    int i = 0; 
    char lines[MAXLINES][BUFSIZ]; 
    FILE *fp = fopen("input.txt", "r"); 

    if (fp == 0) 
    { 
     fprintf(stderr, "failed to open input.txt\n"); 
     exit(1); 
    } 
    while (i < MAXLINES && fgets(lines[i], sizeof(lines[0]), fp)) 
    { 
     lines[i][strlen(lines[i])-1] = '\0'; 
     i = i + 1; 
    } 
    fclose(fp); 
    printf("%d\n", i); 
    srand(time(0)); 
    int j = rand() % i; 
    int k = (j+1) % i; 
    printf("%s %s\n", lines[j], lines[k]); 
    return 0; 
} 

Cela permet de vérifier que le fichier a été ouvert avec succès, clôt le dossier dès que la lecture est terminée, et assure qu'il ne déclenche pas un débordement de pile en lisant plus de lignes que le tableau peut contenir. Cela gaspille beaucoup d'espace en allouant trop d'espace, de sorte que chaque ligne peut être très longue (bien que les lignes soient généralement assez courtes). Si une ligne est plus longue que BUFSIZ, elle sera lue dans deux entrées adjacentes dans lines. Il ne suppose pas qu'il y a 8 lignes dans le fichier de données. Il zappe la nouvelle ligne à la fin de chaque ligne (sauf si une ligne est divisée, auquel cas elle zappe le dernier caractère avant la division sur la première des deux lignes). Il ensemence le générateur de nombres aléatoires avec l'heure actuelle. Il semble étrange que vous ne vouliez que des lignes adjacentes du fichier.

+0

Je n'ai pas compris complètement .. Pouvez-vous montrer l'allocation avec un exemple de code? Les tableaux de taille fixe feront l'affaire. – razor35

1

Avez-vous initialiser le générateur de nombres aléatoires avec srand? Une explication, avec un exemple de comment l'utiliser is available here.

2

Vous remplacez à plusieurs reprises la mémoire dans line_buffer. Le tableau de mots contient seulement des pointeurs cette variable.

Vous devez utiliser un tableau multidimensionnel ou allouer de la mémoire au moment de l'exécution.

BTW: Les mauvaises choses vont se produire lorsque vous passez plus de 20 lignes à votre code ...

3
int main(){ 
int i = 0; 

int BUFSIZE = 1000; 
char* words[20]; 
FILE *fp = fopen("input.txt", "r"); 
if (fp == 0){ 
     fprintf(stderr, "Error while opening"); 
     exit(1); 
} 

words[i] = malloc(BUFSIZE); 
    while (fgets(words[i], BUFSIZE, fp)) { 
     i++; 
     words[i] = malloc(BUFSIZE); 
} 
printf("Output: \n"); 
srand(time(NULL)); 
int j = rand()%i; 
int k = (j+1)%i; 
fflush(stdout); 
printf("%d - %s %d -%s", j, words[j], k, words[k]); 

int x; 
for(x = 0; x<i; x++) 
     free(words[x]); 
scanf("%d", x); 
fclose(fp); 
return 0; 
} 

ps. Vérifiez le résultat de malloc