为什么这段代码没有输出预期的输出?

发布于 2024-08-23 17:30:53 字数 932 浏览 11 评论 0原文

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

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

使用上面的代码,我尝试使用重定向 ./a.out ./a.out 从文件中读取内容。数据。输入文件的内容:

1line
2line
3line
4line

但是我没有得到预期的输出,而是混合了一些图形字符。 怎么了?


提示:(Courtesy Alok)

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

所以,使用 1相反:-)

看看这个post 使用 fread 的缓冲 IO 示例

This can be a good question for finding bugs.
No? Okay for beginners at least.

#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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萌吟 2024-08-30 17:30:53

'1' 的类型在 C 中是 int,而不是 char,因此您正在阅读 SIZE*sizeof(int)fread 中的 code> 字节。如果 sizeof(int) 大于 1(在大多数现代计算机上都是如此),那么您正在读取 buffer 的存储空间。这是 C 和 C++ 不同的地方之一:在 C 中,字符文字的类型为 int,在 C++ 中,它们的类型为 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'int 0,所以{'\0'}< /code> 和 {0} 是等效的。

对于 setvbuf,我的文档说:

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

为什么用 \\ 而不是 ///* */ 进行注释? :-)

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

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

The type of '1' is int in C, not char, so you are reading SIZE*sizeof(int) bytes in each fread. If sizeof(int) is greater than 1 (on most modern computers it is), then you are reading past the storage for buffer. This is one of the places where C and C++ are different: in C, character literals are of type int, in C++, they are of type char.

So, you need chars_read = fread(buffer, 1, SIZE, stdin); because sizeof(char) is 1 by definition.

In fact, I would write your loop as:

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

To answer your another question, '\0' is the int 0, so {'\0'} and {0} are equivalent.

For setvbuf, my documentation says:

The size argument may be given as zero to obtain deferred optimal-size buffer allocation as usual.

Why are you commenting with \\ instead of // or /* */? :-)

Edit: Based upon your edit of the question, sizeof("1") is wrong, sizeof(char) is correct.

sizeof("1") is 2, because "1" is a char array containing two elements: '1' and 0.

此岸叶落 2024-08-30 17:30:53

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

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

/*

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;

}

Here's a byte-by-byte way to fread the lines from a file using redirection ./a.out < data.

Produces the expected output at least ... :-)

/*

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;

}
暖心男生 2024-08-30 17:30:53

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

这并没有达到您的预期,它使缓冲区指向程序常量数据段中的一个字节区域。即,这将损坏 SIZE 字节数并可能导致内存保护故障。始终使用 strcpy() 或等效函数初始化 C 字符串。

char buffer[SIZE + 1] = {0};

This isn't doing what you expect, it is making buffer point to a one byte region in the programs constant data segment. I.e this will corrupt SIZE amount of bytes and possibly cause a memory protection fault. Always initialize C strings with strcpy() or equivalent.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文