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)
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)
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)
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)
So, use 1 instead :-)
Take a look at this post for buffered IO example using fread.
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
.
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;
}
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. Ie this will corrupt SIZE amount of bytes and possibly cause a memory protection fault. Always initialize C strings with strcpy() or equivalent.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.