Joseph
Joseph

Reputation: 3

Reading from stdin and storing \n and whitespace

I've been trying to use scanf to get input from stdin but it truncates the string after seeing whitespace or after hitting return.

What I'm trying to get is a way to read keyboard input that stores in the buffer linebreaks as well as whitespace. And ending when ctrl-D is pressed.

Should I try using fgets? I figured that wouldn't be optimal either since fgets returns after reading in a \n

Upvotes: 0

Views: 959

Answers (4)

hyde
hyde

Reputation: 62777

There is no ready-made function to read everyting from stdin, but creating your own is fortunately easy. Untested code snippet, with some explanation in comments, which can read arbitrarily large amount of chars from stdin:

size_t size = 0; // how many chars have actually been read
size_t reserved = 10; // how much space is allocated
char *buf = malloc(reserved);
int ch;

if (buf == NULL) exit(1); // out of memory

// read one char at a time from stdin, until EOF.
// let stdio to handle input buffering
while ( (ch = getchar()) != EOF) {

    buf[size] = (char)ch;
    ++size;

    // make buffer larger if needed, must have room for '\0' below!
    // size is always doubled, 
    // so reallocation is going to happen limited number of times
    if (size == reserved) {
        reserved *= 2;
        buf = realloc(buf, reserved);
        if (buf == NULL) exit(1); // out of memory
    }
}

// add terminating NUL character to end the string,
// maybe useless with binary data but won't hurt there either
buf[size] = 0;

// now buf contains size chars, everything from stdin until eof,
// optionally shrink the allocation to contain just input and '\0'
buf = realloc(buf, size+1);

Upvotes: 1

Gangadhar
Gangadhar

Reputation: 10516

Read like this

char ch,line[20];  
int i=0;  //define a counter

 //read a character assign it to ch,  
 //check whether the character is End of file or not and   
 //also check counter value to avoid overflow.

while((ch=getchar())!=EOF && i < 19 )   
{
   line[i]=ch;
   i++;
}
line[i]='\0';

Upvotes: 0

Nikos C.
Nikos C.

Reputation: 51832

scanf() splits the input at whitespace boundaries, so it's not suitable in your case. Indeed fgets() is the better choice. What you need to do is keep reading after fgets() returns; each call will read a line of input. You can keep reading until fgets() returns NULL, which means that nothing more can be read.

You can also use fgetc() instead if you prefer getting input character by character. It will return EOF when nothing more can be read.

Upvotes: 1

Douglas
Douglas

Reputation: 37763

If you want to read all input, regardless of whether it is whitespace or not, try fread.

Upvotes: 0

Related Questions