stack around the variable was corrupted

What I'm trying to do is the validation needed by prompting a message if the user entered a name which is more than the required array size. I did it but I dun know how to settle stack around the variable was corrupted issue. Any idea to solve this issue?

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
#include <iostream>
using namespace std;

int main()
{
	char name[10];
	bool valid = false;

	do
	{
		cout << "Enter your name: ";
		cin >> name;
		//cin.getline(name,10);

		if (strlen(name) >= 10)
			valid = false;
		else
			valid = true;

		if (valid == false)
			cout << "Invalid input. Please input again..." << endl << endl;

	}while (valid == false);
	

	cout << "Your name: " << name << endl;
	cout<< endl;

	cout << "Press Enter to exit program...";
	cin.get();
	cin.get();
If the name is more than 9 characters long, you are writing to memory that doesn't belong to you.

Solution: do not use character arrays for strings. Just don't. Don't. That means 'do not'.

Instead, use the class designed for the job:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <limits>
#include <string>

int main()
{
    std::string name;
    std::cout << "Enter your name, even if it is very long or contains spaces: " << std::flush;
    std::getline(std::cin, name);

    std::cout << "Your name is \"" << name << "\" and is " << name.length() << " characters long." << std::endl;

    std::cout << "Press Enter to exit the program..." << std::flush;
    std::cin.ginore(std::numeric_limits<std::streamsize>::max(), '\n');
}
But I'm forced to use character arrays for strings as my practical question.
1
2
3
4
5
6
7
8
9
10
11
char name[10];

// ...

cout << "Enter your name: ";

// cin >> name; // do not do this, you have trouble 
// if the user enters more than 9 characters

cin.getline( name, sizeof(name) ) ; // instead, use getline()
// see http://www.cplusplus.com/reference/istream/istream/getline/ 
Last edited on
I'm forced to use character arrays

Could just limit the size of input: cin >> setw(10) >> name; although getline() is also better in that it allows spaces.
I cannot perform validation anymore after I apply either cin.getline() or setw().
1
2
3
4
5
6
7
8
9
char name[ 10 + 1 ] ; // add space for one extra char
cout << "Enter your name (max 9 characters including spaces): ";
cin.getline( name, sizeof(name) ) ; 

if( strlen(name) > 9 ) { /* error */ }

// or
if( std::cin.gcount() > 9 ) { /* error */ }
// see: http://www.cplusplus.com/reference/istream/istream/gcount/ 
Last edited on
I cannot perform validation anymore after I apply either cin.getline() or setw().

Are you referring to

1
2
3
4
char name[10];
...
if (strlen(name) >= 10)
    valid = false;

?

That's not really validating anything. strlen(name) can only become equal or greater than 10 if you made an error in your program.

Use getline, it will let you know if the input didn't fit in the target array:

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
#include <iostream>
#include <limits>
using namespace std;

int main()
{
    char name[10];
    bool valid = false;
    do
    {
        cout << "Enter your name: ";
        valid = cin.getline(name, sizeof name);

        if (valid == false)
        {
            cout << "Invalid input. Please input again...\n\n";
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }

    }while (valid == false);


    cout << "Your name: " << name << "\n\n";

    cout << "Press Enter to exit program...";
    cin.get();
    cin.get();
}


Edit: or, as JLBorges points out, gcount() can be used too
Last edited on
If you just press Enter without type anything, cin directly takes the \n and the validation ends. How can I fix this flaw? Thanks.
Don't accept a zero-length name?
yup.
That was the answer in question format ;)
1)
I done it with this solution :)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  do
    {
        cout << "Enter your name: ";
        valid = cin.getline(name, sizeof name);

		
        if (valid == false)
        {
            cout << "Invalid input. Please input again...\n\n";
			cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }

		if (name[0] == '\0')
		{
			cout << "Invalid input. Please input again...\n\n";
			valid = false;
		}

    }while (valid == false);



2)
http://stackoverflow.com/questions/5131647/why-would-we-call-cin-clear-and-cin-ignore-after-reading-input
http://stackoverflow.com/questions/5878052/does-using-ignorenumeric-limitsstreamsizemax-in-the-iostreams-library-ha

My another question is after I read through the answer (links above), I still not very understand about how does cin.clear() and cin.ignore(numeric_limits<streamsize>::max(), '\n') work. (Refer Cubbi solution)

i) cin.clear() clears the error flag on cin? Does flag means you change something from true to false or false to true such as bool done = true; ?

ii) cin.ignore(numeric_limits<streamsize>::max(), '\n') skips to the next newline (to ignore anything else on the same line as the non-number so that it does not cause another parse failure). Is the input has been thrown to dustbin and the name array has been reset to blank?

ii) Does numeric_limits<streamsize>::max() has limit?
Last edited on
> cin.clear() clears the error flag on cin?

Yes. It clears the failed state of cin

> Does flag means you change something from true to false or false

The stream object maintains error state via a set of flags - good, fail, eof and bad http://en.cppreference.com/w/cpp/io/ios_base/iostate

clear() without arguments clears the state flags indicating failure
http://en.cppreference.com/w/cpp/io/basic_ios/clear


> Is the input has been thrown to dustbin

Yes. everything in the input buffer up to and including the first new line is extracted and thrown away.


> and the name array has been reset to blank?

No. cin.ignore() knows nothing about the array.


> Does numeric_limits<streamsize>::max() has limit?

It is the theoretical maximum number of characters that can be possibly present in a stream buffer.
http://en.cppreference.com/w/cpp/types/numeric_limits/max

In practice, we could just write cin.ignore( 10000, '\n'); because we do not expect the user to have typed in 10000 characters first and then a new line.
JLBorges wrote:
> Does numeric_limits<streamsize>::max() has limit?

It is the theoretical maximum number of characters that can be possibly present in a stream buffer.
http://en.cppreference.com/w/cpp/types/numeric_limits/max

In practice, we could just write cin.ignore( 10000, '\n'); because we do not expect the user to have typed in 10000 characters first and then a new line.
This contradicts the answer in the second stack overflow link he posted:
http://stackoverflow.com/a/5878850
Last edited on
why I delete #include <limits> the program still can run without any problem?
Another header might be including for you, but this is not guaranteed to work on all compilers and you should not rely on it. If you want to use something in your program, always include the header for it.
Topic archived. No new replies allowed.