Thread: is this simple program correct? K&R 1-12

  1. #1
    Registered User fsx's Avatar
    Join Date
    Apr 2009
    Posts
    29

    is this simple program correct? K&R 1-12

    This is how I solved the exercise 1-12 from K&R. I have found another solution online, but mine seems a lot easier than the other, even if sometimes it prints too many newlines.
    Is this solution acceptable? If not, why? Thank you in advance.

    FSX

    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	int c;
    
    	while((c = getchar()) != EOF)
    	{
    		if((c == ' ') || (c == '\t'))
    			putchar('\n');
    		else
    			putchar(c);
    	}
    	return 0;
    }

  2. #2
    Complete Beginner
    Join Date
    Feb 2009
    Posts
    312
    Quote Originally Posted by fsx View Post
    Is this solution acceptable? If not, why?
    Since your program is not a correct solution, it is especially not acceptable. Re-read the exercise: "Write a program that prints its input one word per line." Your program occasionally prints empty lines, i.e. lines that don't contain a word (and certainly K&R weren't thinking about the empty word here).

    Try to get rid of these empty lines, e.g. by introducing two states "last character was a whitespace" and "last character wasn't". Also have a look at the isspace() function/macro.

    mine seems a lot easier than the other, even if sometimes it prints too many newlines.
    If you allow your program to occasionally produce incorrect results, here's an even simpler version:

    Code:
    int main() {}
    ;-),
    Philip
    All things begin as source code.
    Source code begins with an empty file.
    -- Tao Te Chip

  3. #3
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    Quote Originally Posted by fsx View Post
    This is how I solved the exercise 1-12 from K&R. I have found another solution online, but mine seems a lot easier than the other, even if sometimes it prints too many newlines.
    Is this solution acceptable? If not, why? Thank you in advance.

    FSX

    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	int c;
    
    	while((c = getchar()) != EOF)
    	{
    		if((c == ' ') || (c == '\t'))
    			putchar('\n');
    		else
    			putchar(c);
    	}
    	return 0;
    }
    i executed ur code and it seems to me its working properly.i simply inputted a line and it gave me each word of the line in a new line.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Try inputting two or more lines, Ben. You'll see the code prints additional blank lines.

    In any event, fsx, Snafuist is right - printing additional unwanted output hardly qualifies as a correct solution. The objective of writing code is to deliver the required functionality: no more, no less. Having code that is "easier" is not an excuse for delivering slightly different functionality. The programmer is expected to meet requirements, not force the user to accept compromised requirements.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by fsx View Post
    Code:
    	while((c = getchar()) != EOF)
    	{
    		if((c == ' ') || (c == '\t'))
    			putchar('\n');
    What you really want is a "nop" (no-op, no operation) and to continue --
    Code:
    		if((c == ' ') || (c == '\t'))
    			continue;
    Except you still need a line break! So maybe
    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	int c;
    	char flag=0;
    
    	while((c = getchar()) != EOF)
    	{
    		if((c == ' ') || (c == '\t'))
    			if (flag) continue;
    			else { putchar('\n');
    				flag=1; }
    		else {	putchar(c);
    			flag=0; }
    	}
    	return 0;
    }
    If you are just on chapter 1 you may not know about "continue" (it just starts the loop again without doing anything else).

    The use of a flag is a very handy, basic, chapter 1 kind of thing, so if you don't understand what that's about, try to, or ask and I'll explain.

    Basically now you could type:
    Code:
    this       is     a   sentance   with  extra      spaces
    Output:
    this
    is
    a
    sentence
    with
    extra
    spaces
    
    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
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    That was the idea that Snafuist introduced at the beginning. I think you could come up with a better name than "flag" for that variable, though. Maybe something like "saw_whitespace". There's also a logical bug in the program (which was present in my first version too): since the flag is initially zero, there will be a blank line at the beginning of the output if the first character is whitespace. Also, continue isn't really necessary.

    Anyway, here's my shot at it.
    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    int main() {
        int c, between_words = 1;
    
        while((c = getchar()) != EOF) {
            if(isspace(c)) {
                if(!between_words) {
                    putchar('\n');
                    between_words = 1;
                }
            }
            else {
                putchar(c);
                between_words = 0;
            }
        }
    
        return 0;
    }
    Note the use of isspace() from ctype.h. isspace [C++ Reference]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    Registered User fsx's Avatar
    Join Date
    Apr 2009
    Posts
    29
    I am still stumbling...


    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	int c, pc;
    
    	while((c = getchar()) != EOF)
    	{
    		if((c == ' ') || (c == '\t') && (pc != c))
    			putchar('\n');
    		else if((c != ' ') && (c != '\t'))
    			putchar(c);
    		else
    			putchar(c);
    		pc = c;
    	}
    	return 0;
    }

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What is not working?

    I would expect that you will need a nested if-statement:
    Code:
       if (c == ' ' || c == '\t')
       {
         if (pc != c)
           putchar('\n');
       }
       else 
           putchar(c);
    This will prevent multiple spaces from giving multiple newlines.

    --
    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.

  9. #9
    Registered User fsx's Avatar
    Join Date
    Apr 2009
    Posts
    29
    Thanks a lot! What I would like to understand is why if I use the && it doesn't works... shouldn't it be similar to another IF statement?

    Quote Originally Posted by matsp View Post
    What is not working?

    I would expect that you will need a nested if-statement:
    Code:
       if (c == ' ' || c == '\t')
       {
         if (pc != c)
           putchar('\n');
       }
       else 
           putchar(c);
    This will prevent multiple spaces from giving multiple newlines.

    --
    Mats

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Because you do not want the ELSE part to be executed if the second if is false - only if the first if is false.

    You could of course add a "if (pc != c)" inside the else-branch instead, but that's less logical.

    --
    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.

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by dwks View Post
    That was the idea that Snafuist introduced at the beginning. I think you could come up with a better name than "flag" for that variable, though.
    I called it "flag" because it is a (boolean) flag and I wanted the OP (fsx) to pick up on that (Snafuist refers to this as "two states", which is not quite as specific -- I guess you could see a boolean flag as an implementation of a two-state concept).

    You're right about the continue being unnecessary and the initial whitespace issue.

    Here's a related question: I usually use a char for boolean values cause it's smaller, but would it be true that an int is actually faster for the processor because it has a four byte boundary? Sort of nit-picking, but this could have a lot of significance in the right place...
    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

  12. #12
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by MK27 View Post
    Here's a related question: I usually use a char for boolean values cause it's smaller, but would it be true that an int is actually faster for the processor because it has a four byte boundary? Sort of nit-picking, but this could have a lot of significance in the right place...
    yes it could. you need profiling to prove it or opposite (when the cache size is critical issue)
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  13. #13
    Registered User fsx's Avatar
    Join Date
    Apr 2009
    Posts
    29
    Quote Originally Posted by matsp View Post
    Because you do not want the ELSE part to be executed if the second if is false - only if the first if is false.

    You could of course add a "if (pc != c)" inside the else-branch instead, but that's less logical.

    --
    Mats
    Mats got exactly what I was looking for, a simple explanation. I'm new to C and all those pointers, includes and so on are totally alien to my current knowledge. But thanks also for the other answerers.

  14. #14
    C / C++
    Join Date
    Jan 2006
    Location
    The Netherlands
    Posts
    312
    Quote Originally Posted by MK27 View Post
    Here's a related question: I usually use a char for boolean values cause it's smaller, but would it be true that an int is actually faster for the processor because it has a four byte boundary? Sort of nit-picking, but this could have a lot of significance in the right place...
    Can't bit fields be used for this (making the int size smaller) ? Or is the struct making it larger again?

    Code:
    #include<stdio.h>
    
    struct foo
    {
    	int flag:2;
    } bar;
    
    int main(void)
    {
    	bar.flag = 1;
    	printf("%d", bar.flag);
    	
    	return 0;
    }
    Operating Systems:
    - Ubuntu 9.04
    - XP

    Compiler: gcc

  15. #15
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Bitfields won't actually shrink the structure smaller than the actual type. That is to say, even if you set up a bit field of :2, it's still going to be at least an int in size.

    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simple Blackjack Program
    By saber1357 in forum C Programming
    Replies: 1
    Last Post: 03-28-2009, 03:19 PM
  2. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  3. Help with a troublesome C++ program
    By Kristina in forum C++ Programming
    Replies: 4
    Last Post: 05-18-2002, 01:28 PM
  4. Need help with simple DAQ program
    By canada-paul in forum C++ Programming
    Replies: 12
    Last Post: 03-15-2002, 08:52 AM
  5. Can't figure out why?
    By kwigibo in forum C Programming
    Replies: 10
    Last Post: 10-14-2001, 10:58 PM