fgetc is always returning value 1 - c

there is the following function:
void readAndPrint(FILE * f) {
int c;
while(c = fgetc(f) != EOF) {
printf("%d", c);
}
}
In the main() body I used the following code to use the above function:
FILE * pFile;
pFile=fopen ("myfile.txt","r");
readAndPrint(pFile)
;
Whatever I put into myfile.txt, the program prints out ones.
For example, for abc, 111 is printed out.
I know that c in the function should be declared int to properly compare it to EOF. Also, I expected an int code from the ASCII set for each char in the text file to be printed out (97 for a, ...). I cannot figure out why it prints out 'ones'... Does you know the reason why? Thank you in advance.

(c = fgetc(f) != EOF) - Here first fgetc(f) != EOF this condition is happening and the result 1 or 0 is assigned to c. Always a condition check returns TRUE(1) or FALSE (0).
Do while((c = fgetc(f)) != EOF)

Related

getc(fp) : strange character : ÿ ( at the very bottom )

a new empty file:
touch /file.txt
read. print.
fp = fopen("/file.txt", "r");
char text[1000];
int i=0;
while(!feof(fp)){
text[i++] = getc(fp);
}
text[i]='\0';
printf("%s\n", text);
result:
ÿ
EXTRA INFO : if file.txt had many lines.. it would have appended that strange character at the very bottom of it. so perhaps it is not something that happens on every "while loop".
If you're using ISO 8859-15 or 8859-1 code set, the ÿ (LATIN SMALL LETTER Y WITH DIAERESIS, U+00FF in Unicode) has code 25510 or 0xFF. When you store EOF in the array, it gets converted to ÿ.
Don't store EOF in a char. And remember that getchar() returns an int, not a char. It has to be able to return every value that can be stored in an unsigned char, plus EOF which is negative (usually but not necessarily -1).
And, as noted in the comments, while (!feof(file)) is always wrong. This is just another reason why.
This code is fixed, more or less. It really should report an error if it fails to open the file. Note that it also ensures you don't overflow the buffer.
FILE *fp = fopen("/file.txt", "r");
if (fp != 0)
{
char text[1000];
int i=0;
int c;
while ((c = getc(fp)) != EOF && i < sizeof(text)-1)
text[i++] = c;
text[i]='\0';
printf("%s\n", text);
fclose(fp);
}
See also while ((c = getc(file)) != EOF) loop won't stop executing.
The ÿ is the byte 255 in your codepage, which is the constant EOF coerced into a char. Instead of using feof, you must store the return value of getc into an int, then compare it against EOF, here's an easy-to-read example (notice that you'd have to have bounds-checking too):
while (1) {
int c = getc(fp);
if (c == EOF) {
break;
}
text[i++] = c;
}

issue fgetc() c using while loop

I got a big problem using fgetc() and i can't figure it out... I try to parse a text file, everything compile but at the execution I got an infinite loop or a segfault (Code::blocks), my text file is like that: {"USD_EUR": "0.8631364", "EUR_USD": "1.3964719"} with 16 rates change. I try to put all my float in rate[16]...
FILE* file = NULL;
file = fopen(myFile, "r+");
int value,i;
float rate[16];
char* str = "";
if (file != NULL)
{
do
{
value = fgetc(file);
printf("%c \n",value);
while(value > 48 && value < 57)
{
value = fgetc(file);
strcat(str, value);
//printf("%s \n", str);
}
rate[i] = atof(str);
i++;
str = "";
}while(value != 125); // 125 = }
while(value =! EOF); should be while(value != EOF);
It's a big difference. First case is an assignment to the variable value, second case looks if value is not equal to EOF.
EOF is a macro and usually have the value -1, that means that !EOF becomes 0. Since you have a do{} while() it will run once but not more since condition is false.
while(value =! EOF) is not same as while(value != EOF)
What you need is the latter while(value != EOF)
in the while loop you are assigning the value to the variable value.
`while(value =! EOF);`
The value of EOF is -1.(i.e) End of file. if it is !-1, then it will take as 0.
As it is a do while only once the loop will be executed, next time the condition will be false. So it gets only one character.
You can use
`while(value != EOF);`
which means not equal to EOF. Then the condition will be true and the loop will be executed till the condition becomes false.
Declaration of value is incorrect and make that correct.
int value;
While ( value != EOF ) is comparing the value to EOF. Here EOF is a macro having the
value as -1. Comparing the value with that. You can see that using cc -E while compiling.
(value =!EOF) means that value =! (-1) So !(-1) comes zero. That will assign to the variable value. So in condition zero is false. So it come out from the loop. And you can check the value of variable value by printing that variable.
The following code does the job of reading/echoing a input file
char by char.
#include <stdio.h>
#include <stdlib.h>
char *theFile = "input.txt";
int main()
{
FILE* file = NULL;
int value;
if( NULL == ( file = fopen(theFile, "r") ) )
{ // then fopen failed
perror( "fopen failed" );
exit(EXIT_FAILURE );
}
// implied else, fopen successful
while( EOF != (value = fgetc(file) ) )
{
printf("%c \n",value);
} // end while
return(0);
} // end function: main

Write a program that reads input up to # and reports the number of times that the sequence ei occurs

Write a program that reads input up to # and reports the number of times that the sequence ei occurs
I have this question and I found a code here for this but I'm unable to figure out what the int c1 part does. Here's the code :
#include <stdio.h>
int main(void) {
int c;
int ei_count = 0;
while ((c = getchar())!= '#') {
if (c == 'e') {
int c1 = getchar();
if (c1 == 'i')
ei_count++;
}
}
printf("ei appeared %d times\n", ei_count);
return(0);
}
My question is, how does the if condition work? Can someone please explain ?
I'm new at C
The c1-part is a broken try at scanning the second part of ei, they could have reused c without introducing more errors.
Better alternative:
#include <stdio.h>
int main(void) {
int c, last = 0, ei_count = 0;
while ((c = getchar()) >= 0 && c != '#') {
ei_count += last && c == 'i';
last = c == 'e';
}
printf("ei appeared %d times\n", ei_count);
}
Corrected errors:
neither ei nor # recognized after e.
infinite loop on EOF / input error.
Random facts:
main has an implicit return 0; just before the closing brace.
getchar() returns an int, so it can return -1 on failure and an unsigned char converted to int on success. Always check for failure.
logical and comparison operators always return 0 or 1.
0 is logical false, all else is logical true.
return is not a function call: Use return 0; without parentheses.
That part you mentioned is a way to find a pattern like "ei". At the first moment the code try to find the 'e' character in a loop, and then, once it is found, the code checks if the next char is the letter 'i'. Case not, start again the loop to find another 'e' char.
This is not an good approach since there is no error verification during the getchar() operation and you can fall on a infinite loop.
Oversimplified, it's just a state machine.
Stepping through line-by-line:
while ((c = getchar())!= '#') {
Read input and assign it to the variable c. If that read in char is anything but #, execute the body of the while, otherwise jump over it.
if (c == 'e') {
If the read in character is an e, then we want to execute the internal block. If it's not, skip to the end of this block.
int c1 = getchar();
Read another character.
if (c1 == 'i') ei_count++;
If the new character is an i, then increment the counter of found items.
} close if (if e was found)
} close while.
It's worth pointing out there is a very clear flaw in the logic flow, however. Think about what happens if you have the input "eei".
In C, char and int data types are pretty much the same thing. In an assignment statement, the final result of the calculations are converted to the type of the variable being assigned to. Probably in this example, the author of this code assumed that the value returned by getchar() function which is of type int cannot be assigned to a char variable. You can use a char type for the c1 variable, since the getchar() function returns the ASCII code of the next character in the input, and the value is automatically converted to char during assingment. In the next if statement, you can easily compare the value of c1 with the character value i.
This code is a little bit buggy, for if you enter e# as an input, the program hangs. The reason is that c1 = getchar(); statement in the if block assigns '#' value to variable c1, and the comparison obviously fails, and at the next iteration of the while loop, getchar() returns a value after the '#' character in the input stream, which is a garbage value unless you entered more other characters after the '#' character.
Here's my code with a few fixes:
#include <stdio.h>
int main(void) {
char ch, next;
int ei_cnt = 0;
while((ch = getchar()) != '#') {
if(ch == 'e') {
next = getchar();
if(next == '#')
break;
if(next == 'i')
ei_cnt++;
}
}
printf("ei substring occured %d %s.\n", ei_cnt,
ei_cnt == 1 ? "time" : "times");
return 0;
}

getc(fp) causing trouble

Here is my code.
#include<stdlib.h>
#include<stdio.h>
int main(int argc,char** argv)
{
char a;
a=9;
FILE * fp;
fp=fopen(argv[1],"r");
while(a!= EOF)
{
a=fgetc(fp);
printf("\n%d",a);
}
}
The output to this is alright but at the end I am getting a weird character with -1 (since I am printing integer value.
How to stop it at EOF only?
Also what is this character?
Besides the methods in the other answers, you can also do like this:
while ((a = fgetc(fp)) != EOF)
{
printf("%d\n", a);
}
Now you have a few alternative solutions. :)
Edit: As R.. so kindly reminds us, you also have to change the type of a to int.
You are printing the EOF character (the -1) as you do not check if EOF was encountered immediately after fgetc(). Change the structure of the loop to:
int a; /* not char, as pointed out by R... */
for (;;)
{
a = fgetc(fp);
if (EOF == a) break;
printf("\n%d", a):
}
You need to make a have type int, as that type is the return type of fgetc(), and is needed to represent EOF correctly.
Why don't you stop the while with this condition:
do {...}while(a != EOF)
I suppose that a got EOF value AFTER read it.
So, you do the cycle an extra time

Understanding type casting in c

I'm following a book on c, and I come to some code that reads a file with 3 lines of text.
#include <stdio.h>
int main (int argc, const char * argv[]) {
FILE *fp;
int c;
fp = fopen( "../../My Data File", "r" );
if ( NULL == fp ) {
printf( "Error opening ../My Data File" );
} else {
while ( (c = fgetc( fp )) != EOF )
putchar ( c );
fclose( fp );
}
return 0;
}
I tried to modify it, to detect each line and print the current line number by making these modifications.
int line = 1;
while ( (c = fgetc( fp )) != EOF ){
if (c == '\n'){
printf(" LINE %d", line);
putchar( c );
line++;
}
else {
putchar ( c );
}
}
But it failed to print the line #, till I changed the type of the variable c to a char. Is there a way to check for a newline while still using c as an int?
What is the proper way to check for a newline?
Your code prints line numbers at the end of a line, right before printing the '\n', because of the way you have written the loop. Otherwise, your code should work.
If you want your code to print the line numbers at the beginning, you can do something like (untested):
int line_num_printed = 0; /* indicating if we printed a line number */
int line = 1;
while ((c = fgetc(fp)) != EOF) {
if (!line_num_printed) {
printf("LINE %d: ", line);
line_num_printed = 1;
}
putchar(c);
if (c == '\n'){
line++;
line_num_printed = 0;
}
}
If there is something else that "doesn't work", you should post complete code and tell us what doesn't work.
Edit: The proper way to check a character for a newline is to test against '\n'. If the character came from a file, you should also make sure you open the file in text mode, i.e., without a b in the second argument to fopen().
Also, you want c to be of type int, not char. This is because in C, EOF is a small negative number, and if char is unsigned, comparing it against a negative number convert the value of EOF to a positive value (equal to EOF + UCHAR_MAX + 1 most likely). Therefore, you should not change c to char type. If you do, the comparison c != EOF might be false even when fgetc() returns EOF.
Usually the integer code for a new line ('\n') is 13. So you could do ( if (c == 13) ), but also note that windows files use 2 characters to define a new line '\r' and '\n'. The integer character for '\r' is 10. But basically yes you can keep 'c' as an int and just compare against 13.

Resources