3
tueor
6y

A v dumb C language question....

Consider this code snippet:

{
while( getchar() != EOF )
printf("a");
while( getchar() != EOF )
printf("b");
}

Is there some way to get inside the second loop? After I input some text, ctrl+D sends in the text stream and loop 1 executes, then the control waits at the test for loop 1 again, pressing ctrl+D again triggers EOF, but it ends up skipping all loops after

Comments
  • 1
    It's been a LONG time for me since I've done C, but I'm pretty sure after you exit the first while loop, you need to flush your buffer before you get to the second loop.

    example:
    {
    while( getchar() != EOF)
    printf("a");
    fflush(stdin);
    while( getchat() != EOF)
    printf("b");
    }
  • 2
    If you press CTRL-D and then enter, the control goes right to the second loop. CTRL-D followed by enter again passes over the second loop.

    I think the confusion is because you expect getchar() to read directly from the keyboard, which it doesn't because stdin is buffered. getchar() only gets results once you have hit enter.
  • 1
    @Fast-Nop Ctrl +D terminates the program straight up :/
    And as far as I know, typing input and then ctrl+D sends in the text stream, typing input and then enter sends in the text stream and \n.
    If there's no text stream, ctrl+D sends EOF consistently, hence all loops get bypassed and there's no output, and if enter is pressed in this case, it'll keep sending \n which is why my program keeps outputting
    'a'.
  • 0
    @PaladinRevenant It still won't let me enter the second loop ;_;
  • 2
    @iineo That behaviour must be caused by the shell that you are using. Once EOF, always EOF.

    When I test the snippet under Windows, CTRL-Z doesn't terminate the program, but needs an enter, and that enters the second loop.
  • 1
    @Fast-Nop godfuckingdammit
  • 1
    @iineo what you probably want isn't getchar() anyway, but getting direct keypresses, right?
  • 0
    @Fast-Nop I was doing an exercise from bkw's c programming language, the program already has a while(getchar()!=EOF) and the modification implied by the question required another loop of this kind. Even though I found a workaround, it left me wondering if its possible to enter a second loop of this kind.
  • 4
    @PaladinRevenant fflush(stdin); is undefined behavior

    stdin is an input stream, it shouldn't be written to
  • 0
    @Krokoklemme Yes, but if you're accepting input from the keyboard, isn't that what you're reading? Like I said, it's been a while, but I clearly remember periodically having to clear that buffer to prevent programs from acting upon character that had already been input instead of waiting for new input.
  • 1
    @PaladinRevenant idk, but that's what the C specs says
  • 0
    @iineo getchar usually gives you EOF if the input has ended. That happens if you have stdin from a pipe once the parent process has died, and then the child process won't get any input anymore and needs to end anyway. I don't think that another loop of this kind was actually required.

    @PaladinRevenant getchar() needs an enter, so if you want to read directly, i.e. without waiting for enter, then you can't use getchar() just like that. Under Windows, you have getch(). Under Linux, you need to work with termios and then getchar, just a few lines of code.
  • 1
    @Fast-Nop the question says "revise the main routine so it can print the correct length of arbitrarily long strings", so I thought of putting another loop in main which'd do len++ until EOF is reached. How'd you solve it?
  • 0
    @Fast-Nop What I did was terminating the loop in main with \n instead, it works BUT THIS EOF THING IS CONFUSING ME
  • 2
    @iineo as I assumed, the task wasn't about another loop. Actually, the EOF check is more in the spirit of an error check in case the program ends suddenly. It is not meant for actual control flow.

    The thing that was asked here is to replace the fixed MAXLINE limit, not adding another loop. You will need dynamic memory allocation for that one.

    OR you just drop storing the actual string data and only count the length, that might also fulfill the task.
  • 1
    @Fast-Nop wtf but its the first chapter and they've described nothing about dynamic memory allocation yet :/ searching online does yeild solutions like mine, but maybe the book assumes familiarity with C, idk man
  • 2
    @iineo OK, then dynamic allocation is not what is being asked. What you can do is dropping the storage of the input characters and only count how many characters you have between two enters. And then keep a maximum value to track that.

    So the result would be that you don't print the content of the longest line because you discarded the actual characters; instead, you only print the maximum length.
  • 1
    @Fast-Nop I do need to store some characters because modification of getline isn't allowed, so I have to start counting the input characters from the stream the moment the array gets filled, I guess the only way to do that is to use getline to clear the imput buffer+count characters along with it
  • 1
    @iineo Ah OK getline must stay as is. Well OK, that function also terminates if the buffer is full without having seen enter. In that case, the last character in the line buffer will not be '\n'.
  • 1
    @Fast-Nop Yeah but I had to workaround it in a way last character of the input stream has to be \n because Ctrl+D either flushes the input buffer and sends me back to the same loop, or bypasses all loops if there's nothing in the buffer
  • 0
    @iineo You aren't supposed to use CTRL-D in regular control flow. That's why the loop will also terminate on enter. The EOF check is just there to avoid zombie processes.
  • 1
    @Fast-Nop Ohhh I thought ctrl+D is supposed to be part of program and can be used as input, thank you so much for clearing this up for me.
  • 0
    @highlight
    while( getchar() != EOF) printf("a");
    fflush(stdin);
    while( getchat() != EOF) printf("b");
  • 2
Add Comment