从stdin读取(可变长度的文件)

时间:2012-05-08 02:28:04

标签: c stdin

所以我一直试图以各种不同的方式将这项工作转移到作业,但每次我都会遇到不同的错误。基本上我们所拥有的是一个程序,需要逐字节读取将被管道传输的文件的内容(文件长度可能很大,所以我们不能只调用malloc并分配大块空间)。我们需要使用realloc来扩展释放的内存量,直到我们到达文件末尾。最终结果应该是一个包含每个字节的长C字符串(数组)(如果它们是文件的一部分,我们也不能忽略空字节)。我现在所拥有的是:

   char *buff;
   int n = 0;
   char c;
   int count;

   if (ferror (stdin))
   {
      fprintf(stderr, "error reading file\n");
      exit (1);
   }
   else
   {
      do {   
         buff = (char*) realloc (buff, n+1);
         c = fgetc (stdin);
         buff[n] = c;
         if (c != EOF)
             n++;
     }
       while (c != EOF);
   }
   printf("characters entered: ");
   for (count = 0; count < n; count++)
       printf("%s ", buff[count]);
   free (buff);

它应该一直读到文件的末尾,每次扩展内存但是当我尝试通过在简单的文本文件中管道来运行它时,它告诉我我有一个分段错误。我不太确定我做错了什么。

请注意,我们被允许使用malloc和诸如此类的东西,但由于我们知道需要多少内存,所以我无法看到如何使用它。

4 个答案:

答案 0 :(得分:3)

您在第一次调用realloc时使用的是未分配的指针buf。改为

char *buf = malloc(100);

避免这个问题。

一旦你开始工作,你会注意到你的程序效率很低,每个字符都有一个realloc。考虑重新分配更大的块以减少重新分配的数量。

答案 1 :(得分:3)

char* buff;
...
buff = (char*) realloc (buff, n+1);

您正在尝试重新分配未初始化的指针,这会导致未定义的行为。改为

char* buff = 0;
...
buff = (char*) realloc (buff, n+1);

但正如已经指出的那样,这是非常低效的。

答案 2 :(得分:2)

似乎@dasblinkenlight和@smocking的答案是目前的原因,但要避免下一次崩溃:

  1. char c;更改为int c;,因为EOF由多个字符表示。
  2. 每次为一个字符调用realloc是一个坏主意,而是每次增加X字节的大小(假设为100),这样会更有效率。
  3. 您需要在缓冲区的末尾添加空终止符('\ 0'),否则 - printf()处的未定义行为。

答案 3 :(得分:0)

以下是我在stdinchar[]char*中嵌入NULL时)阅读stdin时的想法:

char* content = NULL;
char c;
int contentSize = 0;

while ((c = fgetc(stdin)) != EOF){
    contentSize++;
    content = (char*)(realloc(content, contentSize+1));
    if (content == NULL) {
        perror("Realloc failed.");
        exit(2);
    }
    content[contentSize] = c;
}

for (int i = 0; i < contentSize; ++i) {
    printf("%c",content[i]);
}