Thread: doubt about kernighan and ritchie excercise 1-12

  1. #1
    Registered User
    Join Date
    Aug 2008
    Posts
    4

    Question doubt about kernighan and ritchie excercise 1-12

    The exercise is to write a program that writes its input one word per line, I did this:
    Code:
    /* Exercise 1-12. Write a program that prints its input one word per line */
    
    #include <stdio.h>
    
    #define IN 1
    #define OUT 0
    
    main()
    {
     int c;
     int state = OUT;
    
     putchar('\n');
     putchar('\n');
    
     while((c = getchar()) != EOF){
    	if((c == ' ' || c == '\t' || c == '\n') && (state == IN)){
    		putchar('\n');
    		state = OUT;
    	}
    	if(c == '\n')
    		printf("por fin lo has logrado");
    	else if((c != ' ') && (c != '\t') && (c != '\n') ){
    		putchar(c);
    		state = IN;
    	}
     }
     putchar('\n');
     putchar('\n');
    }
    The problem is that when I input a newline (pressing enter), the program shows the output. Why the program is interpreting the -enter- as if I was asking it to evaluate the input instead of interpreting it as a newline? How can I make the program interpret the -enter- as a newline?

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I believe you should put your buffered input into a buffer (a large char array perhaps), and then go through it, char by char, and process it - fgets() looks quite promising for that job.

    I don't know if there is any way to treat buffered input, like it's sometimes buffered, and sometimes, like it's unbuffered. How would the program know which is which?

    There might be some slick way to do this, but I don't know it.

    And welcome to the forum. Congrats on using code tags!
    Last edited by Adak; 01-03-2009 at 07:20 PM.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    What you are trying to do is very strange, but what you say you are trying to do should not be like this.

    I think this issue with getchar has to do with the terminal device or shell which executes the program. I don't believe that it can be forced to pass input to the program without a newline. For stuff like that you need to use some kind of terminal library.

    But I still think you should explain what this was supposed to do, even if you could echo keystrokes this way it certainly would not look like something that
    prints
    its
    input
    one
    word
    per
    line"
    Last edited by MK27; 01-03-2009 at 07:25 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    The idea of the program most certainly is to print words to stdout one word per line - ignoring spaces etc. Entering my last sentence into the program would produce the following, after hitting enter:

    Code:
    The
    idea
    of
    the
    program
    most
    certainly
    is
    to
    print
    words
    to
    stdout
    one
    word
    per
    line
    -
    ignoring
    spaces
    etc.
    The reason the OP wants to do this with getchar is because at that point of K&R, they have only used the most basic i/o functions available.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    So you wouldn't want to try and do this:

    Code:
    tthhee   iiddeeaa   ooff    tthhee   pprrooggrraamm
    if you could

    Can the OP (aof_1) consider storing the characters in an array?
    Last edited by MK27; 01-03-2009 at 07:50 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Wouldn't matter - the program is looking for 'words' which could be mis-spelled words as in your example - the idea is not to check spelling but, in a very general sense, check the input one character at a time. If during that check, the program determines it is still within the bounds of a 'word' then it moves to the next character, and so on. Once it comes to the point where it is not in a word anymore, i.e., a tab or a space or a newline, then it can print it to the screen on a new line, and then continue checking characters.

  7. #7
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Quote Originally Posted by MK27 View Post

    I think this issue with getchar has to do with the terminal device or shell which executes the program. I don't believe that it can be forced to pass input to the program without a newline.
    I agree.

    According to my C book, for getchar(), when Enter is pressed, all the characters entered, including the newline, are sent to stdin by the operating system.

    Hence

    Code:
    if(c == '\n')
    		printf("por fin lo has logrado");
    prints "por fin lo has logrado".

    Also, the program works the same without "state, IN, OUT" removed:

    Code:
    #include <stdio.h>
    
    main()
    {
     int c;
    
     putchar('\n');
     putchar('\n');
    
     while((c = getchar()) != EOF){
    	if((c == ' ' || c == '\t' || c == '\n') ){
    		putchar('\n');
    
    	}
    	if(c == '\n')
    		printf("por fin lo has logrado");
    	else if((c != ' ') && (c != '\t') && (c != '\n') ){
    		putchar(c);
    
    	}
     }
     putchar('\n');
     putchar('\n');
    }
    Last edited by happyclown; 01-03-2009 at 08:11 PM.

  8. #8
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Basically the program is to parse its input into words, and print those words one line at a time. The way to do this with the limited functions provided at the stage of K&R the reader is at, is to implement a state machine, which is what the OP was trying to do. He is definitely on the right track.

  9. #9
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by afol_1 View Post
    The problem is that when I input a newline (pressing enter), the program shows the output. Why the program is interpreting the -enter- as if I was asking it to evaluate the input instead of interpreting it as a newline? How can I make the program interpret the -enter- as a newline?
    To answer your question, the input on your implementation is undoubtedly buffered, which means that for you to input any info at all, you need to press ENTER. In other words, when you are using a function such as getchar, the characters are held in a buffer (controlled by your operating system) until you press enter. getchar does not receive the characters you type, until you press enter. If you want some other type of behaviour, you might be able to see something in the FAQ.

    As to your program, you really were on the right track. Study the following, and note the slight changes I made, hopefully making the logic a little more clear:

    Code:
    #include <stdio.h>
    
    #define IN 1
    #define OUT 0
    
    int main(void)
    {                               /* main returns an int. */
        int c;
        int state = OUT;            /* Assume we start outside a word, in a space. */
    
        while ((c = getchar()) != EOF) {
            if (c == ' ' || c == '\t' || c == '\n') {   /* We are in a space now */
                if (state == IN) {  /* Have we just now come out of a word? */
    
                    putchar('\n');  /* Print the whitespace as a newline */
    
                    state = OUT;    /* Change the state and check the next character */
                }  /* Else we are still in a space, so we really don't 
                    * want to do anything but check the next character */
            } else {                /* We are in a word */
                putchar(c);
                state = IN;
            }
        }
        return 0;                   /* Since main returns an int, why not return an int? */
    }
    Last edited by kermit; 01-03-2009 at 10:02 PM.

  10. #10
    Registered User
    Join Date
    Aug 2008
    Posts
    4

    Thumbs up thanks

    thanks everyone, especially kermit for taking the time of revising the code.

  11. #11
    Registered User
    Join Date
    Dec 2008
    Posts
    104
    /* Since main returns an int, why not return an int? */
    that is not the point of making main() an int. i suggest you learn about processor errors.

    @OP: why use EOF if that is only for FILE objects and in console it will not return EOF(-1) if it finished reading input.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by abraham2119 View Post
    @OP: why use EOF if that is only for FILE objects and in console it will not return EOF(-1) if it finished reading input.
    Console returns EOF if you hit CTRL-Z (Windows/DOS etc) or CTRL-D (Linux/Unix etc), since those control characters mean EOF on a text-file (which stdin is [unless you close stdin and re-open it in binary mode - but that's really messing about with things that you probably shouldn't amessing with]).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by abraham2119 View Post
    that is not the point of making main() an int. i suggest you learn about processor errors.
    Sir, yes sir!

    Seriously though, I was being a little bit tongue in cheek there with my approach. My example was not to teach a semester of CS in one post.

Popular pages Recent additions subscribe to a feed