0

I'm quite confused about the function scanf and how the input works in C.

See this code :

#include<stdio.h>

int main()
{
    FILE pt = *stdin;
    char b[100];
    scanf("%s", b);
    scanf("%s", b); //breakpoint here
    scanf(" ");     //breakpoint here
}

When the code runs, I input 12345 into the console. I found that pt _ptr(which I don't actually know what it is) has the value "12345\n\n" and b[] has the value "12345".

Then I continue the program and input 23456. Now pt _ptr is "23456\n\n" and b[] is "23456".

My question :

  • How does the input work in C? Why does pt _ptr have the value of "12345\n\n" not "12345\n" since I pressed enter only one time(and it seems like the function scanf skips those two \n after successfully read "12345" ).
  • Did you read documentation of [scanf(3)](http://man7.org/linux/man-pages/man3/scanf.3.html) and of every other function you are using? – Basile Starynkevitch Oct 23 '14 at 17:02
  • How scanf works will vary from operating system to operating system. For example [here's how it works on a Mac](http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/libkern/stdio/scanf.c), chosen just by virtue of being the easiest version to find. – Dan Oct 23 '14 at 17:03

2 Answers2

2

You are looking under the carpet... You are not supposed to copy FILE structs so the first line

FILE pt = *stdin;

results are actually undefined. Do not look inside, unless you are willing to read and understand the source of you standard C library!

The rest of the code is pretty easy to understand, as b has always the expected value, isn't it?

rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • You might even have some C implementations which won't compile that assignment (e.g. because `FILE` would be `typedef`-ed to some *private* `struct`). – Basile Starynkevitch Oct 23 '14 at 17:04
  • YEP! But I thought that was how I should do it if I want to know the data in stdin, I mean, how to actually look at the current stdin? – Santi Santichaivekin Oct 23 '14 at 17:05
  • 1
    @SantiSantichaivekin: You do not _look into_ stdin. You _read from_ stdin. And you _write to_ stdout, BTW. `FILE` does not have any public field, so you can use it only through the library functions. – rodrigo Oct 23 '14 at 17:06
  • If you just want to see what characters are coming next in stdin without reading them, [someone has a StackOverflow question about that](http://stackoverflow.com/questions/13993742/is-there-anyway-to-peek-at-the-stdin-buffer) – Dan Oct 23 '14 at 17:06
  • @Dan: Yes, but IME, peeking that way is not worth the trouble. – rodrigo Oct 23 '14 at 17:08
0

It is not apparent what it is you are really trying to do besides learn scanf, but you are also invoking stdin and the FILE struct.

Using fscanf instead, (read link for details on `fscanf) it will be easier to use all three.

Here is a simple example of how you can combine fscanf, FILE, and stdin:

int main(void)
{
    FILE *fp={0};
    int res =0 //use to check return value of fscanf 
    char buf[80]; //use 80 for demonstration only
    fp = fopen("c:\\dev\\play\\playtext.txt", "w");//create file and stream
    res = fscanf(stdin, "%s", buf);//stream input from stdin
    if(res == EOF) 
    {
        printf("Exiting...  input error");//notify and exit upon error
        return -1;
    }
    while (strstr(buf, "quit") == NULL)//allow exit by typing quit
    {
        if(fputs(buf, fp) == EOF) return -1;
        buf[0]=0;//reset buffer
        res = fscanf(stdin, "%s", buf);
        if(res == EOF) 
        {
            printf("Exiting...  input error");//notify and exit upon error
            return -1;
        }
    }
    fclose(fp);
    return 0;
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • the function fscanf() returns the number of parameters set, never EOF, though it can return 0 if no parameters are set. – user3629249 Oct 24 '14 at 00:36
  • @user3629249 - It may be you are using an old implementation compiler?. From my documentation - fscanf _Reads input from the specified stream and converts it into a series of values according to the specifications of the formatting string. If an input failure occurs before any conversion, the function returns EOF (-1); otherwise, the function returns the number of input items successfully read._ From ***[MSDN](http://msdn.microsoft.com/en-us/library/aa246414%28v=vs.60%29.aspx)***, From Linux ***[man pages](http://linux.die.net/man/3/fscanf)***. (look under ***Return Value***) – ryyker Oct 24 '14 at 16:12