这对于发现错误来说是一个很好的问题。 没有?好吧,至少对于初学者来说。
#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 But I am not getting the expected output, rather some graphical characters are mixed in.
What is wrong? Hint: (Courtesy Alok) So, use 1 instead :-)
。
./a.out < data
. Contents of input file:1line
2line
3line
4line
sizeof('1') == sizeof(int)
sizeof("1") == sizeof(char)*2
答案 0 :(得分:9)
C中'1'
的类型为int
,而不是char
,因此您在每个SIZE*sizeof(int)
中读取fread
个字节。如果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'}
和{0}
是等效的。
对于setvbuf
,我的文档说:
size
参数可以为零,以便像往常一样获得延迟的最佳大小缓冲区分配。
为什么要使用\\
而不是//
或/* */
进行评论? : - )
修改:根据您对问题的修改,sizeof("1")
错误,sizeof(char)
是正确的。
sizeof("1")
为2,因为"1"
是一个char
数组,其中包含两个元素:'1'
和0
。
答案 1 :(得分:0)
这是使用重定向来从文件中传播行的逐字节方式./a.out&lt;数据
至少产生预期的输出......: - )
/*
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;
}
答案 2 :(得分:-1)
char buffer [SIZE + 1] = {0};
这不是你所期望的,它使缓冲区指向程序常量数据段中的一个字节区域。即,这将破坏SIZE字节数,并可能导致内存保护错误。始终使用strcpy()或等效函数初始化C字符串。