Thread: program logic

  1. #1
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534

    program logic

    Yet another K&R exercise that I am having some troubles with. Heh.... I was just accepted for a series of night school computer courses at the local community college, so hopefully I will get on to some of this stuff better and more quickly.

    But as for the trouble I have..

    The exercise is to:

    "Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank"

    After some consideration of how the solution might work, this is what I came up with:

    Code:
    #include <stdio.h>
    
    /* This is from K&R and what it is supposed to do is *
     * copy the input to the output, and then replace    *
     * each string of one or more blanks with a single   *
     * blank.                                            *
     */
    
    int main(void)
    {
         int c;
         int done;
         int blank;
         
         done = 0;
         blank = 0;
         
         while ( done == 0 )
         {
    	  c = getchar();
    
    	  if ( c == ' ' )
    	       ++blank;
    	 
    	  {
    	       if ( blank >= 2 )
    		    ( c = ' ' );
    	      
    	       putchar( c );
    	       blank = 0; 
    	  }
    
    
    	  c = getchar();
    
    
    	  if ( c == EOF )
    	       done = 1;
         }
         
         return 0;
    }
    The idea was to count the blanks, and if the variable 'blank' got higher than 1, to set the value of c to one blank, then putchar() to the output - This 'solution' of mine definitely does not work the way I want it to, and is not close to the answers posted here , however, perhaps somebody would be willing to give me a hint, and point me in the right direction. I am aware that I have possibly done some poor logical structure, but I will leave the critique to all of you.

    kermit

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    You have to be careful not to print anything until all of the blanks have been taken in. Then you print a single blank and the next nonblank character. If there are no blanks, then you need to print every time. This logic really calls for an if..else if..else sequence:
    Code:
    /*
    * Copy input to output, compact whitespace
    */
    #include <stdio.h>
    
    int main(void)
    {
        int c;
        int done;
        int blank;
        
        done = 0;
        blank = 0;
        
        while ( done == 0 )
        {
            c = getchar();
    
            if ( c == EOF )
                done = 1;
            else if ( c == ' ' )
                blank++;
            else if ( blank > 0 ) {
                blank = 0;
                putchar( ' ' );
                putchar( c );
            }
            else
                putchar( c );
        }
        
        return 0;
    }
    My best code is written with the delete key.

  3. #3
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    1) You have two getchar() functions. Use only one. If EOF is reached, use the break command.
    2) You only putchar() when there are two or more spaces.

    My advice:
    If you reach a space, getchar() until there are no more spaces, and putchar a single space.

  4. #4
    Registered User
    Join Date
    Jul 2003
    Posts
    61
    1) Setup a loop testing if c isn't EOF, then inside of the loop test if c is a blank.
    2) If c is a blank, continue fetching the chars until c is a non-blank.
    3) Print a single blank, and the non-blank c.

    Code:
    #include <stdio.h>
    int main()
    {
      int c;
    
      while( (c = getchar()) != EOF)
        {
          if(c == ' ')
    	{
    	  while( (c = getchar()) == ' ')
    	    ;
    	  putchar(' ');
    	}
          	putchar(c);
        }
    
      return 0;
    }
    HTH,
    Last edited by cc0d3r; 08-15-2003 at 09:56 AM.
    $ENV: FreeBSD, gcc, emacs

  5. #5
    Registered User
    Join Date
    Dec 2002
    Posts
    27
    But what if you get an EOF in the inner getch() ?
    Kaputt?


    EDIT: not getch(), getchar() :- )
    Last edited by C-learning; 08-15-2003 at 12:46 PM.
    "Can i really learn this? If i cant, why bother?"

  6. #6
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by Prelude
    You have to be careful not to print anything until all of the blanks have been taken in. Then you print a single blank and the next nonblank character. If there are no blanks, then you need to print every time. This logic really calls for an if..else if..else sequence:
    Code:
    /*
    * Copy input to output, compact whitespace
    */
    #include <stdio.h>
    
    int main(void)
    {
        int c;
        int done;
        int blank;
        
        done = 0;  
        blank = 0;
        
        while ( done == 0 )  // This can be simply changed to (!done)
        {
            c = getchar();
    
            if ( c == EOF )
                done = 1;
            else if ( c == ' ' )    
                {                          // close... add the following
                    if (blank == 0)  
                        putchar(c);
                }
    
                blank++;
            else if ( blank > 0 )    // remove these lines 
            {
                blank = 0;
                putchar( ' ' );
                putchar( c );
            }
            else
                blank = 0;    // move this line here 
                putchar( c );
        }
        
        return 0;
    }
    See, lots of ways to do this...

    Using your original concept, all you forgot is that you are looking for a space or not space. Only two conditions (3 if you consider the EOF)

    If not a space,
    -- print the char
    -- flag 'no space'
    If a space,
    -- if not flagged, output the space
    -- flag the space
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  7. #7
    Registered User
    Join Date
    Jul 2003
    Posts
    61
    Originally posted by C-learning
    But what if you get an EOF in the inner getch() ?
    Kaputt?


    EDIT: not getch(), getchar() :- )
    Hmm, it all depends on whether stdin is a file or the keyboard, if it's the former, everything will be printed as expected.
    OTOH, if you're entering from the keyboard, a garbage value will be displayed.

    To fix that add if(c!=EOF) before putchar(c); line.
    Last edited by cc0d3r; 08-15-2003 at 03:13 PM.
    $ENV: FreeBSD, gcc, emacs

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    As a function:

    Code:
    char * thin(char * dest, const char * source, char single)
    {
     char * s, * d = dest;
    
     int flag = 2;
    
      for(s = (char*)source; *s != 0; ++s)
     {
      if(*s == single)
       --flag;
      else
       flag = 2;
    
      if(flag > 0) *(d++) = *s;
     }
    
     *d = 0;
    
     return dest;
    }
    
    
    char * thin_space(char * dest, const char * source)
    {
     return thin(dest, source, ' ');
    } 
    
    int main()
    {
     char buffer[100] = "hello          world.";
    
     printf("%s", thin_space(buffer, buffer));
    
     return 0;
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >See, lots of ways to do this...
    Indeed. Just out of curiosity, were you correcting me or making a point to the OP? Hard to tell.
    My best code is written with the delete key.

  10. #10
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by Prelude
    >See, lots of ways to do this...
    Indeed. Just out of curiosity, were you correcting me or making a point to the OP? Hard to tell.
    Nope, I wasn't correcting you. More making a point. I simply preferred putting the multi-test within the Space test
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Why do you cast away the const of source here?

    Because it's rather hard to increment a contant pointer.

    >> source is no longer const at all...

    True. Ordinarily, 'source' *would* be constant, but I chose to use it as both 'source' and 'dest'.

    While it's true that overlapping the two seems risky, it's not as long as you design functions to handle it properly. In some cases, reverse copying or other approaches are necessary, but in this one, we know that 'dest' will always be shorter or equal to 'source'. Had the function been designed to EXPAND segments of the string, on the other hand, it would've needed a different design.

    Still, good points. : - )
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  12. #12
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    const char *p;
    p++ is allowed, *p++ isn't
    char * const p;
    p++ isn't allowed, *p++ is
    I think you may have this a little mixed up Salem:

    Given

    const char *p;
    p++ increments the pointer, all is well.
    *p++ increments the pointer, not the data pointed to because ++ has higher precedence than *.
    (*p)++ is not legal because the data pointed to is const.

    char *const p;
    p++ is illegal because it modifies a const pointer.
    *p++ is also illegal because it modifies a const pointer.
    (*p)++ is legal, the data pointed to is not const.
    My best code is written with the delete key.

  13. #13
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708

    Talking

    Whoops. I can't believe I said that.

    It's been a long week.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. my server program auto shut down
    By hanhao in forum Networking/Device Communication
    Replies: 1
    Last Post: 03-13-2004, 10:49 PM
  2. insufficient memory for tsr
    By manmohan in forum C Programming
    Replies: 8
    Last Post: 01-02-2004, 09:48 AM
  3. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  4. logic on a program
    By officegirl in forum C Programming
    Replies: 0
    Last Post: 10-13-2001, 10:41 PM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM