#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    142
    Rep Power
    2

    Problem with getting input


    Code:
    int
    main()
    {
        // input
        double input1, input2;
        int input3;
        char input4;
        // get input
        printf("input1 (double)?> ");
        scanf("%lf", &input1);
        printf("input2 (double)?> ");
        scanf("%lf", &input2);
        printf("input4 (char)?> ");
        scanf("%c", &input4);
    
        // call function
        printf("%f, %f, %d, %c", input1, input2, input3, input4);
    
    }
    This is the program.
    It stops after I enter the value for input3 and skips to the last line.

    The program works fine until I insert
    Code:
        printf("input4 (char)?> ");
        scanf("%c", &input4);
    But having the above two lines without the other code for input1, input2, input3 works fine.
    What is the problem?
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,184
    Rep Power
    2222
    Uh, you never try to input input3. But that doesn't matter.

    This should be discussed in the "commonly asked questions" sticky thread. It involves scanf's behavior and what you're telling it to do with "%c".

    scanf will scan the input buffer and perform the conversions that you tell it to do. As soon as it has performed the last conversion, it returns, leaving in the input buffer the remaining characters that you had typed in. None of the standard input functions even begin to start processing input until you have pressed the Enter key. The character code for the enter key also gets entered into the input buffer. When scanf has performed its last conversion, then the characters that remain in the input buffer include the code for the Enter key ... and maybe that since Enter key code is all that's still in the input buffer, but it is quaranteed to be there.

    When you tell scanf "%c", you are telling it to read in the next character regardless of what it is. So scanf reads in the Enter key and stores it in input4. What does printf give you? An extra newline, right? If you don't believe me, then change that format string to: "%f, %f, %d, %c -- this should still be on the same line."

    What you need to do is to tell scanf that it needs to ignore any white space that it may encounter before it encounters a printable character. You do that with " %c"; please note the space before the percent sign.

    Computers don't do what we want them to do; they only do what we tell them to do.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    142
    Rep Power
    2
    I forgot to put input3 back after deleting some lines to try to debug, my bad.

    Thanks, I now understand why this happened and got it fixed.
    I did try the "this should be on the same line" and indeed it wasn't on the same line.

    By "conversion", do you mean to store the appropriate characters in the memory cell?
    So if I had
    Code:
    scanf("%lf", number);
    and entered '1.23CA<ENTER>', '1,23' would be "converted" and stored into memory cell number, while 'CA<ENTER>' would be in the input buffer?
    And is input buffer sort of like a temporary storage which records input from the keyboard?
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,184
    Rep Power
    2222
    For your questions, you need to understand what's happening and what format data is in. Plus consistent terminology is important.

    "Character" refers specifically to char data, which is what we place between single and double quotation marks, depending on whether it's single characters or strings (arrays) of characters. Binary data which is stored in int and float and pointer types is not referred to as being "character data". Yes, characters have integer values, but those values are the ASCII code for those characters.

    Now, in reality there's nothing inherently different between the patterns of bits that make up character data and binary data, integer data and floating-point data and memory addresses (AKA "pointers"). The only difference is in how the program uses those bits and that is determined by the data types we declare and the code that we write. So what we need to always keep in mind when we program, especially in C, is how we are interpreting those bit patterns in our data.

    Whenever you input data from the keyboard, it is character data. Every key that you press gets converted by the keyboard into the ASCII code for that character (yes, I'm glossing over the codes generated by function keys, pgup, etc). In your example of "1.23CA<ENTER>", that character data would be {0x31 0x2E 0x32 0x33 0x43 0x41 0x0A} *.

    [* FOOTNOTE:
    I'm not sure exactly what the Enter key places into the input buffer and I think it will vary between operating systems. In MS-DOS and Windows, it's two characters, carriage return and line feed, 0x0D 0x0A. In UNIX/Linux, it's only one character which I'm pretty sure is line feed, 0x0A, which the system interprets as the two-character CR-LF sequence. Both are represented by the '\n' escape sequence, though for some low-level applications (eg, generating specific characters for HTTP) I've see the sequence "\r\n" used to force an actual two-character CR-LF sequence. Suffice to say that whatever actually gets placed in the input buffer by the Enter key, it is treated as a single character when you read it.
    END FOOTNOTE]

    So when you input a value of 1.23 through the keyboard, it's actually received as "1.23" or {0x31 0x2E 0x32 0x33}. However, in a double variable, the value of 1.23 is this byte sequence, {0x3F 0xF3 0xAE 0x14 0x7A 0xE1 0x47 0xAE}. That means that in order to assign a value of 1.23 to a double variable, you will need to convert {0x31 0x2E 0x32 0x33} to {0x3F 0xF3 0xAE 0x14 0x7A 0xE1 0x47 0xAE}. That is what scanf does and that is why we call what it does "conversion".

    Originally Posted by 046
    and entered '1.23CA<ENTER>', '1,23' would be "converted" and stored into memory cell number, while 'CA<ENTER>' would be in the input buffer?
    Yes, that is correct.

    Originally Posted by 046
    And is input buffer sort of like a temporary storage which records input from the keyboard?
    Yes, that is also correct. In the actual electronics, the data is only present on the input port for a very limited amount of time. If your program and the operating system and all the other programs running concurrently with yours had to stop everything to fetch and process that single character being input, then that computer would not work very well. So instead that character gets buffered, it gets stored in a temporary location until your program can get around to reading it. It gets buffered by a special interrupt service routine which does its job very quickly so that it doesn't impact the other processes running on your computer. Similarly, when your program writes to the screen, it doesn't really do that since that would take too much time, so your output is also buffered so that you can write it all to the screen which is much more efficient. Same thing with reading from and writing to a disk file.

    Similarly, when C was designed (c. 1970), it was designed for a main frame or minicomputer that had several users logged in through dumb terminals -- remember, microprocessors didn't become commercial until the early 1970's and the IBM PC didn't come out until 1980. I believe that is why C input I/O is line-oriented; nothing happens until you hit Enter.

    I hope that helped.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    142
    Rep Power
    2
    Thank you for the detailed reply.

    So when you input a value of 1.23 through the keyboard, it's actually received as "1.23" or {0x31 0x2E 0x32 0x33}. However, in a double variable, the value of 1.23 is this byte sequence, {0x3F 0xF3 0xAE 0x14 0x7A 0xE1 0x47 0xAE}. That means that in order to assign a value of 1.23 to a double variable, you will need to convert {0x31 0x2E 0x32 0x33} to {0x3F 0xF3 0xAE 0x14 0x7A 0xE1 0x47 0xAE}. That is what scanf does and that is why we call what it does
    So at the point of input, each of "1", ".", "2", and "3" are separate letters treated as characters, and scanf treats the 4 characters as one whole unit, giving them a numerical value of 1.23?

    Also, can you explain {0x3F 0xF3 0xAE 0x14 0x7A 0xE1 0x47 0xAE}?
    I converted this, and what I got was ?  z G }.
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,184
    Rep Power
    2222
    Originally Posted by 046
    Also, can you explain {0x3F 0xF3 0xAE 0x14 0x7A 0xE1 0x47 0xAE}?
    I converted this, and what I got was ?  z G }.
    Huh?

    0xXX is standard C notation for a byte in hexadecimal notation.

    That says it all.

    Here are the binary representations:

    0011 1111 1111 0011 1010 1110 0001 0100 0111 1010 1110 0001 0100 0111 1010 1110

    Obviously, hexadecimal is easier to read than binary.

    So what is your question?

IMN logo majestic logo threadwatch logo seochat tools logo