2

这对于查找错误来说是一个很好的问题。不?至少对初学者来说还可以。

#define SIZE 4
int main(void){
  int chars_read = 1;
  char buffer[SIZE + 1] = {0};  
  setvbuf(stdin, (char *)NULL, _IOFBF, sizeof(buffer)-1);  
  while(chars_read){
    chars_read = fread(buffer, sizeof('1'), SIZE, stdin);
    printf("%d, %s\n", chars_read, buffer);
  }
  return 0;
}

Using the above code, I am trying to read from a file using redirection ./a.out < data. Contents of input file:

1line
2line
3line
4line

But I am not getting the expected output, rather some graphical characters are mixed in. What is wrong?


Hint: (Courtesy Alok)

  • sizeof('1') == sizeof(int)
  • sizeof("1") == sizeof(char)*2

So, use 1 instead :-)

Take a look at this post for buffered IO example using fread.

4

3 回答 3

9

的类型'1'intC 中,而不是char,因此您正在读取SIZE*sizeof(int)each 中的字节fread。如果sizeof(int)大于 1(在大多数现代计算机上是),那么您正在阅读超过buffer. 这是 C 和 C++ 不同的地方之一:在 C 中,字符文字是 type int,在 C++ 中,它们是 type char

因此,您需要chars_read = fread(buffer, 1, SIZE, stdin);因为sizeof(char)定义为 1。

事实上,我会把你的循环写成:

while ((chars_read = fread(buffer, 1, sizeof buffer - 1)) > 0) {
    buffer[chars_read] = 0; /* In case chars_read != sizeof buffer - 1.
                               You may want to do other things in this case,
                               such as check for errors using ferror. */
    printf("%d, %s\n", chars_read, buffer);
}

要回答你的另一个问题,'\0'int0,所以{'\0'}{0}是等价的。

对于setvbuf,我的文档说:

size参数可以为零,以像往常一样获得延迟的最佳大小缓冲区分配。

你为什么评论\\而不是//or /* */?:-)

编辑:根据您对问题的编辑,sizeof("1")是错误的,sizeof(char)是正确的。

sizeof("1")是 2,因为"1"是一个char包含两个元素的数组:'1'0

于 2010-03-04T10:10:34.547 回答
0

这是使用重定向 ./a.out < data 从文件中逐字节读取行的方法。

至少产生预期的输出...... :-)

/*

Why does this code not output the expected output ?,
http://stackoverflow.com/questions/2378264/why-does-this-code-not-output-the-expected-output

compile with:
gcc -Wall -O3 fread-test.c

create data:
echo $'1line\n2line\n3line\n4line' > data

./a.out < data

*/

#include <stdio.h>

#define SIZE 5

int main(void) 
{

   int i=0, countNL=0;
   char singlechar = 0;
   char linebuf[SIZE + 1] = {0};
   setvbuf(stdin, (char *)NULL, _IOFBF, sizeof(linebuf)-1);  

   while(fread(&singlechar, 1, 1, stdin))     // fread stdin byte-by-byte
   {
      if ( (singlechar == '\n') )
      {
         countNL++;
         linebuf[i] = '\0';
         printf("%d:  %s\n", countNL, linebuf);
         i = 0;
      } else {
         linebuf[i] = singlechar; 
         i++;
      }
   }

   if ( i > 0 )    // if the last line was not terminated by '\n' ...
   {
      countNL++;
      linebuf[i] = '\0';
      printf("%d:  %s\n", countNL, linebuf);
   }

 return 0;

}
于 2010-03-05T12:45:51.737 回答
-1

字符缓冲区[大小 + 1] = {0};

这不是你所期望的,它使缓冲区指向程序常量数据段中的一个字节区域。即,这将破坏 SIZE 字节数,并可能导致内存保护错误。始终使用 strcpy() 或等效方法初始化 C 字符串。

于 2010-03-05T04:09:08.410 回答