为什么这段代码没有输出预期的输出?
这可能是一个寻找错误的好问题。 不?至少对于初学者来说还可以。
#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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
'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。事实上,我会把你的循环写成:
为了回答你的另一个问题,
'\0'
是int
0,所以{'\0'}< /code> 和
{0}
是等效的。对于
setvbuf
,我的文档说:为什么用
\\
而不是//
或/* */
进行注释? :-)编辑:根据您对问题的编辑,
sizeof("1")
是错误的,sizeof(char)
是正确的。sizeof("1")
为 2,因为"1"
是一个包含两个元素的char
数组:'1'和<代码>0。
The type of
'1'
isint
in C, notchar
, so you are readingSIZE*sizeof(int)
bytes in eachfread
. Ifsizeof(int)
is greater than 1 (on most modern computers it is), then you are reading past the storage forbuffer
. This is one of the places where C and C++ are different: in C, character literals are of typeint
, in C++, they are of typechar
.So, you need
chars_read = fread(buffer, 1, SIZE, stdin);
becausesizeof(char)
is 1 by definition.In fact, I would write your loop as:
To answer your another question,
'\0'
is theint
0, so{'\0'}
and{0}
are equivalent.For
setvbuf
, my documentation says: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 achar
array containing two elements:'1'
and0
.这是使用重定向从文件中逐字节读取行的方法 ./a.out <数据。
至少产生预期的输出...:-)
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 ... :-)
字符缓冲区[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.