By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,413 Members | 999 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,413 IT Pros & Developers. It's quick & easy.

data validation

P: n/a
How do i validate data? IE if a have a variable X of type int, and i
promt a user with cin >> X; how do i make sure they don't answer with a
letter? or a symbol?

Jul 23 '05 #1
Share this Question
Share on Google+
24 Replies


P: n/a
<gu******@gmail.com> wrote...
How do i validate data? IE if a have a variable X of type int, and i
promt a user with cin >> X; how do i make sure they don't answer with a
letter? or a symbol?


This is explained in the FAQ (http://www.parashift.com/c++-faq-lite/)
Jul 23 '05 #2

P: n/a
gurumare wrote:
How do i validate data? IE if a have a variable X of type int, and i
promt a user with cin >> X; how do i make sure they don't answer with a
letter? or a symbol?


Use std::getline(cin, myString) to pull a string. That lets the user hit
<Enter> to turn-around the input.

Then call:

char * end = NULL;
strtol(myString.c_str(), 10, &end);

Test 'end' to see if it truly points to myString.end(). That gives a quick,
simple, and robust validation.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces


Jul 23 '05 #3

P: n/a
"Phlip" <ph*******@yahoo.com> wrote...
gurumare wrote:
How do i validate data? IE if a have a variable X of type int, and i
promt a user with cin >> X; how do i make sure they don't answer with a
letter? or a symbol?


Use std::getline(cin, myString) to pull a string. That lets the user hit
<Enter> to turn-around the input.

Then call:

char * end = NULL;
strtol(myString.c_str(), 10, &end);

Test 'end' to see if it truly points to myString.end(). That gives a
quick,
simple, and robust validation.


For one, I'd probably declared 'end' as const char*. And is it guaranteed
that the pointer returned by c_str() actually survives long enough for 'end'
to still be valid some time later when you check its value? I wonder how
well implementations handle this mix of std::string and std::strXXX library
functions especially for checking if 'end' "points to myString.end()". Are
you sure that c_str() returns a pointer whose last element coincides with
what 'std::string::end()' returns? I can't find any guarantee of it in the
Standard.

V
Jul 23 '05 #4

P: n/a
Could you tell me where in the FAQ? a search came up with nada

Jul 23 '05 #5

P: n/a
<gu******@gmail.com> wrote...
Could you tell me where in the FAQ? a search came up with nada


I'd try section 15. However, all of it is useful information and
you should be at least familiar with what's there and what's not
there. So, start from the top and read.
Jul 23 '05 #6

P: n/a
gurumare wrote:
Could you tell me where in the FAQ? a search came up with nada


You searched with Google, right? What terms did you use?

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #7

P: n/a
gu******@gmail.com wrote:
Could you tell me where in the FAQ? a search came up with nada


How did you search? It's quite hard to miss the chapter about "Input/output
via <iostream> and <cstdio>".

Jul 23 '05 #8

P: n/a
Thank you, i looked in section 15 and found exactly what i needed. I
searched the faq for 'validation' i guess what i needed was 'bad input'
once again thanks

Jul 23 '05 #9

P: n/a
Victor Bazarov wrote:
"Phlip" <ph*******@yahoo.com> wrote...
gurumare wrote:
How do i validate data? IE if a have a variable X of type int, and i
promt a user with cin >> X; how do i make sure they don't answer with a
letter? or a symbol?
Use std::getline(cin, myString) to pull a string. That lets the user hit
<Enter> to turn-around the input.

Then call:

char * end = NULL;
strtol(myString.c_str(), 10, &end);

Test 'end' to see if it truly points to myString.end(). That gives a
quick,
simple, and robust validation.


For one, I'd probably declared 'end' as const char*. And is it guaranteed
that the pointer returned by c_str() actually survives long enough for
'end' to still be valid some time later when you check its value?


Yes. It lives as long as the whole expression.
I wonder how well implementations handle this mix of std::string and
std::strXXX library functions especially for checking if 'end' "points to
myString.end()". Are you sure that c_str() returns a pointer whose last
element coincides with what 'std::string::end()' returns? I can't find
any guarantee of it in the Standard.


You have a point here. It's not required that c_str() returns a pointer to
the original string content.

Jul 23 '05 #10

P: n/a
Rolf Magnus wrote:
Victor Bazarov wrote:

"Phlip" <ph*******@yahoo.com> wrote...
gurumare wrote:
How do i validate data? IE if a have a variable X of type int, and i
promt a user with cin >> X; how do i make sure they don't answer with a
letter? or a symbol?

Use std::getline(cin, myString) to pull a string. That lets the user hit
<Enter> to turn-around the input.

Then call:

char * end = NULL;
strtol(myString.c_str(), 10, &end);

Test 'end' to see if it truly points to myString.end(). That gives a
quick,
simple, and robust validation.
For one, I'd probably declared 'end' as const char*. And is it guaranteed
that the pointer returned by c_str() actually survives long enough for
'end' to still be valid some time later when you check its value?

Yes. It lives as long as the whole expression.


But I don't see the test of 'end' against myString.end() anywhere in this
full expression. Do you?

I think there is a guarantee that the pointer survives until the string is
actually modified. But I am not sure. Too lazy to look it up.
[...]


V
Jul 23 '05 #11

P: n/a
Victor Bazarov wrote:

I think there is a guarantee that the pointer survives until the string is
actually modified. But I am not sure. Too lazy to look it up.


The value returned by c_str() is guaranteed to be valid until a non-const
method of string is called (C++ Standard, 21.3.6.2).
Jul 23 '05 #12

P: n/a
Victor Bazarov wrote:
Rolf Magnus wrote:
Victor Bazarov wrote:

"Phlip" <ph*******@yahoo.com> wrote...

gurumare wrote:
>How do i validate data? IE if a have a variable X of type int, and i
>promt a user with cin >> X; how do i make sure they don't answer with a
>letter? or a symbol?

Use std::getline(cin, myString) to pull a string. That lets the user hit
<Enter> to turn-around the input.

Then call:

char * end = NULL;
strtol(myString.c_str(), 10, &end);

Test 'end' to see if it truly points to myString.end(). That gives a
quick,
simple, and robust validation.

For one, I'd probably declared 'end' as const char*. And is it
guaranteed that the pointer returned by c_str() actually survives long
enough for 'end' to still be valid some time later when you check its
value?

Yes. It lives as long as the whole expression.


Oops, didn't read it carefully enough. I thought we were talking about a
temporary string.
But I don't see the test of 'end' against myString.end() anywhere in this
full expression. Do you?

I think there is a guarantee that the pointer survives until the string is
actually modified. But I am not sure. Too lazy to look it up.


Yes.

Jul 23 '05 #13

P: n/a
Ok, i have another question then, upon reading the FAQ, i found a great
way to differentaite between an int and a char in validation. But what
if you user enters 1a. the 1 makes it through my validation, and then
the a messes everything up. Is there a way to take care of that? I am a
student, and this is my first semester in c++ and i have a crafty
teacher who just may do that to see how well my validation is. thanks

Jul 23 '05 #14

P: n/a
Kurt Stutsman wrote:
Victor Bazarov wrote:

I think there is a guarantee that the pointer survives until the
string is
actually modified. But I am not sure. Too lazy to look it up.


The value returned by c_str() is guaranteed to be valid until a
non-const method of string is called (C++ Standard, 21.3.6.2).


So, if one calls the const variation of the 'end()' member function, then
one should be OK when comparing the pointer obtained from 'strtol' to it.
One would need to cast the string to 'const string' first, of course, to
achieve that. Otherwise, the non-const variation of 'end()' is called and
the pointer returned by 'c_str()' (and the one obtained from 'strtol') are
not valid any longer. Of course even in case of calling 'end() const' it
is still not guaranteed to produce the desired result due to the other
reason I mentioned. Thank you for clarifying the matter, though.

V
Jul 23 '05 #15

P: n/a
"gu******@gmail.com" wrote:

Ok, i have another question then, upon reading the FAQ, i found a great
way to differentaite between an int and a char in validation. But what
if you user enters 1a. the 1 makes it through my validation, and then
the a messes everything up. Is there a way to take care of that? I am a
student, and this is my first semester in c++ and i have a crafty
teacher who just may do that to see how well my validation is. thanks


To quote a previous poster
Then call:

char * end = NULL;
strtol(myString.c_str(), 10, &end);

Test 'end' to see if it truly points to myString.end(). That gives a
quick,
simple, and robust validation.


strtol is kind enough to tell you where it stopped translating
the string to an integer. Either strtol has processed the whole
string (then the whole string was one single integer) or it
did not (in that case there are some non digit characters left
in the string)

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #16

P: n/a
gu******@gmail.com wrote:
Ok, i have another question then, upon reading the FAQ, i found a great
way to differentaite between an int and a char in validation. But what
if you user enters 1a. the 1 makes it through my validation, and then
the a messes everything up. Is there a way to take care of that? I am a
student, and this is my first semester in c++ and i have a crafty
teacher who just may do that to see how well my validation is. thanks


'a' doesn't mess things up. '1' will be interpreted as the int you wanted
to input. The rest of the stream (what comes after a valid number) is
usually non-consequential. Of course, you could write a more clever
validation algorithm according to more complicated rules you are willing
to impose, but AFA I'm concerned "1a" string does contain a valid integer.

What you do after '1' has been extracted is up to you. You could try to
go back to reading and report invalid input or stop if the input has been
exhausted. You could simply ignore the rest of the input. You could read
the input as a string an analyze it char by char and only if the sequence
in its entirety represents a number (in your understanding), accept it,
and report an error otherwise. The choices are many.

BTW, 1a is a valid hexadecimal value. :-)

V
Jul 23 '05 #17

P: n/a
Karl Heinz Buchegger wrote:
"gu******@gmail.com" wrote:
Ok, i have another question then, upon reading the FAQ, i found a great
way to differentaite between an int and a char in validation. But what
if you user enters 1a. the 1 makes it through my validation, and then
the a messes everything up. Is there a way to take care of that? I am a
student, and this is my first semester in c++ and i have a crafty
teacher who just may do that to see how well my validation is. thanks

To quote a previous poster

Then call:

char * end = NULL;
strtol(myString.c_str(), 10, &end);
BTW, it should be

long value = strtol(.., &end, 10);

Test 'end' to see if it truly points to myString.end(). That gives a
quick,
simple, and robust validation.

strtol is kind enough to tell you where it stopped translating
the string to an integer. Either strtol has processed the whole
string (then the whole string was one single integer) or it
did not (in that case there are some non digit characters left
in the string)


The only way to do it is to store the pointer returned by 'c_str()' in
a variable and compare 'end' to its real end without touching the original
string:

char const *buffer = myString.c_str();
char const *end = buffer;
long value = strtol(buffer, &end, 10);
if (end != buffer + strlen(buffer))
{
// error, not all chars have been converted
}

Neither the "previous poster" nor anybody else specified this before.
However, it is necessary, AFAIK.

V
Jul 23 '05 #18

P: n/a
what does "Test 'end' to see if it truly points to myString.end()." I
am new to this, and i am really trying to understand, but i have no
idea how to do it, or even what these lines of code mean. I have never
heard of strtol nor do i know what it does, the same goes for c_str().
and so far, any attempts i have made to implement the code i have found
here only results in errors i do not know how to fix. I probably
wouldn't even know it if a had it right. Please help

Jul 23 '05 #19

P: n/a
When you reply with Google Groups, use Preview, then Edit, to get the
replied-to text. Then trim most of it out, leaving enough context that we
can tell to what you replied.

gurumare wrote:
what does "Test 'end' to see if it truly points to myString.end()." I
am new to this, and i am really trying to understand, but i have no
idea how to do it, or even what these lines of code mean. I have never
heard of strtol nor do i know what it does, the same goes for c_str().
What did Google tell you about strtol, and std::string ? What do your
tutorial tell you?

What do the sample programs that came with your compiler tell you?
and so far, any attempts i have made to implement the code i have found
here only results in errors i do not know how to fix.


Post the code and the errors.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #20

P: n/a

Phlip wrote:
When you reply with Google Groups, use Preview, then Edit, to get the
replied-to text. Then trim most of it out, leaving enough context that we can tell to what you replied.

There's a more direct way. Click "show options" and use the Reply shown
in the expanded header. Saves several steps over your method (which
does seem to work, to my surprise).


Brian

Jul 23 '05 #21

P: n/a
Ok, i was finally able to use strtol after looking it up and studying
its structure. my final code looks like this:
void main()
{
char name[20];
cin.getline(name, 20);

const char *strPtr = name;
char *end = NULL;

int val = strtol(strPtr, &end, 10);
cout << val;
getch();

}

this is just a test i set up to make sure i was doing it correctly. If
there is anything else i shoulkd know or change, please let me know,
thanks.

Jul 23 '05 #22

P: n/a
gu******@gmail.com wrote:
Ok, i was finally able to use strtol after looking it up and studying
its structure. my final code looks like this:
#include <iostream>
using namespace std;
void main()
int main()
{
char name[20];
cin.getline(name, 20);

const char *strPtr = name;
char *end = NULL;

int val = strtol(strPtr, &end, 10);
cout << val;
getch();
There is no standard function 'getch'. Did you mean 'getchar'?

}

this is just a test i set up to make sure i was doing it correctly. If
there is anything else i shoulkd know or change, please let me know,
thanks.


What do you have your 'end' for? You don't seem to be using the value
you get in it back from 'strtol' in any way...

V
Jul 23 '05 #23

P: n/a

There is no standard function 'getch'. Did you mean 'getchar'?
I included those iostream, and i included conio.h which has the
function getch(); i use it as a quick way to pause my script

What do you have your 'end' for? You don't seem to be using the value you get in it back from 'strtol' in any way...


i added code later that displayed my 'end' to see if it was working
correctly. i basically set up that code so that if i needed to see what
was there i can.

Jul 23 '05 #24

P: n/a
In article <11**********************@l41g2000cwc.googlegroups .com>,
"gu******@gmail.com" <gu******@gmail.com> wrote:
Ok, i was finally able to use strtol after looking it up and studying
its structure. my final code looks like this:
void main()
{
char name[20];
cin.getline(name, 20);

const char *strPtr = name;
char *end = NULL;

int val = strtol(strPtr, &end, 10);
cout << val;
getch();

}

this is just a test i set up to make sure i was doing it correctly. If
there is anything else i shoulkd know or change, please let me know,
thanks.


#include <iostream>
#include <cstdlib>
#include <cerrno>
int atoi(const char* nptr)
{
char *endptr;

errno = 0;
int value = static_cast<int>(std::strtol(nptr, &endptr, 10));
if (*nptr == '\0' || *endptr != '\0')
throw std::invalid_argument(buf);
if (errno)
throw std::range_error(buf);

return value;
}
int main()
{
try
{
char buf[20];
std::cin.getline(name, sizeof(buf));
std::cout << atoi(buf) << std::endl;
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}

return 0;
}
Jul 23 '05 #25

This discussion thread is closed

Replies have been disabled for this discussion.