Fgets() keeps skipping first character
Asked Answered
W

4

6

This is part of a larger program to emulate the cat command in unix. Right now trying to take input and send it to stdout:

char in[1000];
int c = 0; 
while ((c = getchar()) != EOF)
 {
   fgets(in,1000,stdin);
   fputs(in, stdout);
 }

This sends output to stdout, but in every case it skips the first letter. For instance, if I type the word Computer

I get back:

omputer
Wershba answered 28/4, 2015 at 11:52 Comment(3)
That is because the first character gets stored in getchar()Felicific
You want while (fgets(in,1000,stdin)) and don't forget to remove the fgets in the body of the while loop.Evans
Do instead while (fgets(...) != NULL)Normalcy
R
8

Your problem is all about eating.

c = getchar()

This line, as many I/O operations in C consume your buffer. Meaning that when you have say 0123456789 after your getchar() you're left with 123456789 in your buffer.

What you want to do is use the same functions to control the input and to store it, so something like getting rid of the getchar() should do the trick :

while (fgets(in,1000,stdin) != NULL)
 {
   fputs(in, stdout);
 }

And there you have it !

Roundshouldered answered 28/4, 2015 at 11:59 Comment(0)
P
6

There is an ungetc function that allows to return character to a stream. It is not standard C function, but implemented in Unix-like systems and by Visual Studio CRT:

while ((c = getchar()) != EOF)
{
    ungetc(c, stdin);
    fgets(in, 1000, stdin);
    fputs(in, stdout);
}

But as other answerers note, cleaner way to do that is to use fgets() directly:

while (fgets(in, sizeof(in), stdin) != NULL)

The third option is to save first character directly to a string:

while ((c = getchar()) != EOF)
{
    in[0] = c;
    fgets(in + 1, 999, stdin);
    fputs(in, stdout);
}
Pentheus answered 28/4, 2015 at 12:1 Comment(1)
I did not now about ungetc(), +1 for thatRoundshouldered
T
4

It's not skipping anything you are consuming it with getchar().

Upon successful completion, fgets() returns the string in. If the stream is at end-of-file, the end-of-file indicator for the stream shall be set and fgets() shall return a NULL pointer.

Change this

while ((c = getchar()) != EOF)

to

while (fgets(in, sizeof(in), stdin) != NULL)  
Trepang answered 28/4, 2015 at 11:57 Comment(0)
S
0

This will work too:

char in[1000];
while ((in[0] = (char)getchar()) != EOF)
 {
   fgets(in+1,999,stdin);
   fputs(in, stdout);
 }
Swig answered 28/4, 2015 at 12:12 Comment(3)
If getchar() returns 255, then with signed char, in[0] would have the value of -1. This may match EOF even though end-of-file did not occur.Nonintervention
How do you make getchar() return 255?Swig
Many ways. Example: 1) FILE * f= fopen("test.txt", "w"); fputc(255, f); fclose(f): Now pipe that file into you program "a.bin < text.txt" 2) On many PC keyboard using standard IO: <Alt> key down, <number pad 2> <number pad 5> <number pad 5> <Alt> key up. 3) getchar(), by spec, returns an int in the range of unsigned char or EOF. It does not specify it will not return 255 - so code should be prepared to handle all 257 different values.Nonintervention

© 2022 - 2024 — McMap. All rights reserved.