问题
So here's the code:
int create_mask(unsigned b, unsigned e)
{
unsigned int mask=1;
if(b<e || b<0 || e<0)
{
printf("Wrong values, starting bit can't be smaller than ending.\n");
printf("Both got to be >= 0.\n");
exit(EXIT_FAILURE);
}
while(b>0)
{
printf("%u\n", b);
mask<<=1;
if(b>e)
mask|=1;
b--;
}
return ~mask; /* negates mask for later purpose that is clearing corresponding bits */
}
Function creates mask for some bit operations, but should take two unsigned ints b and e, both non-negative. Question is how to prevent user input of negative numbers? When function is called with (-1,0) it start the loop, and shoult exit with error.
回答1:
You could just input a string, check if it contains a '-'
character, and yield an error if it does. Else you convert it to an unsigned integer and proceed on. (Reading as a string then converting with strtoul()
is preferred over using scanf()
anyway, especially while you aren't aware of all of the quirks of scanf()
.)
char buf[LINE_MAX];
fgets(buf, sizeof buf, stdin);
if (strchr(buf, '-') != NULL) {
fprintf(stderr, "input must be non-negative!\n");
exit(-1);
}
unsigned int n = strtoul(buf, NULL, 0);
回答2:
Edit:
you can take the long int
input and then checks input is in between 0 to ending range of unsigned int
.if so then assign to your variable else rise an exception to the user ,you should only give unsigned numbers as input.
long int input;
unsigned int valid_input;
scanf("%ld",&input);
if((0<= input) && (input <= 4294967295))
valid_input= (unsigned int)input ;
else
printf("Unvalid input\n");
As H2CO3 said. reading input into string and checking for first literal if it is not minus then convert into unsigned integer would be preferable rather than the below method. because half of the part unsigned integers not covered.
you can get the input into int
and then if it is non negative then proceed .if it is negative rise an exception to the user ,you should not give negative input.
回答3:
Take a look at this: Stopping function implicit conversion
I was able to adapt it to your issue, and it stops the program from linking. The info in the above thread seems partially incorrect because the example compiled fine. It failed to link because there was not a template specialization defined. I'm actually a little surprised that the following worked for the int vs unsigned int.
template <class T>
void foo(const T& t);
template <>
void foo<unsigned int>(const unsigned int& t)
{
}
int main(){
foo((unsigned int) 9); // will compile and link
unsigned int value(5);
foo(value);// will compile and link
foo(9.0); // will not link
foo(-9); // will not link
return 0;
}
I think that you might be over thinking this though. Is it really a problem? Would it be better to make your id type an int to begin with? Is there a min/max id that avoids the large numbers that could be mistaken for a twos compliment? This seems like an unfortunate issue with the language that it doesn't provide any easy way to stop an implicit cast.
I tested the example with Visual Studio 2010. Additionally, I didn't have the time to write a test class so if it interests you then you'll have to adapt the example to a foo class to see if it works with a constructor of a class, or if there is another way to use templates to do this. Based on the other answers, and my experience I don't think that you are going to find an easy way to do what you want.
来源:https://stackoverflow.com/questions/18574933/prevent-user-passing-negative-numbers-to-a-function-accepting-unsigned-int