从文件中读取并存储到数组中

6
我已经编写了以下程序,用于逐行从文件中读取并将其存储在单词数组中。输出应该是数组中的两个随机单词。但令人惊讶的是,单词数组只包含重复读取的最后一个单词。请问出了什么问题?
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

10
永远不会放弃你!永远不会……哦,对不起。 - Tim Pietzcker
我删除了Python标签。 - Eli Bendersky
4个回答

7
你需要将每一行数据读入到不同的缓冲区中,这样才能避免最后一行覆盖之前的所有行。你可以通过动态内存分配函数malloc()(或可能是strdup())来为每一行分配空间,或者使用固定大小的数组(这会限制程序可以安全处理的数据量)。此外,你还需要处理读取数据中的换行符。
你因为使用了fgets()而没有使用gets()而获得了一些信誉;这是一个100%正确的决定。
#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;
}

这段代码检查文件是否成功打开,一旦读取完成就关闭文件,并确保不会读取比数组容量更多的行数以避免触发堆栈溢出。这种方法通过过度分配空间来浪费大量内存,因此每行可以非常长(尽管行通常相当短)。如果一行超过BUFSIZ,它将被读入lines中的两个相邻条目中。它不假设数据文件中有8行。它删除每行末尾的换行符(除非一行被分割,此时它删除第1行分割之前的最后一个字符)。它用当前时间为随机数生成器提供种子。奇怪的是,您只希望从文件中获取相邻的行。


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. 检查malloc的结果


2

您不断地覆盖line_buffer中的内存。该变量只包含指针数组。

您应该使用多维数组或在运行时分配内存。

顺便说一下:当您向代码传递超过20行时,会发生糟糕的事情...


1
你是否使用了srand初始化随机数生成器?一个解释和如何使用的示例 在这里可用

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接