I'm trying to print the chars (with fgetc) in a file one by a one with a while loop.
I'm using the latest Atom editor to write the code, and I compile with the GPP Compiler, by pressing F5 and the output is displayed in the xterm terminal.
int main(int argc, char const *argv[])
{
FILE* file = NULL;
file = fopen("text.txt", "r+");
int letter = 0;
if (file != NULL)
{
while(letter != EOF)
{
letter = fgetc(file);
printf("%c", letter);
}
I expected the output to be the text in my file, which it is, but at the end there's a question mark symbol.
What I understood after doing some research is that my fgetc function reads the EOF like a normal character and prints it, resulting in a question mark symbol at the end.
Thanks for your help !
... ending with a “?” symbol
doing
while(letter != EOF)
{
letter = fgetc(file);
printf("%c", letter);
}
you print letter before to check if it is EOF, so you (try to) print EOF which is not a character, producing the unexpected output
Example of a valid code :
while ((letter = fgetc(file)) != EOF)
putchar(letter); /* or printf("%c", letter); if you prefer */
I have been having the same issue and I found out that the return type for fgetc is an integer and it may be returning -1.
Related
Given the code reading from the standard input
int main() {
int c;
while ((c = getchar()) != EOF) {
fprintf(stdout, "%c", c);
}
}
This code is fine for reading all contents from the stdin containing multiple lines. But it will add a new line at the end of file. How can I modify the above code so that I can prevent from adding an extra new line \n in the last line of stdin? The example of stdin is given below.
hello world!!!
how is going today?
this is the last line in stdin
As #NateEldredge said in a friendly way, removing the trailing '\n' from the last line is dumb. By convention, on UNIX-like systems, every line in a textfile must be terminated with '\n'. But if you actually want to remove the last newline, maybe to be compatible with some lesser OS, you have to delay printing of characters until you know if the next read returned EOF, or not:
#include <stdio.h>
int main(void)
{
int c = getchar();
int peek_c;
if (c != EOF)
{
/* Print out everything except the last char */
while ((peek_c = getchar()) != EOF)
{
fprintf(stdout, "%c", c);
c = peek_c;
}
/* If the last char was not '\n', we print it
(We only want to strip the last char if it is a newline) */
if (c != '\n')
fprintf(stdout, "%c", c);
}
}
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;
}
I want to read a text from file which contains also '\n' character
This is my function
void readFromFile (FILE * fid, unsigned char * mesage) {
unsigned char c;
int mesage_length = 0;
while((c = fgetc(fid)) != EOF) {
mesage[mesage_length] = c;
mesage_length++;
}
}
I have completely absolute no idea why when it gets to the '\n' my program crashes, it enters in an infinite loop and the mesage_length grows up to 13992 or something, but i read only 13 characters like : "Why not working?\n"
How can i read the whole text until EOF and put it into a string (char *) ?
If i put the condition inside the while if(c == '\n') break; it works fine.. but would read until the first \n
I want program count lines in text file by function. It used to work ,but it always return 0 now.
What am I doing wrong?
#include <stdio.h>
int couLineF(FILE* fp){ //count lines in file
int count = 0,ch;
while((ch = fgetc(fp)) != EOF){
if(ch == (int)"\n" ) count++;
}
rewind(fp);
return count;
}
int main(){
FILE *fp = fopen("book.txt","r");
int lines;
if(fp){
lines = couLineF(fp);
printf("number of lines is : %d",lines);
}
return 0;
}
Another question
Are there any other ways to get number of lines in text file?
Your problem is here:
if(ch == (int)"\n" )
You are casting the address of "\n", a string literal, into an int and comparing it with ch. This doesn't make any sense.
Replace it with
if(ch == '\n' )
to fix it. This checks if ch is a newline character.(Use single quotes(') for denoting a character and double quotes(") for a string)
Other problems are:
Not closing the file using fclose if fopen was successful.
Your program won't count the last line if it doesn't end with \n.
There is absolutely no reason to use rewind(fp) as you never use the FILE pointer again.
I'm trying to read the first character of a file and whenever it's equal to '(' I should skip that line else get the first character from that line. I'm under a mac and I can make use of fgetln.
FILE *file = fopen("test.txt", "r");
char c;
while(fscanf(file, "%s", &c) != EOF) {
if (c != '(')
printf("%c", c);
}
That's my current code. I don't know how to skip lines, although I've tried to get the whole line and checked only the first char solving the skip problem. However this is not working I'm getting strange characters in my console instead of the ones inside test.txt. How should I do that?
The problem with using %s format specifier of fscanf is that is splits on spaces, not only on end-of-line characters. Moreover, reading it in a single-character buffer will nearly always produce undefined behavior.
There are several ways to solve this problem, using different APIs:
You could replace %s with %200[^\n], and passing a 201-character buffer instead of c,
Using fgets with a properly-sized buffer, and picking the initial character, or
Using a character-based API, and setting a "take next" flag each time that you see a '\n' character:
Here is how you can implement the third approach:
bool takeNext = true;
int ch;
while ((ch = fgetc(file)) != EOF) {
if (takeNext && ch != '(') {
printf("%c", ch);
}
takeNext = (ch == '\n');
}
Here is a slightly longer character-based approach, which conditions on whether the first character in a line is ( or not.
If it is (, then we consume everything up to and including the next newline without outputting.
If it not, then we do the same thing but we output the characters as we read them.
#include <stdio.h>
int main(){
FILE *file = fopen("test.txt", "r");
int c;
while((c = getc(file)) != -1) {
if (c == '(') {
// Skip until the next newline
do {
c = getc(file);
} while (c != -1 && c != '\n');
continue;
}
else {
putchar(c);
do {
c = getc(file);
putchar(c);
} while (c != -1 && c != '\n');
}
}
fclose(file);
}
Change c to string because fscanf reads string. See if the 1st character of c matches with (.
If it does not then print the line else skip the line.
FILE *file = fopen("test.txt", "r");
char c[100];
while(fscanf(file, "%s", c)) {
if (c[0] != '(')
printf("%s", c);
}
Use fgets to read whole lines. It is also safer than fscanf as it limits the reading to the buffer size.
To check if the first char is '(' you can refer to it directly:
if (buf[0]=='(')
or
if (*buf=='(')