-2

I am working on a simple demographics program. Enter the data and output it to a csv file. I am having issue validating data input for the name. Validation works fine if enter just number but if I enter an alphanumeric string twice it does not work. For example, if I type Max1, I get the exception, if I type Max1 again, it just moves on to the next function call. However if I enter just a string of digits it will not move on until I enter a correct alpha only string or two alphanumerics strings

    #include <iostream>
    #include <vector>
    #include "People.h"

    int main()
    {
        const short elements = 2;
        PersonalData Demographics;
        std::string input;
        std::vector<std::string> response;

        for (int i = 0; i < elements; i++)
        {
            std::cout << "Please enter first name of child: " << i+1 << std::endl;
            std::cin >> input;
            response.push_back(input)
            Demographics.setName(response);
        }
        return 0;
    }

    People.hpp

#ifndef PEOPLE_H_INCLUDED
#define PEOPLE_H_INCLUDED
#include <vector>

    class PersonalData
    {
        private:
            std::vector<std::string> name;
        public:
            void setName(std::vector<std::string>&); //get the names of each person
    };

    #endif // PEOPLE_H_INCLUDED



People.cpp

#include <iostream>>
#include "People.h"
#include <vector>

    void PersonalData::setName(std::vector<std::string> &names)
    {
        string retry;
        bool valid=false; // we start by assuming that the entry is not valid
        std::string::const_iterator it;
        while(!valid) //start validation loop
        {
            for(int i=0; i <names.size(); i++)
            {
                 for(it = names[i].begin(); it != names[i].end(); ++it) //start loop to check type of each char in string
                {
                    if(isalpha(*it)) //if it is char set name to user names
                    {
                        name=names;
                        valid = true; //the entry was valid, jump out of loop
                    }
                    else //it was not just char, try again
                    {
                        std::cout << "Name should be alphabetic only.  Try again: " <<endl;
                        std::cin >> retry;
                        names.erase(names.begin()+i); // remove the bad non-alphabetic entry from the names array
                        names.push_back(retry);
                        break;
                    }
                }
            }
        }
    }
  • That entire loop could be replace with a `std::remove_if / erase` with a simple lambda. Also, why are you putting bad names in your vector to begin with? Why not do the checking up front before you place the name in the vector? – PaulMcKenzie Feb 21 '16 at 17:43
  • Ok, that makes sense. Just remove anything that is not an alpha character. Did not know the remove if option existed. I'm still pretty new as you can tell. Not sure what a lamda is but I can research it – NoiseyAgent Feb 21 '16 at 18:16

1 Answers1

0

Instead of trying to figure out the logic of your loop, I would recommend that you first test to see if the name is valid, and if it is, then add it to your vector of names. Your current code adds invalid names and then tries to remove them, which doesn't make too much sense.

The way to check if a name is valid (contains all alphabetic characters) is to use the std::all_of algorithm function:

#include <iostream>
#include <vector>
#include <ccytpe>
#include <algorithm>
//...
using namespace std;
int main()
{
    const short elements = 2;
    PersonalData Demographics;
    std::string input;
    std::vector<std::string> response;

    for (int i = 0; i < elements; i++)
    {
        bool input_good;
        do
        {
            std::cout << "Please enter first name of child: " << i+1 <<  std::endl;
            std::cin >> input;
            input_good = std::all_of(input.begin(), input.end(), ::isalpha);
            if ( !input_good )
               cout << "Sorry, bad input.  Try again...\n";
        } while (!input_good);
        response.push_back(input)
    }

    // now we know that all the names are valid.  Place in 
    // Demographics
    Demographics.setName(response);
    return 0;
}

void PersonalData::setName(std::vector<std::string> &names)
{
   name = names;  // simple
}

With the following, the input for a particular name doesn't get accepted until all of the characters are alphabetic. You no longer need a validation loop, as all of the names are valid that are placed in the vector.

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • Yes, this makes much more sense, thank you. I need to familiarize myself with the algorithm library, i did not know of all_of. – NoiseyAgent Feb 21 '16 at 19:14
  • I can't seem to get all_of to work. It keeps saying its not decalred in this scope even though I have the algorithm library included – NoiseyAgent Feb 21 '16 at 19:30
  • What compiler are you using? `std::all_of` is supported for C++ 11 compliant compilers. Here is a simple example: http://ideone.com/garzCb – PaulMcKenzie Feb 21 '16 at 19:35
  • GNU gcc with code::blocks ide. How do I check what I am using? – NoiseyAgent Feb 21 '16 at 19:39
  • g++ has a command-line option to check the version (I think it's `--version`). There is also an option to turn on C++11 compliancy http://stackoverflow.com/questions/16886591/how-do-i-enable-c11-in-gcc – PaulMcKenzie Feb 21 '16 at 19:39