2010-11-21 11 views
5

He escrito el siguiente programa para leer línea por línea desde un archivo y almacenarlo en el conjunto de palabras. La salida debe ser de dos palabras aleatorias de la matriz. Pero, sorprendentemente, la matriz de palabras contiene solo la última palabra leída repetidamente. ¿Alguna ayuda sobre lo que salió mal?Lectura de un archivo y almacenamiento en matriz

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; 
} 

entrada.txt

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

¡Nunca te rendiré! Nunca va a ... oh, lo siento. –

+0

Quité la etiqueta de Python –

+0

Me di cuenta:) ... –

Respuesta

6

Lea cada línea de datos en el mismo búfer, por lo que la última línea sobrescribe todas las líneas anteriores. Tendrá que asignar espacio para cada línea de una u otra manera: asignación de memoria dinámica con malloc() (o posiblemente strdup()), o utilizando una matriz de tamaño fijo (lo que limita la cantidad de datos que su programa puede manejar de manera segura). También necesitará lidiar con nuevas líneas en la lectura de datos.

Obtienes algún crédito por usar fgets() y no usar gets(); esa es una decisión 100% correcta.


#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; 
} 

Esto comprueba que el archivo se abre correctamente, cierra el archivo tan pronto como la lectura se ha completado, y asegura que no provoca un desbordamiento de pila mediante la lectura de más líneas que la matriz puede contener. Se desperdicia mucho espacio asignando demasiado espacio, por lo que cada línea puede ser muy larga (aunque las líneas suelen ser bastante cortas). Si una línea es más larga que BUFSIZ, se leerá en un par de entradas adyacentes en lines. No supone que haya 8 líneas en el archivo de datos. Desplaza la nueva línea al final de cada línea (a menos que una línea se divida, en cuyo caso elimina el último carácter antes de la división en la primera de las dos líneas). Siembra el generador de números aleatorios con la hora actual. Parece extraño que solo quieras líneas adyacentes del archivo.

+0

No lo entendí del todo ... ¿Puedes mostrar la asignación con un código de muestra? Arreglos de tamaño fijo hará. – razor35

1

Quizás quiso inicializar el generador de números aleatorios con srand? Una explicación, con un ejemplo de cómo usarlo is available here.

2

Sobreescribe repetidamente la memoria en line_buffer. La matriz de palabras contiene solo punteros esta variable.

Debe utilizar una matriz multidimensional o asignar memoria en tiempo de ejecución.

Por cierto: las cosas malo va a pasar cuando se pasa más de 20 líneas de código ...

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. Verificar el resultado de malloc

Cuestiones relacionadas