Reputation: 635
I wrote a short program to test reading text files from stdin
:
int main(){
char c;
while(!feof(stdin)){
c = getchar(); //on last iteration, this returns '\n'
if(!isspace(c)) //so this is false
putchar(c);
//remove spaces
while (!feof(stdin) && isspace(c)){ //and this is true
c = getchar(); // <-- stops here after last \n
if(!isspace(c)){
ungetc(c, stdin);
putchar('\n');
}
}
}
return 0;
}
I then pass it a small text file:
jimmy 8
phil 6
joey 7
with the last line (joey 7
) terminated with a \n
character.
My problem is, after it reads and prints the last line, then loops back to check for more input, there are no more characters to read and it just stops at the line noted in the code block.
Question: The only way for feof()
to return true is after a failed read as noted here: Detecting EOF in C. Why isn't the final call to getchar
triggering EOF and how can I better handle this event?
Upvotes: 0
Views: 997
Reputation: 144715
There are multiple problems in your code:
<stdio.h>
, nor <ctype.h>
, or at least you did not post the whole source code.feof()
to check for end of file. This is almost never the right method, as underscored in Why is “while ( !feof (file) )” always wrong? char
variable. This prevents proper testing for EOF
and also causes undefined behavior for isspace(c)
. Change the type to int
.Here is an improved version:
#include <stdio.h>
int main(void) {
int c;
while ((c = getchar()) != EOF) {
if (!isspace(c)) {
putchar(c);
} else {
//remove spaces
while ((c = getchar()) != EOF && isspace(c)) {
continue; // just ignore extra spaces
}
putchar('\n');
if (c == EOF)
break;
ungetc(c, stdin);
}
}
return 0;
}
While your method with ungetc()
is functionally correct, it would be better to use an auxiliary variable this way:
#include <stdio.h>
#include <ctype.h>
int main(void) {
int c, last;
for (last = '\n'; ((c = getchar()) != EOF; last = c) {
if (!isspace(c)) {
putchar(c);
} else
if (!isspace(last))
putchar('\n');
}
}
return 0;
}
Upvotes: 2