LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   scanf reading newline into char array while reading 1 char at a time (http://www.linuxquestions.org/questions/programming-9/scanf-reading-newline-into-char-array-while-reading-1-char-at-a-time-834403/)

austinium 09-25-2010 04:55 AM

scanf reading newline into char array while reading 1 char at a time
 
The following code should read 4(and adds a '\0') into the character array str. As i debugged the code i figured that it reads newline into the str[index+1] after reading into str[index] after i hit Enter upon entering the desired character.

Code:

#include<stdio.h>
#include<string.h>

int main(void)
{
        char str[5];
        int cntr=0;

        memset(str,'\0',strlen(str));

        for(cntr=0;cntr<4;cntr++)
        {
                fflush(stdin);
                scanf("%c",&str[cntr]);
        }

        printf("\n%s\n",str);

        return 0;
}

Output

Code:

1
2
3

1
2
3�]

i've not been C much off late, don't know what i am missing here.

I know i can check each character and make sure newline characters don't make it into the array, but that would be an overkill.

help!

Sergei Steshenko 09-25-2010 06:13 AM

Quote:

Originally Posted by austinium (Post 4108496)
The following code should read 4(and adds a '\0') into the character array str. As i debugged the code i figured that it reads newline into the str[index+1] after reading into str[index] after i hit Enter upon entering the desired character.

Code:

#include<stdio.h>
#include<string.h>

int main(void)
{
        char str[5];
        int cntr=0;

        memset(str,'\0',strlen(str));

        for(cntr=0;cntr<4;cntr++)
        {
                fflush(stdin);
                scanf("%c",&str[cntr]);
        }

        printf("\n%s\n",str);

        return 0;
}

Output

Code:

1
2
3

1
2
3�]

i've not been C much off late, don't know what i am missing here.

I know i can check each character and make sure newline characters don't make it into the array, but that would be an overkill.

help!

Reading '\n' is by construction, so what help are you asking for ?

ntubski 09-25-2010 08:59 AM

man scanf(3)
Quote:

* A sequence of white-space characters (space, tab, newline, etc; see isspace(3)). This directive matches any amount of white space, including none, in the input.
Code:

        char str[5];
        int cntr=0;

        memset(str,'\0',strlen(str));

At your call to strlen(), str's contents are undefined so strlen could return anything, you should use sizeof instead.

austinium 09-26-2010 12:12 AM

Quote:

Originally Posted by Sergei Steshenko (Post 4108537)
Reading '\n' is by construction, so what help are you asking for ?

I am trying to read characters into an array using scanf, its not working like it should...i.e., when i hit enter i expect the index to be incremented so that the next character can be input, what is happening here is that '\n' is also being treated as character and is being stored into the array. may be this is how it is meant to be in the C Standard, and maybe this is not the right way to read characters into a an array?

Quote:

Originally Posted by ntubski (Post 4108632)
man scanf(3)
At your call to strlen(), str's contents are undefined so strlen could return anything, you should use sizeof instead.

thanks :)

paulsm4 09-26-2010 12:53 AM

Hi -

1. There are several problems with your original code. First, here's sample output from the code you originally posted (it happens to "work", despite the two "strlen()" errors):
Code:

$ g++ -o x -Wall -pedantic test.c
$ ./test
9876543210

9876

2. The first problem is "memset(str,'\0',strlen(str));"
As you already saw, "str" isn't terminated, so strlen() is a bug.
One workaround is "memset (str, 0, sizeof(str));".
Perhaps a better solution might be to add the terminator after you've added all the characters.

3. The second problem is the "fflush()". You don't need it.

4. You're trying to read a character at a time. Fine.

But the OS gives you a LINE at a time.

In other words, you don't get ANY characters from the keyboard to your program until you hit <Enter>. Then you get them all at once.

This is the whole point behind "buffered input".

If you don't want this behavior (if you actually DO need to read a character at a time), then you need to look at a library like curses (which does text-mode screen control), or SDL (which lets you read individual events from a mouse, keyboard or joystick).

Here's a modified version of your code, and the corresponding output:
Code:

#include <stdio.h>
#include <string.h>

#define MAXCHAR 4

int
main  (int argc, char *argv[])
{
  char str[MAXCHAR+1];
  int i=0;

  for (i=0; i<MAXCHAR; i++)
  {
    scanf ("%c", &str[i]);
  }
  str[MAXCHAR] = '\0';

  printf ("\n%s\n", str);
  return 0;
}

       
Code:

       
$ g++ -o x -Wall -pedantic test.c
$ ./test
9876543210

9876




Sergei Steshenko 09-26-2010 01:14 AM

Quote:

Originally Posted by austinium (Post 4109152)
.. its not working like it should ...

There is a manpage of 'scanf'. 'scanf' should work as the manpage (and related manpages) describe. If it doesn't work as the manpage(s) prescribe, you've found a bug in 'scanf', which a is a part standard "C" library ('glibc'), so file a bug against it.

austinium 09-26-2010 11:27 PM

thanks for your replies ppl...they've been very helpful

@Sergei ... notice that should was in italics, by that i meant that it wasn't working like how I thought it would...i'll refer to the man pages ASAP...gotta get reading


All times are GMT -5. The time now is 05:57 PM.