\377 character in c - c

i am trying to read a file in c.
i have a .txt file and it has that content:
file_one.txt file_two.txt file_three.txt file_four.txt
when i try to read this file with fopen i get this output:
file_one.txt file_two.txt file_three.txt file_four.txt\377
what does \377 mean? Here's my code.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]){
FILE *filelist;
char ch;
filelist=fopen("file-path", "rt");
while (!feof(filelist)) {
ch = getc(filelist);
printf("%c",ch);
}
fclose(filelist);
return 0;
}

The getc() function returns a result of type int, not of type char. Your char ch; should be int ch;.
Why does it return an int? Because the value it returns is either the character it just read (as an unsigned char converted to int) or the special value EOF (typically -1) to indicate either an input error or an end-of-file condition.
Don't use the feof() function to detect the end of input. It returns true only after you've run out of input. Your last call to getc() is returning EOF, which when stored into a char object is converted to (char)-1, which is typically '\377'.
Another problem is that feof() will never return a true value if there was an input error; in that case, ferror() will return true. Use feof() and/or ferror() after getc() returns EOF, to tell why it returned EOF.
To read from a file until you reach the end of it:
int ch;
while ((ch = getc(filelist)) != EOF) {
/* ch contains the last character read; do what you like with it */
}
Suggested reading: Section 12 of the comp.lang.c FAQ.

The \377 is an octal escape sequence, decimal 255, all bits set. It comes from converting EOF - which usually has the value -1 - to a char, due to
while (!feof(filelist)) {
feof(filelist) only becoming true after you have tried to read past the file.
So at the end of the file, you enter the loop once more, and the getc() returns EOF.

Related

difference between getc and fscanf

why does the following code work fine:
#include<stdio.h>
int main()
{
FILE *fp=fopen("input.txt","r+");
char c;
while((c=getc(fp))!=EOF)
{
printf("%c",c);
}
fclose(fp);
return 0;
}
but this code gives an error 'segmentation fault, core dumped':
#include<stdio.h>
int main()
{
FILE *fp=fopen("input.txt","r+");
char c;
while((c=fscanf(fp,"%c",&c))!=EOF)
{
printf("%c",c);
}
fclose(fp);
return 0;
}
input.txt contains a space separated list of characters like: a b c d e f
This will not work the way you expect:
while((c=fscanf(fp,"%c",&c))!=EOF)
getc() returns the character read, which can be EOF, but fscanf() returns the number of input items assigned, or EOF if there was a failure before any conversion took place.
You can't assign this return value to c, because the return value is not the character read (which you then try to print later).
You should try this instead:
while(fscanf(fp,"%c",&c) == 1)
Or:
while(fscanf(fp,"%c",&c) != EOF)
Which is equivalent to saying "As long as there is a character to read..."
Also, in the first case (the code where you use getc()), c should be int - you can have an infinite loop if the target platform uses unsigned chars, because c will always be converted to a positive int (again, only in platforms with unsigned chars), and thus will never be equal to EOF. If you check the manpages for getc() and putc() (and other functions that deal with a character), you will see that they receive int, not char.

Extra EOF character

I have a program that reads a file into a buffer structure. The problem I'm having is that when I look at the output of the file, there's an extra EOF character at the end. Ill post the related functions:(NOTE: I removed parameter checks and only posted code in the function related to the issue)
b_load
int b_load(FILE * const fi, Buffer * const pBD){
unsigned char character; /*Variable to hold read character from file*/
Buffer * tempBuffer; /*Temparary Bufer * to prevent descruction of main Buffer*/
short num_chars = 0; /*Counter of the amount of characters read into the buffer*/
/*Assigns main Buffer to tempBuffer*/
tempBuffer = pBD;
/*Infinite loop that breaks after EOF is read*/
while(1){
/*calls fgetc() and returns the char into the character variable*/
character = (unsigned char)fgetc(fi);
if(!feof(fi)){
tempBuffer = b_addc(pBD,character);
if(tempBuffer == NULL)
return LOAD_FAIL;
++num_chars;
}else{
break;
}
}
return num_chars;
}
b_print
int b_print(Buffer * const pBD){
int num_chars = 0;
if(pBD->addc_offset == 0)
printf("The buffer is empty\n");
/*Sets getc_offset to 0*/
b_set_getc_offset(pBD, 0);
pBD->eob=0;
/*b_eob returns the structures eob field*/
while (!b_eob(pBD)){
printf("%c",b_getc(pBD));
++num_chars;
}
printf("\n");
return num_chars;
}
b_getc
char b_getc(Buffer * const pBD){
if(pBD->getc_offset == pBD->addc_offset){
pBD->eob = 1;
return R_FAIL_1;
}
pBD->eob = 0;
return pBD->ca_head[(pBD->getc_offset)++];
}
at the end I end up with:
"a catÿ"
(the y is the EOF character)
It prints an EOF character but is never added to the buffer. When the driver code adds an EOF character to the end of the buffer, 2 appear. Any idea what is causing this? I might be using feof() wrong so that may be it, but it is required in the code
There is no "EOF character". EOF is a value returned by getchar() and related functions to indicate that they have no more input to read. It's a macro that expands to a negative integer constant expression, typically (-1).
(For Windows text files, an end-of-file condition may be triggered by a Control-Z character in a file. If you read such a file in text mode, you won't see that character; it will just act like it reached the end of the file at that point.)
Don't use the feof() function to detect that there's no more input to read. Instead, look at the value returned by whatever input function you're using. Different input functions use different ways to indicate that they weren't able to read anything; read the documentation for whichever one you're using. For example, fgets() returns a null pointer, getchar() returns EOF, and scanf() returns the number of items it was able to read.
getchar(), for example, returns either the character it just read (treated as an unsigned char and converted to int) or the value EOF to indicate that it wasn't able to read anything. The negative value of EOF is chosen specifically to avoid colliding with any valid value of type unsigned char. Which means you need to store the value returned by getchar() in an int object; if you store it in a char or unsigned char instead, you can lose information, and an actual character with the value 0xff can be mistaken for EOF.
The feof() function returns the value of the end-of-file indicator for the file you're reading from. That indicator becomes true after you've tried and failed to read from the file. And if you ran out of input because of an error, rather than because of an end-of-file condition, feof() will never become true.
You can use feof() and/or ferror() to determine why there was no more input to be read, but only after you've detected it by other means.
Recommended reading: Section 12 of the comp.lang.c FAQ, which covers stdio. (And the rest of it.)
UPDATE :
I haven't seen enough of your code to understand what you're doing with the Buffer objects. Your input look actually looks (almost) correct, though it's written in a clumsy way.
The usual idiom for reading characters from a file is:
int c; /* `int`, NOT `char` or `unsigned char` */
while ((c = fgetc(fi)) != EOF) {
/* process character in `c` */
}
But your approach, which I might rearrange like this:
while (1) {
c = fgetc(fi);
if (feof(fi) || ferror(fi)) {
/* no more input */
break;
}
/* process character in c */
}
should actually work. Note that I've added a check for ferror(f1). Could it be that you have an error on input (which you're not detecting)? That would cause c to contain EOF, or the value of EOF converted to the type of c. That's doubtful, though, since it would probably give you an infinite loop.
Suggested approach: Using either an interactive debugger or added printf calls, show the value of character every time through the loop. If your input loop is working correctly, then build a stripped-down version of your program with a hard-wired sequence of calls to b_addc(), and see if you can reproduce the problem that way.
There you go ...
int b_load(FILE * const fi, Buffer * const pBD){
int character; /*Variable to hold read character from file*/
Buffer * tempBuffer; /*Temparary Bufer * to prevent descruction of main Buffer*/
short num_chars ; /*Counter of the amount of characters read into the buffer*/
/*Infinite loop that breaks WHEN EOF is read*/
while(num_chars = 0; 1; num_chars++ ) {
character = fgetc(fi);
if (character == EOF || feof(fi)) break; // since you insist on the silly feof() ...
tempBuffer = b_addc(pBD, (unsigned char) character);
if(tempBuffer == NULL) return LOAD_FAIL;
}
}
return num_chars;
}

While (( c = getc(file)) != EOF) loop won't stop executing

I can't figure out why my while loop won't work. The code works fine without it... The purpose of the code is to find a secret message in a bin file. So I got the code to find the letters, but now when I try to get it to loop until the end of the file, it doesn't work. I'm new at this. What am I doing wrong?
main(){
FILE* message;
int i, start;
long int size;
char keep[1];
message = fopen("c:\\myFiles\\Message.dat", "rb");
if(message == NULL){
printf("There was a problem reading the file. \n");
exit(-1);
}
//the first 4 bytes contain an int that tells how many subsequent bytes you can throw away
fread(&start, sizeof(int), 1, message);
printf("%i \n", start); //#of first 4 bytes was 280
fseek(message, start, SEEK_CUR); //skip 280 bytes
keep[0] = fgetc(message); //get next character, keep it
printf("%c", keep[0]); //print character
while( (keep[0] = getc(message)) != EOF) {
fread(&start, sizeof(int), 1, message);
fseek(message, start, SEEK_CUR);
keep[0] = fgetc(message);
printf("%c", keep[0]);
}
fclose(message);
system("pause");
}
EDIT:
After looking at my code in the debugger, it looks like having "getc" in the while loop threw everything off. I fixed it by creating a new char called letter, and then replacing my code with this:
fread(&start, sizeof(int), 1, message);
fseek(message, start, SEEK_CUR);
while( (letter = getc(message)) != EOF) {
printf("%c", letter);
fread(&start, sizeof(int), 1, message);
fseek(message, start, SEEK_CUR);
}
It works like a charm now. Any more suggestions are certainly welcome. Thanks everyone.
The return value from getc() and its relatives is an int, not a char.
If you assign the result of getc() to a char, one of two things happens when it returns EOF:
If plain char is unsigned, then EOF is converted to 0xFF, and 0xFF != EOF, so the loop never terminates.
If plain char is signed, then EOF is equivalent to a valid character (in the 8859-1 code set, that's ÿ, y-umlaut, U+00FF, LATIN SMALL LETTER Y WITH DIAERESIS), and your loop may terminate early.
Given the problem you face, we can tentatively guess you have plain char as an unsigned type.
The reason that getc() et al return an int is that they have to return every possible value that can fit in a char and also a distinct value, EOF. In the C standard, it says:
ISO/IEC 9899:2011 §7.21.7.1 The fgetc() function
int fgetc(FILE *stream);
If the end-of-file indicator for the input stream pointed to by stream is not set and a
next character is present, the fgetc function obtains that character as an unsigned char converted to an int ...
If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-
file indicator for the stream is set and the fgetc function returns EOF.
Similar wording applies to the getc() function and the getchar() function: they are defined to behave like the fgetc() function except that if getc() is implemented as a macro, it may take liberties with the file stream argument that are not normally granted to standard macros — specifically, the stream argument expression may be evaluated more than once, so calling getc() with side-effects (getc(fp++)) is very silly (but change to fgetc() and it would be safe, but still eccentric).
In your loop, you could use:
int c;
while ((c = getc(message)) != EOF) {
keep[0] = c;
This preserves the assignment to keep[0]; I'm not sure you truly need it.
You should be checking the other calls to fgets(), getc(), fread() to make sure you are getting what you expect as input. Especially on input, you cannot really afford to skip those checks. Sooner, rather than later, something will go wrong and if you aren't religiously checking the return statuses, your code is likely to crash, or simply 'go wrong'.
There are 256 different char values that might be returned by getc() and stored in a char variable like keep[0] (yes, I'm oversummarising wildly). To detect end-of-file reliably, EOF has to have a value different from all of them. That's why getc() returns int rather than char: because a 257th distinct value for EOF wouldn't fit into a char.
Thus you need to store the value returned by getc() in an int at least until you check it against EOF:
int tmpc;
while( (tmpc = getc(message)) != EOF) {
keep[0] = tmpc;
...

File handling in C: can't fathom the output

I compiled this (gcc compiler) :
#include< stdio.h>
main() {
unsigned char ch;
FILE *fp;
fp=fopen("trial","r");
while((ch=getc(fp))!=EOF)
printf("%c",ch);
fclose(fp);
}
It gives the follwing:
Warning: comparison is always true due to limited range of the data type
On executing, an endless stream of characters is printed on terminal.
(Assuming I created a file named "trial" before compiling the program and wrote some text in the file.)
Kindly explain the warning.....
Because EOF is -1 and your ch is unsigned char which means ch will never become -1.
Instead use int ch;
The EOF value in C is an int while ch here is a char. The char type is smaller than int and hence can represent less values than int can. EOF is one of the values which char simply can't ever represent and hence ch will never be equal to EOF.
In this scenario getc actually returns an int so it can represent EOF. But you are immediately shrinking it to a char and losing that extra information.
Here's a way to properly write this.
int cur;
FILE *fp;
fp=fopen("trial","r");
while((cur = getc(fp))!=EOF) {
unsigned char ch = cur;
printf("%c",ch);
}
fclose(fp);
getc() returns an int. You're truncating (and changing the signedness) it to unsigned char with that assignment, so it will never match EOF. Just change the type of ch to int and you'll be fine.
getc returns an integer for good reason. The EOF indicator is outside the range of a normal char, because otherwise you could confuse a legitimate character with the EOF indicator. However, you're assigning the results to a character which confines the answer to fall within the limits of a char value. In short, you're never going to know when the end of the file has been reached this way. Make "ch" an int type or assign result from call to getc to an unsigned char type after you compare it with EOF.

how to stop reading from file in C

I am just trying to read each character of the file and print it out but when the file finishes reading, but I am getting a bunch of ? after it finishes reading. How do I fix it?
#include <stdio.h>
int main(void){
FILE *fr; /* declare the file pointer */
fr = fopen ("some.txt", "r"); /* open the file for reading */
/* elapsed.dta is the name of the file */
/* "rt" means open the file for reading text */
char c;
while((c = getc(fr)) != NULL)
{
printf("%c", c);
}
fclose(fr); /* close the file prior to exiting the routine */
/*of main*/
return 0;
}
In spite of its name, getc returns an int, not a char, so that it can represent all of the possible char values and, in addition, EOF (end of file). If getc returned a char, there would be no way to indicate the end of file without using one of the values that could possibly be in the file.
So, to fix your code, you must first change the declaration char c; to int c; so that it can hold the EOF marker when it is returned. Then, you must also change the while loop condition to check for EOF instead of NULL.
You could also call feof(fr) to test end of file separately from reading the character. If you did that, you could leave c as a char, but you would have to call feof() after you read the character but before you printed it out, and use a break to get out of the loop.
If unsuccessful, fgetc() returns EOF.
int c;
while ((c = getc(fr)) != EOF)
{
printf("%c", c);
}
Change this
char c;
while((c = getc(fr)) != NULL)
{
printf("%c", c);
}
to
char c;
int charAsInt;
while((charAsInt = getc(fr)) != EOF)
{
c = (char) charAsInt;
printf("%c", c);
}
In other words: You need to compare against EOF, not NULL. You also need to use an int variable to receive the return value from fgetc. If you use a char, the comparison with EOF may fail, and you'll be back where you started.
fgetc() returns EOF on end-of-file, not NULL.
Replace "NULL" with "EOF".
Others have already addressed the issue you're having, but rather than using printf("%c", c); it is probably much more efficient to use putchar(c);. There is quite a bit of overhead involved when you ask printf to print just one character.
getc returns an int.
change char c, to int c.
also getc returns EOF,
change your test against NULL to a test against EOF

Resources