Thread: Is this programming exercise possible (don't answer with code, just is it possible?)

  1. #16
    Registered User
    Join Date
    Nov 2011
    Posts
    161
    Quote Originally Posted by Matticus View Post
    So did the suggestions I offered give you any ideas for solving this problem?
    The entire source for my solution is 20 lines (including declarations and whitespace).
    Not really, because my understanding of cin is that reads the input from the keyboard (standard) after the enter/return key is pressed.
    Then it has to loop and get another line and loop through it counting and looking for 'done' while ignoring words after 'done'.
    So while getline is a member function of the istream class of which cin is an object of that class. I did use getline.

  2. #17
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Using getline is tripping you up here. The (usually undesirable but in this case useful) default behavior of cin is to read up until the first whitespace:

    Code:
    #include <iostream>
    
    int main()
    {
        char s[64];
    
        std::cout << "Enter a line of text:\n";
        std::cin >> s;
    
        std::cout << "\nYou entered: " << s << std::endl;
    }
    Code:
    Enter a line of text:
    one two three
    
    You entered: one
    Anything not read remains on the buffer. You can use additional reads to continue taking (whitespace delimited) words from the input buffer:

    Code:
    #include <iostream>
    
    int main()
    {
        char s1[64];
        char s2[64];
        char s3[64];
    
        std::cout << "Enter a line of text:\n";
        std::cin >> s1;
        std::cin >> s2;
        std::cin >> s3;
    
        std::cout << "\nYou entered:"
                  << "\n> " << s1
                  << "\n> " << s2
                  << "\n> " << s3 << std::endl;
    }
    Code:
    Enter a line of text:
    one two three
    
    You entered:
    > one
    > two
    > three
    Newlines are considered whitespace, so the same rules apply whether you enter a single line or three separate lines:

    Code:
    Enter a line of text:
    one
    two
    three
    
    You entered:
    > one
    > two
    > three
    The second program expects three words, whether they are separated by spaces or newlines (i.e. on separate lines).

    So the notion of "lines" isn't really relevant in this situation. As long as there are more reads waiting to be executed, words will be extracted one at a time, whether separated by spaces or newlines. How do you continue calling cin to read the next word? Loop.

  3. #18
    Registered User
    Join Date
    Nov 2011
    Posts
    161

    Lightbulb

    Quote Originally Posted by Matticus View Post
    Using getline is tripping you up here. The (usually undesirable but in this case useful) default behavior of cin is to read up until the first whitespace:
    ...

    Anything not read remains on the buffer. You can use additional reads to continue taking (whitespace delimited) words from the input buffer:

    ...

    Newlines are considered whitespace, so the same rules apply whether you enter a single line or three separate lines:


    So the notion of "lines" isn't really relevant in this situation. As long as there are more reads waiting to be executed, words will be extracted one at a time, whether separated by spaces or newlines. How do you continue calling cin to read the next word? Loop.

    Ah, ha! thank you Matticus. The old noobie trip-up of whitespace on the buffer.
    Your lesson cleared things up, thanks so much.

    Here is the resulting code that works like it should:

    Code:
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    
    int main(int argc, const char * argv[]) {
        int numwords = 0;
        cout << "Give me a line:" << endl;
        char line[80];
        do {
            cin >> line;
            cin.get();
            numwords++;
        }while(strcmp("done",line));
        
        cout << "You entered a total of : "<< --numwords << " words!" << endl;
       
        return 0;
    }
    Is this similar to your code? Any corrections?

    Thanks again.

  4. #19
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Well you shouldn't need that cin.get(), and your "cin >> line" should be:

    Code:
    #include <iomanip>
    
    ...
    
    int main() { // You're not using any arguments so use this main().
    
    ...
    
            cin >> setw(80) >> line; // Never try to retrieve a line where you don't limit the number of characters accepted.
    ...
    Jim
    Last edited by jimblumberg; 10-04-2017 at 10:06 AM. Reason: Added missing )

  5. #20
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by FloridaJo View Post
    Ah, ha! thank you Matticus. The old noobie trip-up of whitespace on the buffer.
    Your lesson cleared things up, thanks so much.

    ...

    Is this similar to your code? Any corrections?

    Thanks again.
    Well done! Almost exactly like the first draft of my version. I later modified it by calling cin once before the loop, and using while instead of do-while. This removed the need to decrement the word count, making the code a little bit neater IMO.

    Code:
    #include <iostream>
    #include <cstring>
    
    int main()
    {
        char s[64];
        int count = 0;
    
        std::cout << "Enter words (to stop, type the word done):\n";
        std::cin >> s;
    
        while(strcmp(s, "done") != 0)
        {
            ++count;
            std::cin >> s;
        }
    
        std::cout << "\nYou entered a total of " << count << " words." << std::endl;
    }
    Jim is right about limiting the input - I didn't include this as the program was for proof of concept.

  6. #21
    Registered User
    Join Date
    Nov 2011
    Posts
    161
    Quote Originally Posted by Matticus View Post
    Well done! Almost exactly like the first draft of my version. I later modified it by calling cin once before the loop, and using while instead of do-while. This removed the need to decrement the word count, making the code a little bit neater IMO.

    Code:
    #include <iostream>
    #include <cstring>
    
    int main()
    {
        char s[64];
        int count = 0;
    
        std::cout << "Enter words (to stop, type the word done):\n";
        std::cin >> s;
    
        while(strcmp(s, "done") != 0)
        {
            ++count;
            std::cin >> s;
        }
    
        std::cout << "\nYou entered a total of " << count << " words." << std::endl;
    }
    Jim is right about limiting the input - I didn't include this as the program was for proof of concept.
    Yes, yours is much neater, that --numword didn't feel clean.
    And yes, Jim that makes sense. (but setw() wasn't covered yet, but thanks anyway for that)..

    thanks again guys.
    On to the next speed bump....

  7. #22
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    And yes, Jim that makes sense. (but setw() wasn't covered yet, but thanks anyway for that)..
    So? If you can't use setw() (just because it hasn't been covered is a bad reason to use unsafe methods) then I recommend using getline() with the optional third parameter to retrieve your string.

    Code:
    const size_t String_size 80;
    char s[String_size];
    cin.getline(s,  String_size, ' ');
    This should be basically the same as using the extraction operator.

    Jim

  8. #23
    Registered User
    Join Date
    Nov 2011
    Posts
    161
    Quote Originally Posted by jimblumberg View Post
    So? If you can't use setw() (just because it hasn't been covered is a bad reason to use unsafe methods) then I recommend using getline() with the optional third parameter to retrieve your string.
    In the spirit of learning, I think using tools not yet covered is meant to teach tools that might not otherwise be covered. Hence, not being able to use if/else && etc. As in this example, it forced me to learn cin better (thanks Matticus for that).


    Code:
    const size_t String_size 80;
    char s[String_size];
    cin.getline(s,  String_size, ' ');
    This should be basically the same as using the extraction operator.

    Jim

    Good option.

  9. #24
    Registered User
    Join Date
    Nov 2011
    Posts
    161
    eh, hem, actually while that works, now that I read the problem again, it says "uses an array of char and a loop to read one word at a time"

    The next problem asks you to use Strings.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 23
    Last Post: 10-01-2017, 03:55 PM
  2. Need help with C programming exercise.
    By dnguyen8 in forum C Programming
    Replies: 7
    Last Post: 10-08-2013, 08:05 PM
  3. C Programming Language Exercise
    By serg_yegi in forum C Programming
    Replies: 17
    Last Post: 11-30-2010, 04:36 AM
  4. c programming exercise
    By Pulock2009 in forum C Programming
    Replies: 3
    Last Post: 10-30-2009, 02:48 AM
  5. programming exercise
    By mashour06 in forum C Programming
    Replies: 1
    Last Post: 06-01-2009, 06:22 AM

Tags for this Thread