Thread: K & R Chapter 1.9 getline problem

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    32

    K & R Chapter 1.9 getline problem

    Hello,

    I tried to experiment with the code in K & R chapter 1.9 (a program that reads a set of text lines and prints the longest) and I was getting weird results when entering EOF (pressing CTRL+D on my system).

    The code of the function in question is posted below. I set a breakpoint on the line labelled HERE. When I pressed CTRL+D, the breakpoint was never triggered, which means that the for loop didn't end.

    Any explanations why, please?

    Code:
    int getline(char s[],int lim)
    {
           int c, i;
           for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
               s[i] = c;
           if (c == '\n') {
               s[i] = c;
           ++i; }
           s[i] = '\0'; /* HERE */
          return i;
    }

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    What platform? *nix or windows.

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    32
    Quote Originally Posted by itCbitC View Post
    What platform? *nix or windows.
    *nix (Mac OS X 10.7 with XCode 4)

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    XCode uses the emacs style of EOF so instead of Ctrl-D try Ctrl-Q+Ctrl-D

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You have to hit ctrl-D twice to get it to work. The reason seems to be explained here: python - Why do I have to press Ctrl+D twice to close stdin? - Stack Overflow.

    EDIT: Oh, just saw that you're on OSX. I tested on Linux.

  6. #6
    Registered User
    Join Date
    May 2011
    Posts
    32
    Quote Originally Posted by anduril462 View Post
    You have to hit ctrl-D twice to get it to work. The reason seems to be explained here: python - Why do I have to press Ctrl+D twice to close stdin? - Stack Overflow.

    EDIT: Oh, just saw that you're on OSX. I tested on Linux.
    If I enter some text and press CTRL+D twice, the breakpoint gets triggered twice! The first time reading the text/string and returning its length, the second time reading an empty string and returning zero (thus terminating the whole program).

    However, it doesn't seem to be doing anything when I press it only once. Strange...

  7. #7
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Try printing some stuff from your program, this might clue you in on what's going on.

  8. #8
    Registered User
    Join Date
    May 2011
    Posts
    32
    Quote Originally Posted by itCbitC View Post
    Try printing some stuff from your program, this might clue you in on what's going on.
    How is "entering" EOF supposed to work in programs then? I figure it just sends the input text/string for processing to my program, very much like a newline (enter) does. Am I getting it wrong?

    Tested it with:

    Code:
    while(1)
    {
            c = getchar();
            putchar(c);
    }
    And after pressing CTRL + D (EOF) or Enter (newline), the text I typed before that gets printed. I can repeat that infinitely...

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Did you read the link I posted? Click on the red text in post #5, the second answer to the question on stack overflow explains it. If you still need help understanding something specific in that thread, then ask something more specific.

    EDIT: I think the second answer is clearer than the first.
    Last edited by anduril462; 08-31-2011 at 02:35 PM.

  10. #10
    Registered User
    Join Date
    May 2011
    Posts
    32
    Quote Originally Posted by anduril462 View Post
    Did you read the link I posted? Click on the red text in post #5, the second answer to the question on stack overflow explains it. If you still need help understanding something specific in that thread, then ask something more specific.

    EDIT: I think the second answer is clearer than the first.
    Just read it. What I don't get is that EOF works as described on stack overflow in the while(1) loop in post #8 and doesn't work like that in the function in my original post - it doesn't flush the input I typed so far in that case.

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Ahh, I see what you're asking. Here's what it is (at least, I'm pretty sure this is it):

    stdin isn't transmitted to your program until you hit ctrl-D or enter.
    stdout isn't flushed until you print a new line, call fflush(stdout), or request input.

    Let's go through an example of typing "asdf<ctrl-D><ctrl-D>" in each program

    K&R
    1. You type "asdf" at the keyboard, and see it echoed out on the terminal
    2. You then type <ctrl-D>, causing your terminal to send "asdf" to your program
    3. Your program reads in "asdf", but does not see a '\n' or EOF yet, so it stays in the for loop
    4. You then type <ctrl-D> a second time, and your program reads the EOF, finishing the for loop and exiting getline
    5. You print the contents of the buffer filled by getline
    Your while loop
    1. You type "asdf" at the keyboard, and see it echoed out on the terminal
    2. You then type <ctrl-D>, causing your terminal to send "asdf" to your program
    3. Your loop reads "asdf" (via getchar) character-by-character, and does a putchar with every character it reads.

    Now, remember, getchar is a "request input" function. That causes stdout to be flushed. You read one char, called putchar (which doesn't flush stdout), then tried to read again. It's the subsequent read that causes the previous char to be printed on your screen.

    Hope that clears it up.

  12. #12
    Registered User
    Join Date
    May 2011
    Posts
    32
    Quote Originally Posted by anduril462 View Post
    Ahh, I see what you're asking. Here's what it is (at least, I'm pretty sure this is it):

    stdin isn't transmitted to your program until you hit ctrl-D or enter.
    stdout isn't flushed until you print a new line, call fflush(stdout), or request input.

    Let's go through an example of typing "asdf<ctrl-D><ctrl-D>" in each program

    K&R
    1. You type "asdf" at the keyboard, and see it echoed out on the terminal
    2. You then type <ctrl-D>, causing your terminal to send "asdf" to your program
    3. Your program reads in "asdf", but does not see a '\n' or EOF yet, so it stays in the for loop
    4. You then type <ctrl-D> a second time, and your program reads the EOF, finishing the for loop and exiting getline
    5. You print the contents of the buffer filled by getline
    Your while loop
    1. You type "asdf" at the keyboard, and see it echoed out on the terminal
    2. You then type <ctrl-D>, causing your terminal to send "asdf" to your program
    3. Your loop reads "asdf" (via getchar) character-by-character, and does a putchar with every character it reads.

    Now, remember, getchar is a "request input" function. That causes stdout to be flushed. You read one char, called putchar (which doesn't flush stdout), then tried to read again. It's the subsequent read that causes the previous char to be printed on your screen.

    Hope that clears it up.
    Thanks for your valuable post, I now get it! Perfect! Thanks again!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. debug problem --> chapter 5.6 K&R
    By c_lady in forum C Programming
    Replies: 2
    Last Post: 06-18-2010, 03:26 AM
  2. problem with quix chapter 4
    By roelof in forum C++ Programming
    Replies: 2
    Last Post: 05-31-2010, 08:38 AM
  3. K&R chapter 8
    By Tool in forum C Programming
    Replies: 9
    Last Post: 02-22-2010, 02:05 PM
  4. getline problem
    By Bitphire in forum C++ Programming
    Replies: 5
    Last Post: 10-18-2004, 04:42 PM
  5. getline problem
    By Steph in forum C++ Programming
    Replies: 7
    Last Post: 01-18-2002, 06:25 PM