Thread: A little help here

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

    A little help here

    I've always had this "thing" for the C programming language but because I was never able to validate user input with it, I went with C++ lol. Anyway, I've decided to give it another go, especially now that I am learning about the Win32 API and I want you guys to help me with something. I wrote this program in C++ (it is not completed yet but is a perfect example of what I want to accomplish in C) and I was wondering if someone could write a C version of it. Here's my program:
    Code:
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <vector>
    
    bool validate_number_of_names(const std::string &);
    bool validate_name(const std::string &);
    bool validate_sort_type(const std::string &);
    bool length_and_spaces(const std::string &);
    
    int main()
    {
        int number_of_names;
        std::string user_input;
        std::string name;
        std::vector<std::string> all_names;
        std::string sort_type;
        
        do{
            std::cout << "Number of names: ";
            std::getline(std::cin, user_input);
        }while(!validate_number_of_names(user_input));
        
        system("cls");
        
        std::istringstream iss(user_input);
        iss >> number_of_names;
        
        std::cout << "Now, start inputing the names. They have to be in the format\n"
                  << "\"last, first, age\" with no spaces and the name string cannot\n"
                  << "exceed 40 characters.\n\n";
                  
        while(number_of_names != 0){
            do{
                std::cout << "Name: (" << number_of_names << " left) ";
                std::getline(std::cin, name);
            }while(!validate_name(name));
            
            all_names.push_back(name);
            
            number_of_names--;
        }
        
        do{
            std::cout << "\nThe names can be sorted by either last, first or age. How\n"
                         "would you like them to be sorted? ";
                         
            std::getline(std::cin, sort_type);
        }while(!validate_sort_type(sort_type));
                  
        std::cin.get();
        
        return 0;
    }
    
    bool validate_number_of_names(const std::string &user_input)
    {
         int number_of_names;
         int length_of_user_input;
         
         length_of_user_input = user_input.length();
         
         for(int i = 0; i != length_of_user_input; i++){
             if(!isdigit(user_input[i])){
                 std::cout << "Invalid entry.\n\n";
                 return false;
             }
         }
         
         std::istringstream iss(user_input);
         iss >> number_of_names;
         
         if(number_of_names > 100){
             std::cout << "Number of names must be between 1 and 100.\n\n";
             return false;
         }
         
         return true;
    }
    
    bool validate_name(const std::string &name)
    {
         int i;
         int comma;
         int result;
         int second_comma;
         int comma_count = 0;
         int number_of_characters;
         std::string age;
         std::string last_name;
         std::string first_name;
         std::string last_and_first_names;
         
         if(!length_and_spaces(name))
             return false;
             
         number_of_characters = name.length();
             
         for(i = 0; i != number_of_characters; i++){
             if(name[i] == ','){
                 comma_count++;
             }
         }
         
         if((comma_count < 2) || (comma_count > 2)){
             std::cout << "Invalid entry.\n\n";
             return false;
         }
             
         second_comma = name.find_first_of(',', name.find_first_of(',') + 1);
         
         last_and_first_names = name.substr(0, second_comma);
         
         comma = last_and_first_names.find_first_of(',');
         
         last_name = last_and_first_names.substr(0, comma);
         
         first_name = last_and_first_names.substr(comma + 1);
         
         age = name.substr(name.rfind(',') + 1);
         
         if(!length_and_spaces(last_name))
             return false;
             
         if(!length_and_spaces(first_name))
             return false;
             
         if(!length_and_spaces(age))
             return false;
             
         for(int i = 0; i != number_of_characters; i++){
             if(last_and_first_names[i] != ','){
                 if(!isalpha(last_and_first_names[i])){
                     std::cout << "Invalid entry.\n\n";
                     return false;
                 }
                 
                 return true;
             }
         }
             
         return true;
    }  
         
    bool validate_sort_type(const std::string &sort_type)
    {         
         if((sort_type != "last") && (sort_type != "first") && (sort_type != "age")){
             std::cout << "Invalid entry.\n";
             return false;
         }
         
         return true;
    }
    
    bool length_and_spaces(const std::string &foo)
    {
         int number_of_characters;
         
         number_of_characters = foo.length();
         
         if(number_of_characters == 0){
             std::cout << "Invalid entry.\n\n";
             return false;
         }
         
         for(int i = 0; i != number_of_characters; i++){
             if(isspace(foo[i])){
                 std::cout << "Invalid entry.\n\n";
                 return false;
             }
         }
         
         return true;
    }
    Thanks.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Someone want to move this over to the C++ board where it belongs?

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

  3. #3
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Quote Originally Posted by caduardo21
    I wrote this program in C++...and I was wondering if someone could write a C version of it.
    Yes, someone could. However, I doubt someone will. If you show us your attempt, we'll help you with it. If you ask a better question, we can try to answer it.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    *chuckle* I suppose I should have read that blurb at the top. I just saw a pile of C++ code and gave it the boot. At any rate, you've answered it well. But I'll be generous, and point the origional poster along the way to go:

    1) Convert the string class usage to C string functionality. Consider reading up on the <string.h> functions. You'll also want to cover things like malloc and free, and what not.

    2) Convert all of the iostream functions over to standard C functions such as printf, fgets and the like.

    3) Create yourself something along the lines of your vector class by writing something like a handy linked list.

    That'll get you started. Check back here when you've got that out of the way if you're still stuck.

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

  5. #5
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    As for boolean usage, try using an enumerator:
    Code:
    typedef enum {
        false,
        true
    } bool;
    
    bool myBoolean = true;
    if(myBoolean == true)
        puts("God bless America!");
    else  // false
        puts("God bless America!...#2");
    
    // NOT VALID Like in C++:
    if(myBoolean)
        puts("The above does not work out");
    else
        puts("My name is spaghetti man");
    Last edited by Kleid-0; 01-26-2005 at 05:19 PM. Reason: Dave's right

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    204
    Thanks guys. Thinking about it now, I was kinda silly but now I'll at least try and come back here when I run into problems.

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by Kleid-0
    As for boolean usage, try using an enumerator:
    Code:
    typedef enum {
       true,
       false
    } bool;
    Doesn't it seem rather counterintuitive for true to be 0 and false to be 1? Wouldn't that make more sense the other way around?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    You're right Dave, I learn something every 5 minutes hanging out here! Do you guys like my new programming style?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    // Boolean enumerator
    typedef enum
    {
      false,
      true
    } bool;
    
    // MAIN -- START
    int main (void)
    {
      // b1 is the first boolean value
      // b2 is the second boolean value
      bool b1 = true, b2 = false;
    
      // Check if the first boolean value is correct
      if (b1)
        puts ("Good!");
      else
        puts ("Bad!");
    
      // Check if the second boolean value is correct
      if (!b2)
        puts ("Good!");
      else
        puts ("Bad!");
    
      return 0;
    }

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    204
    Here's my first try:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    int validate_number_of_names(const char[]);
    
    int main()
    {
        char number_of_names[4];
    
        do{
            printf("Number of names: ");
            fgets(number_of_names, sizeof(number_of_names), stdin);
        }while(validate_number_of_names(number_of_names) == 1);
    
        return 0;
    }
    
    int validate_number_of_names(const char number_of_names[])
    {
        int i;
        int length_of_user_input;
    
        length_of_user_input = strlen(number_of_names);
    
        for(i = 0; i != length_of_user_input; i++){
            if(!isdigit(number_of_names[i])){
                printf("Invalid entry.\n\n");
                return 1;
            }
        }
    
        return 0;
    }
    The problem is, even if I input a valid numerical character, I get the error message. I think this is happening because the string is terminated with a \0 or \n, not sure which one though. Can somebody tell me how to get around this? Thanks.

  10. #10
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by caduardo21
    I think this is happening because the string is terminated with a \0 or \n, not sure which one though. Can somebody tell me how to get around this? Thanks.
    Probably the '\n'. Have you been to the FAQ?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    204
    Ok, this is what I have now:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    int validate_number_of_names(const char *);
    
    int main()
    {
        char number_of_names[4];
    
        do{
            printf("Number of names: ");
            fgets(number_of_names, sizeof(number_of_names), stdin);
            number_of_names[strlen(number_of_names) - 1] = '\0';
        }while(validate_number_of_names(number_of_names) == 1);
    
        return 0;
    }
    
    int validate_number_of_names(const char *number_of_names)
    {
        int i;
    
        if(number_of_names[0] == '\0'){
            printf("Invalid entry.\n\n");
            return 1;
        }
    
        for(i = 0; i != strlen(number_of_names); i++){
            if(!isdigit(number_of_names[i])){
                printf("Invalid entry.\n\n");
                return 1;
            }
        }
    
        return 0;
    }
    If I type 876t, for example, the program accepts the input, and that is not good. If I type uu8, things get even worse:
    Code:
    Number of names: uu8
    Invalid entry.
    
    Number of names: Invalid entry.
    
    Number of names:
    What is wrong now?

  12. #12
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    fgets() sucks up the '\n' character when you hit enter from the last fgets(). You want a sponge to suck up that '\n'! And I've got the code to fix that puppie up!
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    int validate_number_of_names(const char *);
    
    int main()
    {
        char number_of_names[4];
        int c;
    
        do{
            printf("Number of names: ");
            fgets(number_of_names, sizeof(number_of_names), stdin);
            while((c=getchar()) != EOF && c != '\n');
            number_of_names[strlen(number_of_names) - 1] = '\0';
        }while(validate_number_of_names(number_of_names) == 1);
    
        return 0;
    }
    
    int validate_number_of_names(const char *number_of_names)
    {
        int i;
    
        if(number_of_names[0] == '\0'){
            printf("Invalid entry.\n\n");
            return 1;
        }
    
        for(i = 0; i != strlen(number_of_names); i++){
            if(!isdigit(number_of_names[i])){
                printf("Invalid entry.\n\n");
                return 1;
            }
        }
    
        return 0;
    }

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    204
    I'm afraid the changes you made didn't fix the problems. Instead, it added some more
    I had to hit enter twice in order to get the my input into the program and things like 876t were still being accepted.

  14. #14
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    fgets only receives 3 characters.
    You could type:
    9279837496297634
    And you only get "927".

    You could type:
    827iuusdflnsclhLKHJLKHERB
    And you could only get:
    "827"

    fgets() has to ignore the rest of the characters because it only gets the amount that you asked for (3) characters + '\0' at the end.

  15. #15
    ---
    Join Date
    May 2004
    Posts
    1,379
    Code:
    while((c=getchar()) != EOF && c != '\n');
    /* wont work because fgets() recieves the '\n' 
        try this calling this function after using fgets() */
    
    void flush_newline(char *swap)
    {
      char ch;
      int i;
      for(i=0;i<sizeof(swap);i++){
        ch = swap[i];
        if(ch == '\n')
            swap[i] = '\0';
      } 
    }

Popular pages Recent additions subscribe to a feed