Logic Error?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
using namespace std;

const int LAST_NAME_LENGTH = 15;

string ReadAndValidateUserLastName (string userLastName);

int main ()
{
	string userLastName;

	ReadAndValidateUserLastName (userLastName);

	system ("PAUSE");
	return 0;
}

string ReadAndValidateUserLastName (string userLastName)
{
	bool check = false;

	while (!check)
	{
		check = true;

		cout << "Enter Last Name: ";
		cin >> userLastName;

		if (userLastName.length () > LAST_NAME_LENGTH)
		{
			check = false;
		}
		
		for (unsigned int i = 0; i < userLastName.length(); i++)
		{
			if (!isalpha (userLastName [i]) || isspace (userLastName [i]))
			{
				check = false;
			}
		}

		if (!check)
		{
			cout << "Invalid Entry! Please try again." << endl;
		}
	}

	return userLastName;
}


My biggest error is when I try to check for spaces. I am attempting to validate a last name string. Last name can be up to 15 characters, all alphabetical, with no spaces. I can't seem to figure out how to get the spaces to get caught and flag them with the error...
1
2
3
4
5
if(userLastName==' ' || !isalpha(userLastName[i]))
{
check=false;
break;
}


Also at
1
2
3
4
5
6
if (userLastName.length () > LAST_NAME_LENGTH)
		{
			check = false;
cout << "Invalid Entry! Please try again." << endl;
continue;
		}
Last edited on
I don't think that works Arkshit. The break in your first piece of code will break the while (!check), so an invalid name would be returned. The continue will ignore the rest of the loop and then loop again, so you never see the "Invalid Entry".

A space is a non-alpha, so you don't need to check "isspace()".

Actually, you wont be able to store a space in your string at all, you're using >> to extract (which stops at white space). Use getline(cin, userLastName); instead of what you have at line 32.
Last edited on
Actually, you wont be able to store a space in your string at all, you're using >> to extract (which stops at white space). Use getline(cin, userLastName); instead of what you have at line 32.


Yes thats true and haven't saw that.

And LowestOne my code is going to work(if he have spaces included or not).I just need to insert one more line which is non logic related.and break will break for loop not while one

The code I want him to use is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void ReadAndValidateUserLastName (string &userLastName)
{
	bool check = false;

	while (!check)
	{
		check = true;

		cout << "Enter Last Name: ";
		getline(cin, userLastName);

		if (userLastName.length () > LAST_NAME_LENGTH)
		{
			check = false;
                        cout << "Invalid Entry! Please try again." << endl;
                        continue;
		}
		
		for (unsigned int i = 0; i < userLastName.length(); i++)
		{
			if (!isalpha (userLastName [i]) || isspace (userLastName [i]))
			{
				check = false;
                                break;
			}
		}

		if (!check)
		{
			cout << "Invalid Entry! Please try again." << endl;
		}
	}
}
Last edited on
I do understand the getline instead of >>. Thank you for catching that.
However, Akshit I cannot use break or continue at all.
I cannot use break or continue at all.


you cannot use them or you don't know them? they are extremely useful.

and >> gets input till a white space is encountered(Enter,tab,space).
while getline takes input till specific character(by default enter) is encountered.
You have to get a little tricky to not use a break:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void validateLastName(string& name)
{
  int i;
  cout << "Enter your last name: ";
  do
  {
    getline(cin, name);
    for (i = 0; i < LAST_NAME_LENGTH && i < string.length() && isalpha(string.at(i)); i++)
      ;  // Keep looping
    if (i != string.length())
      cout << "You name can only be letters and must  be less than " << LAST_NAME_LENGTH << " characters long.  Try again: ";
  }
  while (i != string.length());
}

Last edited on
No, we are not ALLOWED to use break or continue to exit out of a loop. Class rules. :/
This is what I have come up with...so far...from my test case it has worked, but I am not sure if I am missing anything. Feel free to take a look and let me know if you see any issues
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
string ReadAndValidateUserSocial (string userSocial)
{
	bool check = false;

	while (!check)
	{
		check = true;

		cout << "Enter Social Security Number (###-##-####): ";
		cin >> userSocial;

		if (userSocial.length () != SSN_LENGTH)
		{
			check = false;
		}
		
		if (userSocial [3] != '-' && userSocial [6] != '-')
		{
			check = false;
		}
		else
		{
			userSocial = userSocial.replace (3, 1, "");
			userSocial = userSocial.replace (5, 1, "");

			for (int i = 0; i < userSocial.length(); i++)
			{
				if (!isdigit (userSocial [i]))
				{
					check = false;
				}
			}
		}
		
		if (!check)
		{
			cout << "Invalid Entry! Please try again." << endl;
		}
	}
	
	return userSocial;
}

string ReadAndValidateUserLastName (string userLastName)
{
	bool check = false;

	while (!check)
	{
		check = true;

		cout << "Enter Last Name: ";
		getline (cin, userLastName);

		if (userLastName.length () > LAST_NAME_LENGTH)
		{
			check = false;
		}
		
		for (unsigned int i = 0; i < userLastName.length(); i++)
		{
			if (!isalpha (userLastName [i]) || isspace (userLastName [i]))
			{
				check = false;
			}
		}

		if (!check)
		{
			cout << "Invalid Entry! Please try again." << endl;
		}
	}

	return userLastName;
}
Eh...this isn't quite working...while the error checking looks correct for all tests I am applying...
I have also tried to add

 
toupper (userLastName [0]);


to make sure that the first letter of the last name is upper case...and its not quite reading it...i am going to have to play with this a little more..
any suggestions?

This is my second course in C++ programming, but i have to admit, i am not too familiar with toupper or string manipulation yet. Maybe i am doing something wrong?
what actually is going wrong now?
Nothing now :) i figured the last part out.
My intention above (After figuring out how to error check the last name entered by the user) was to convert the first letter to upper case. I jsut figured that out.

Now..if anyone would like to put their input in haha, i am attempting to create the same type of error checking function to validate a phone type...here is the information that i have coded so far, followed by the instructions on how to validate. I haven't gotten that far, so it will take me a few minutes to add enough code to show you that I am still doing it myself rather than asking for an answer...but in case you feel like having an idea before i submit my idea :)

1
2
3
4
5
6
7
8
9
10
11
// enumerated types
enum PhoneType {HOME, WORK, CELL};

// struct
struct RecordType
{
	string socialSecurityNumber;
	string lastName;
	string phoneNumber;
	PhoneType typePhone;
};


Phone type enumerated type
Options for enumerated type are: HOME, WORK, CELL
(define them in this order, so their ordinal values will be
HOME = 0, WORK = 1, and CELL = 2 when saved to the data file).
NOTE: When refering to enumerated values in the program, the code should never use the ordinal
values. It should always use the HOME, WORK, CELL values.

Verify that a valid value is entered for phone type
(make sure your program tells the user what the choices are,
and how to enter the correct value).
This is my idea so far:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
PhoneType ReadAndValidateUserPhoneType (PhoneType userTypePhone)
{
	bool check;

	while (!check)
	{
		cout << "Enter Phone Type:" << endl;
		cout << "[H]ome" << endl;
		cout << "[W]ork" << endl;
		cout << "[C]ell" << endl;
		cin >> (char&) userTypePhone;

		userTypePhone = toupper (userTypePhone);

		if (userTypePhone == 'H')
		{
			userTypePhone = 0;
		}
		else if (userTypePhone == 'W')
		{
			userTypePhone = 1;
		}
		else if (userTypePhone == 'C')
		{
			userTypePhone = 2;
		}
		else
		{
			cout << "Invalid Entry! Please try again." << endl;
		}

	return userTypePhone;
}


Issue so far:
when i set userTypePhone equal to ANYTHING i see this error:
"Error: a value of type int cannot be assigned to an entity of PhoneType"

Not sure how to fix something like that though...im not quite sure what the error means to be honest.
NOTE: When refering to enumerated values in the program, the code should never use the ordinal
values. It should always use the HOME, WORK, CELL values.
So I should not be setting the userTypePhone equal to it's ordinal value at all? How will the program know (when I go to save the use input to a file) to convert HOME, WORK, or CELL to it's ordinal value?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
using namespace std;

const int LAST_NAME_LENGTH = 15;

// enumerated types
enum PhoneType {HOME, WORK, CELL};

// struct
struct RecordType
{
	string socialSecurityNumber;
	string lastName;
	string phoneNumber;
	PhoneType typePhone;
};

string ReadAndValidateUserPhoneType (string userTypePhone);

int main ()
{
	string userTypePhone;

	ReadAndValidateUserPhoneType (userTypePhone);

	system ("PAUSE");
	return 0;
}

string ReadAndValidateUserPhoneType (string userTypePhone)
{
	bool check;

	while (!check)
	{
		cout << "Enter Phone Type:" << endl;
		cout << "[H]ome" << endl;
		cout << "[W]ork" << endl;
		cout << "[C]ell" << endl;
		cin >> userTypePhone;

		userTypePhone = toupper (userTypePhone);

		if (userTypePhone == "H")
		{
			userTypePhone = "HOME";
		}
		else if (userTypePhone == "W")
		{
			userTypePhone = "WORK";
		}
		else if (userTypePhone == "C")
		{
			userTypePhone = "CELL";
		}
		else
		{
			cout << "Invalid Entry! Please try again." << endl;
		}
	}

	cout << userTypePhone << endl;

	return userTypePhone;
}


So is this correct then? I should keep it as a string? I just don't understand how to do the conversion later on I guess...to make the string userPhoneType = PhoneType typePhone
Topic archived. No new replies allowed.