Reading text file from stdin stops at last line - c

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?

There are multiple problems in your code:
You do not include <stdio.h>, nor <ctype.h>, or at least you did not post the whole source code.
You use feof() to check for end of file. This is almost never the right method, as underscored in Why is “while ( !feof (file) )” always wrong?
You read the byte from the stream in a 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;
}

Related

C code doesn't print whole paragraph with newlines

This is my C code:
#include <stdio.h>
int main()
{
int c = getchar();
while (c != EOF) {
if (c != '\n')
putchar(c);
else putchar(32);
c = getchar();
}
return 0;
}
I want to make a program that prints out a paragraph with newlines, by replacing the \n character with spaces. The problem is, it only prints out the last line, when I use the code provided above.
For, example, for the text:
This is
my
text
the result printed is text.
The paragraph is properly printed when I remove the if(), else conditions, and only leave the putchar(), without trying to replace anything.
What's the problem?
Your input file has CRLF newlines. You need to ignore the CR characters when you're replacing LF with space. Otherwise, printing the CR characters will go back to the beginning of the line and overwrite what was already printed.
#include <stdio.h>
int main()
{
int c;
while ((c = getchar()) != EOF) {
if (c == '\n') {
// replace newline with space
putchar(' ');
} else if (c == '\r') {
// ignore CR
} else {
putchar(c);
}
}
return 0;
}

Avoiding adding a new line at the end of file

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);
}
}

getchar() stuck in a loop never reaching the EOF

#include <stdio.h>
int main() {
int c;
while(getchar() != EOF) {
if (getchar() == ' ') {
c++;
}
printf("%i", c);
}
}
I realized that typing in a sentence like the one you're reading right
I\nrealized\nthat\ntyping\nin\n\a\n ...
i believe that's how it's being read, getchar() does not reach the EOF to make the condition in the while parentheses false..
my goal here is to make a program that takes in input from me..
reads it
if there are any spaces
it counts on a counter
when EOF is reached
the condition to keep reading it becomes false
the counter value gets printed out on the screen
to show me how many spaces i had in my entire input..
is it impossible? is that why people just use scanf() ?
this is the output i get when trying something
user#user:/c# ./a.out
hello stackoverflow this does not do what i want it to
001111111222223344445666677
You need to put the result of getchar() into a variable:
int ch;
while ((ch = getchar()) != EOF)
You shouldn't call getchar() a second time to check if it's a space, since that will read a second character so you'll be testing every other character, just compare the variable:
if (ch == ' ')
And if you want to see the total number of spaces, put the printf() at the end of the loop, not inside it.
So the whole thing should look like:
#include <stdio.h>
int main() {
int counter=0;
int ch;
while((ch = getchar()) != EOF) {
if (ch == ' ') {
counter++;
}
}
printf("%i\n", counter);
}
To send EOF from the terminal, type Control-d on Unix, Control-z on Windows.

How Can I Get the First Character of Standard Input and Throw Out the Rest?

I know I can get the first character of a line of standard input by using getchar(), but I only want the first character of each line. Is there a function I can use to get rid of the rest of the string entered into standard input (if it is more than one character)? if not, what methodology should I consider using to get rid of the rest of the standard input line?
char buf[100];
while(fgets(buf,sizeof(buf),stdin) != NULL)
{
if(strlen(buf)>0)
buf[1] = '\0';
printf("%s",buf);
}
Read the whole line using fgets() and just nul terminate it after the first character.
#include <stdio.h>
int main(void)
{
int ch;
size_t len;
for (len = 0; 1; ) {
ch = getc(stdin);
if (ch == EOF) break;
if (!len++) putc(ch, stdout); /* the first character on a line */
if (ch == '\n') len = 0; /* the line has ended */
}
return 0;
}
Please note that the first character on a line can actually be a '\n' !!!
// Get the character you need
char c = getchar();
// Skip the rest
int a;
while((a = getchar()) != '\n' && a != EOF);
If you know how many lines you'll have, you can put it in a loop.

How to exit a while-loop?

#include <stdio.h>
main(void) {
char ch;
while (1) {
if ((ch = getchar()) != EOF)
{
break;
}
putchar(ch);
}
return 0;
}
How do I escape from this while? I had tried with EOF but it didn't work.
I think you mean:
int ch;
Because EOF won't fit in a char.
Also:
if ((ch=getchar()) == EOF)
break;
Your logic is backwards.
This:
char ch;
is wrong, EOF doesn't fit in a char. The type of getchar()'s return value is int so this code should be:
int ch;
Also, as pointed out, your logic is backwards. It loop while ch is not EOF, so you can just put it in the while:
while((ch = getchar()) != EOF)
check with the while. It's more simple
while((ch=getchar())!= EOF) {
putchar(ch);
}
The EOF is used to indicate the end of a file. If you are reading character from stdin, You can stop this while loop by entering:
EOF = CTRL + D (for Linux)
EOF = CTRL + Z (for Windows)
You can make your check also with Escape chracter or \n charcter
Example
while((ch=getchar()) != 0x1b) { // 0x1b is the ascii of ESC
putchar(ch);
}

Resources