Length command and variable not declared in scope

I wrote a program to test my skills in using classes and now I'm stuck. I'm basically doing input validation right now. The third do while loop is giving me some problems. I want it to only accept 4 digits for the year. I am trying to use the length() command. This statement:
 
} while (yearString.length() != 4); 

It's giving me: "dateProg.cpp:83:11: error: ‘yearString’ was not declared in this scope"
But I did declare it here:
 
std::string yearString = std::to_string(inputYear);

The only thing I can think of is that my data members for "setYear/getYear" are set to int right now, this may be causing a problem. I'm trying to use to_string in there as well as I can't figurte out a way of using length without using a string.

Also, I would like to know if there is a more elegant way of doing my input validation. I am using a local variable (i) and incrementing it so the "invalid month!" "Invalid Day!" only comes up once. How else would I have the "input Day" prompt, for instance come up everytime, then the "Invalid Day" prompt come up only when invalid? I feel I'm using a workaround, but it works.
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <cstdlib>


class Date {
	private: 
	int month;
	int day;
	int year;
	public:
	void setMonth(int);
	void setDay(int);
	void setYear(int);
	int getMonth();
	int getDay();
	int getYear();
};

void Date::setMonth(int m)
{
	month = m;
}
void Date::setDay(int d)
{
	day = d;
}
void Date::setYear(int y)
{
	year = y;
}
int Date::getMonth()
{
	return month;
}
int Date::getDay()
{
	return day;
}
int Date::getYear()
{
	return year;
}


int main() {
	
	Date dateInput;
	int inputMonth;
	int inputDay;
	int inputYear;
	do{
	int i = 0;
	std::cout << "Input Month " << std::endl;
	std::cin >> inputMonth;
	
	if (i > 0) {
	std::cout << "Invalid month!" << std::endl;
}
	i++;
	} while (inputMonth < 1 || inputMonth > 12);

	do{
	int i = 0;
	std::cout << "Input Day " << std::endl;
	std::cin >> inputDay;
	
	if (i > 0) {
	std::cout << "Invalid day!" << std::endl;
}
	i++;
	} while (inputDay < 1 || inputDay > 31);
		
	do{
	int i = 0;
	std::cout << "Input year" << std::endl;
	std::cin >> inputYear;
	std::string yearString = std::to_string(inputYear);
	//std::string countString = yearString.length();
	
	if (i > 0) {
	std::cout << "Invalid Year" << std::endl;
	}	
	i++;
	} while (yearString.length() != 4); // THIS IS MY PROBLEM

	//std::cout << "Input Year " << std::endl;
	//std::cin >> inputYear;
	
	dateInput.setMonth(inputMonth);
	dateInput.setDay(inputDay);
	dateInput.setYear(inputYear);
	
	std::cout << "The date is: " << dateInput.getMonth() << "/" << dateInput.getDay() << "/" << dateInput.getYear() << std::endl;
	
	
	return EXIT_SUCCESS;
	
}



Thanks in advance!
Variables declared inside the do-while loop are unfortunately out of scope in the loop condition.

You have to declare yearString outside the loop.
1
2
3
4
5
6
std::string yearString;
do {
	...
	yearString = std::to_string(inputYear);
	...
} while (yearString.length() != 4);
Last edited on
Ok, I did not know that, thanks! It is compiling now but the year validation is doing an infinite loop, even when I put in a 4 digit number. Could this be where me using int's for my classes, setters and getters might be causing the problem?
Oh wait. Would I have to put all this validation outside the loop since it doesnt have scope access to it? I guess I could create a function maybe?
Inside the loop, make sure that you assign to the string that you created outside the loop.

 
std::string yearString = std::to_string(inputYear);
Last edited on
OMG! I never would have thought that putting std::string in front of it would make that big of a difference! Thank you! - If I could ask one more thing. Why? Why does that make such a big difference?
By C++ syntax,

(Type) (VariableName) = (Data); is declaring a new variable and initializing it with data

(VariableName) = (Data); is assigning data to a variable that ought to already exist.

When a declared parameter in an inner scope has the same name as the outer scope, it's called "shadowing" a variable -- a new variable is created, which has nothing to do with the former variable declared in an outer scope -- and it's best to avoid doing this.
https://en.wikipedia.org/wiki/Variable_shadowing
Last edited on
Ok Ganado, thanks for the response. So that wikipedia article basically says it is just confusing and bad practice.

- In my code how else could I do what I'm trying to do without shadowing?

"shadowing" was how you had it before. The yearString variable inside the loop shadowed the yearString variable that was declared outside the loop. After you removed std::string inside the loop there is only one variable named "yearString" and hence no shadowing.
Last edited on
Oh ok. Thanks!!
Do you really need a string?
1
2
3
4
int year = 0;
while ( std::cin >> year && !(999 < year && year < 10000) ) {
  std::cout << "Invalid Year\n";
}
Topic archived. No new replies allowed.