Thread: getchar() wierd Behaviour

  1. #1
    Registered User
    Join Date
    Jun 2018
    Posts
    3

    Post getchar() wierd Behaviour

    I am starting to learn C and do it with the "c programming language" by
    Kerningham and Ritchie. I am currently at page 31.

    there is an example program which has to be refined:

    Code:
    #include <stdio.h>
    #define MAXLINE 1000
    
    int getLine(char line[], int maxline);
    void copy(char to[], char from[]);
    
    int main(){
      int len,max,m;
      char line[MAXLINE];
      char longest[MAXLINE];
    
      m=0;
      max =0;
      while((len=getLine(line, MAXLINE)) > 0)
        if(len > max) {
          max = len;
          copy(longest, line);
        }
      }
      if(max > 0)
        printf("%s\n", longest);
      return 0;
    }

    in an followup excercise i should handle an error, coming to life, after a
    line is fed in longer than MAXSIZE. for this i should display the actual length of the line and display the maximum amount of chars i can (which is MAXSIZE -1).

    I use the function getLine, which looks like this:

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

    when i implement my solution inside the while loop where i call the function "getLine"(using the function getchar()) like this:

    Code:
    while((len=getLine(line, MAXLINE)) > 0)
      if(len > max) {
        max = len;
        copy(longest, line);
        if(max == MAXLINE -1 && longest[MAXLINE-1] == '\0' 
                && longest[MAXLINE-2] != '\n'){
          int c;
          while((c=getchar()) != EOF && c != '\n'){
            ++m;
          }
          printf("input line too long.\n chars: %d\n", m+MAXLINE);
        }
      }
      ..code refer to the main program at the top
    }
    i get the proper output and count of chars from input.
    BUT when i call getchar() outside the while loop. where I call the function using getchar to get the initial input. like this:

    Code:
    ...code refer to the whole program at the top
    if(max > 0){
      if(max == MAXLINE -1 && longest[MAXLINE-1] == '\0' 
                && longest[MAXLINE-2] != '\n'){
        int c;
        while((c=getchar()) != EOF && c != '\n'){
          ++m;
        }
        printf("input line too long.\n chars: %d\n", m+MAXLINE);
      }
    }
    then c == -1 which is equal to EOF.

    My Question is the following:
    why does it seem that the input buffer is getting emptied as soon as i leave the loop where i first read it with getchar()?

    I am a beginner and just starting out with c. as this is a relative hard problem to search for i thought ill ask here. thanks for your time. i am open to any suggestions.

    yay first post

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,628
    You are doing the line-to-long check in the wrong place. If you put it after the while loop like you have it, then the input will already be at EOF (how else would the while loop have ended?).

    It needs to be inside the while loop and you need to compare len, not max.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    Registered User
    Join Date
    Jun 2018
    Posts
    3
    Thanks very much for your response.

    your right i dont quite understand the behaviour of the while loop there.

    Code:
    while ((len = getline(line, MAXLINE)) > 0)

    the first time executed (assuming the line exceeds MAXLINE), len would be equal to 999. the while would be therefor true.
    the code inside gets executed. then it gets evaluated again. with above mentioned function:

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



    if it gets called again, will i be initialized a second time? and therefor be 0?
    or will it store its previous value somehow, know i == 999 which is != lim-1
    which will prevent the for loop from executing.
    but if i were initialized again and be equal to 0, it would store a null terminator
    at position 0 of the array s; which it doesnt do

    therefor i have to assume i is stored somehow, but this would create an infinite loop
    as return i never would drop to 0 or below, which would make len always above 0
    and the while loop would always be true.

    you see i have some issues interpreting the execution of the code correctly
    any help is appreciated.

    pps:
    i corrected the error at:
    Code:
    if(max == MAXLINE -1 && longest[MAXLINE-1] == '\0'
                && longest[MAXLINE-2] != '\n')
    pointed out by you and corrected it with:
    Code:
    if(len == MAXLINE -1 && longest[MAXLINE-1] == '\0'
                && longest[MAXLINE-2] != '\n')
    i have also put the error checking (if line too long for MAXLINE) at the top. like this:
    Code:
    while((len=getLine(line, MAXLINE)) > 0)
      if(max == MAXLINE -1 && longest[MAXLINE-1] == '\0'
                && longest[MAXLINE-2] != '\n'){
    
        int c;
    
        while((c=getchar()) != EOF && c != '\n'){
    
          ++m;
    
        }
    
        printf("input line too long.\n chars: %d\n", m+MAXLINE);
    
      }
    
    
      if(len > max) {
    
        max = len;
    
        copy(longest, line);
    
      }
    
    }

  4. #4
    Registered User
    Join Date
    Dec 2017
    Posts
    1,628
    if it gets called again, will i be initialized a second time?
    Yes.

    but if i were initialized again and be equal to 0, it would store a null terminator at position 0 of the array s
    Why would it do that? There's no '\0' in the input, if that's what you're thinking.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  5. #5
    Registered User
    Join Date
    Jun 2018
    Posts
    3
    alright I got it. your help is very much appreciated.

    to wrap it up:
    as 'i' is reinitialized at the second run of the while loop it starts again from zero and goes through the input buffer until it finds the EOF or a newline character.
    I thought once reached the limit it will stop from evaluating the input buffer and as 'i' equal to 0. it would enter a null terminator
    at the beginning of the array it will later evaluate on. this isn't true obviously.

    what made me understand:
    the limitation of length is just valued while the loop is running, thats why one has to test inside the while loop.
    now it seems obvious, but then it was hard to distinguish the different approaches testing the while clause.
    testing for a limit meant: check if the input is the longest I can store in one loop. (valid once)
    testing for EOF or newline: check if the input has reached EOF or \n. (valid continuously)
    note that valid here doesn't stand for true it stands for the importance of the test in time.

    as soon as the loop ran twice the array would have been overwritten with input[lim + input<lim], at its end a null terminator, and EOF or \n would have been reached.
    Therefor testing the input outside of the while would always return nil. because there is nothing left on the same line.
    The title shouldn't be
    getchar() wierd behaviour
    it should be
    while and different aspects of testing.


    thanks to John.c for clarification.
    thread is closed.
    Last edited by cless; 06-30-2018 at 06:50 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. wierd behaviour of strlen
    By saurabhsnha in forum C Programming
    Replies: 7
    Last Post: 07-20-2010, 03:30 AM
  2. wierd..
    By Mitsukai in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 01-20-2006, 03:21 PM
  3. huh wierd
    By drdodirty2002 in forum C++ Programming
    Replies: 3
    Last Post: 09-25-2004, 01:40 PM
  4. This is wierd.
    By Ranedhel in forum C++ Programming
    Replies: 6
    Last Post: 12-12-2003, 03:26 PM
  5. wierd !!
    By GSLR in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 11-15-2003, 05:19 AM

Tags for this Thread