Thread: string not fully outputted when a type bool function is called.

  1. #1
    Registered User
    Join Date
    Jan 2005
    Posts
    14

    string not fully outputted when a type bool function is called.

    Hello, all.

    I don't like to post anything on boards, but I am stumped here.

    I have a program that will solicit a line of text from the user. It will then output the string later in the program (by passing a char * to a function).

    The trouble comes in when main() ALSO calls a certain function that returns a type bool variable. When that function is called, the string does not output fully!

    Please note that when I assign either 'true' or 'false' to the bool variable in main(), instead of getting the value from the return value of the type
    bool function, the string outputs just fine.

    What in the world could I possibly be missing?

    For any interested, here is the code, with all comments that I thought would be pertinent. Note that if you comment the line:

    use_num = use_number();
    and uncomment the line:
    use_num = true;

    Then the program runs fine. How could this seemingly unrelated function call break the output of the string?


    Code:
    // comparison.cpp
    // What changes the length of the string?
    
    #include <iostream>
    
    void get_a_string(char *);
    void print_a_string(char *, int i = 0);
    
    bool use_number(void);                          // This seems to be the "trouble causing" function, in that,
                                                    // when it is called, the string pointed to by 'pt_line'
                                                    // seems to decrease in length.
    
    int main(void)
    {
            using namespace std;
    
            char * pt_line = new char;              // Get memory to put the string of text in.
            get_a_string(pt_line);                  // Solicit the string of text from the user,
                                                    // and store it in the memory address pointed
                                                    // to by 'pt_line'.
    
            bool use_num;
            //=======================================================================================
            // We can get a value for the variable 'use_num' two different ways.
            //
            // If we use the return value of the function 'use_number(void)' as the value for
            // 'use_num', then the string pointed to by 'pt_line' does not output correctly.  Only
            // the first part of the line is outputted.
            //
            // If, however, we simply _assign_ a value to 'use_num', then the string IS outputted
            // correctly (its entire length is shown).
            //
            // So, uncomment out only ONE of the following lines of code, to make your choice.
            //=======================================================================================
            use_num = use_number();                 // This way will cause the program to print out only
                                                    // the first part of the string.
            //use_num = true;                       // This (other way) will cause the string to be
                                                    // properly outputted.
    
            print_a_string(pt_line);
    
            return 0;
    }
    
    // Remember, the function prototype for this function is this:
    //
    // void print_a_string(char *, int i = 0);
    //
    // The idea is, that if only a    char *    is passed to this function, then the line of text
    // pointed to by the     char *    will be outputted only ONCE.
    //
    // However, if a second argument, of type    int    is passed to this function as well, and
    // it has a non-zero value, then the string pointed to by the type    char *    argument
    // be outputted a number of times equal to the number of times the function has been called by
    // main().
    void print_a_string(char * pointer, int i)
    {
            using namespace std;
    
            static int times = 0;                                           // the number of times this function
                                                                            // has been called.
            times++;
    
            if(i == 0)
                    cout << pointer << endl;
            else
            {
                    int j = 0;
                    while(j < times)
                    {
                            cout << pointer << endl;
                            j++;
                    }
            }
    }
    
    void get_a_string(char * pointer)
    {
            using namespace std;
    
            cout << "Please enter a line of text:\n";
            char ch;
            int i = 0;
            while((ch = getchar()) != '\n')
            {
                    *(pointer + i) = ch;
                    i++;
            }
    }
    
    bool use_number(void)
    {
            using namespace std;
            string usr_in;
            cout << "Do you want to use a number? [Y/n] ";
            getline(cin, usr_in);
            while((usr_in.size() != 1 && usr_in.size() != 0) ||
                            (usr_in != "y" && usr_in != "Y" && usr_in != "n" && usr_in != "N" && usr_in.size() != 0))
            {
                    cout << "\t## size of input == " << usr_in.size() << endl;
                    cout << "Oh, c'mon now... Enter a y or an n...\n";
                    cout << "Do you want to use a number? [Y/n] ";
                    getline(cin, usr_in);
            }
            if(usr_in == "y" || usr_in == "Y" || usr_in.size() == 0)
                    return true;
            else if(usr_in == "n" || usr_in == "N")
                    return false;
            else
            {
                    cout << "Error in function use_number(), program is terminating...\n";
                    exit(EXIT_FAILURE);
            }
    }

  2. #2
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    The first thing I see is this:
    Code:
    char * pt_line = new char;              // Get memory to put the string of text in.
    get_a_string(pt_line);                  
    //...
    void get_a_string(char * pointer)
    {
            using namespace std;
    
            cout << "Please enter a line of text:\n";
            char ch;
            int i = 0;
            while((ch = getchar()) != '\n')
            {
                    *(pointer + i) = ch;
                    i++;
            }
    }
    Not good. You only allocate space for a single char, but you treat "pointer" in get_a_string as an array. Is there any reason you can't use getline?
    Code:
    void get_a_string(char pointer[256])
    {
       std::cout<<"Please enter a line of text:\n";
       std::cin.getline(pointer,256,'\n');
    }
    //or better yet (be sure to #include <string>):
    void get_a_string(std::string& str)
    {
      std::cout<<"Please enter a line of text:\n";
      getline(std::cin,str,'\n'); 
    }
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    14
    Thank you for your response, JaWib!

    I am working through the text C++ Primer Plus (Stephen Prata), and wanted to use dynamically allocated memory to store the string in.

    The reason why? Because I felt it would be the "right" way to do it (it just seems to be the "neatest" way).

    So,...

    I really screwed up when I put the line:

    Code:
    char * pt_line = new char;              // Get memory to put the string of text in.
    in. hmmm...
    I will have to look farther into how to dynamicallly allocate memory for a string in C++, then.

    Thank you.

  4. #4
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    That code needs some major reworking. That is a very nice mix of C and C++. I say pick one and go for it. I made some changes but it needs a re-write.
    Code:
    // comparison.cpp
    // What changes the length of the string?
    
    #include <iostream>
    #include <string>
    #include <cctype>
    #include <cstdio>
    
    using namespace std;
    
    void get_a_string(char *);
    void print_a_string(char *, int i = 0);
    
    bool use_number(void);                          // This seems to be the "trouble causing" function, in that,
                                                    // when it is called, the string pointed to by 'pt_line'
                                                    // seems to decrease in length.
    void ToUpper(string &toUp);
    
    int main(void)
    {
            using namespace std;
            
            //This is only allocating one char variable        
            //char * pt_line = new char;         
               
            char *pt_line = new char[50];           // Get memory to put the string of text in.
            get_a_string(pt_line);                  // Solicit the string of text from the user,
                                                    // and store it in the memory address pointed
                                                    // to by 'pt_line'.
    
            bool use_num;
            //==================================================  =====================================
            // We can get a value for the variable 'use_num' two different ways.
            //
            // If we use the return value of the function 'use_number(void)' as the value for
            // 'use_num', then the string pointed to by 'pt_line' does not output correctly.  Only
            // the first part of the line is outputted.
            //
            // If, however, we simply _assign_ a value to 'use_num', then the string IS outputted
            // correctly (its entire length is shown).
            //
            // So, uncomment out only ONE of the following lines of code, to make your choice.
            //==================================================  =====================================
            use_num = use_number();                 // This way will cause the program to print out only
                                                    // the first part of the string.
            //use_num = true;                       // This (other way) will cause the string to be
                                                    // properly outputted.
    
            print_a_string(pt_line);
    
            return 0;
    }
    
    // Remember, the function prototype for this function is this:
    //
    // void print_a_string(char *, int i = 0);
    //
    // The idea is, that if only a    char *    is passed to this function, then the line of text
    // pointed to by the     char *    will be outputted only ONCE.
    //
    // However, if a second argument, of type    int    is passed to this function as well, and
    // it has a non-zero value, then the string pointed to by the type    char *    argument
    // be outputted a number of times equal to the number of times the function has been called by
    // main().
    void print_a_string(char * pointer, int i)
    {
            using namespace std;
    
            static int times = 0;                                           // the number of times this function
                                                                            // has been called.
            times++;
    
            if(i == 0)
                    cout << pointer << endl;
            else
            {
                    int j = 0;
                    while(j < times)
                    {
                            cout << pointer << endl;
                            j++;
                    }
            }
    }
    
    void get_a_string(char * pointer)
    {
            using namespace std;
    
            cout << "Please enter a line of text:\n";
            //Maybe fgets?
            /*
            while((ch = getchar()) != '\n')
            {
                    *(pointer + i) = ch;
                    i++;
            }
            */
            fgets(pointer, 50, stdin);
    }
    
    bool use_number(void)
    {
            using namespace std;
            string usr_in;
            cout << "Do you want to use a number? [Y/n] ";
            getline(cin, usr_in);
            
            //Save some comparisons
            ToUpper(usr_in);
            
            //You don't need to check for size == 0 since if it doesn't == Y or N
            //then it is no good
            while(usr_in != "Y" && usr_in != "N")
            {
                    cout << "\t## size of input == " << usr_in.size() << endl;
                    cout << "Oh, c'mon now... Enter a y or an n...\n";
                    cout << "Do you want to use a number? [Y/n] ";
                    getline(cin, usr_in);
            }
            
            if(usr_in == "Y")
                    return true;
            if(usr_in == "N")
                    return false;
                    
            cout << "Error in function use_number(), program is terminating...\n";
            exit(EXIT_FAILURE);
            
    }
    
    void ToUpper(string &toUp)
    {
        //This makes a std::string uppercase
        for(size_t i = 0; i < toUp.length(); i++)
        {
            toUp[i] = toupper(toUp[i]);
        }
    }
    Woop?

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    14
    Oh, my!

    Thank you both!!!

    I now see how JaWiB gave me a "head's - up" about the string input!!!

    Yessir!

    And, thank you for your comments and feedback, too, prog-bman!

    Yes, I have only studied C, and some PERL and BASH. This C++ is all new to me. I have just now gotten to the point in the book where it is really getting into the C++ part, and Man, did it bog me down fast, but good!

    Yes, this C++ will take some time to learn, but, I will get it, that's for sure!

    Yes, I will have quite a bit to learn from this feedback!

    All the best!




    Robert

  6. #6
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Well. I have heard that is a good book. But when it comes to coding IMO it is best not to mix c-style functions and strings(char *) with C++ strings. Well without good reason. Plus C++ strings are way easier to manage
    Woop?

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    14
    Yes, thank you.

    I suppose that I will just have to "drive on", and get through this first C++ text in a "messy" way. That is, I may not completely understand all of the topics, but at least I will be exposed to them all.

    Then, I can go through another C++ text, and try to get another layer of the onion peeled off.

    In this manner, I will persist. Then, finally, with the understanding of the classes and objects and things (this knowlege _must_ be mine!), I will be well suited to study python, and java and all manner of other things!

    Here we go, then, ahead we go!

    Thanks again,



    Robert

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  3. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  4. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  5. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM