简体   繁体   English

检查输入是否为正确的整数

[英]Check if input is a correct integer

I have a little problem with checking my input. 我在检查输入内容时遇到了一些问题。 I know that there a already similar questions but sincerly it does not solve my problem. 我知道这里已经存在类似的问题,但是诚恳地,这并不能解决我的问题。 I'm already using one of the suggestions from the other questions and it does not work. 我已经在使用其他问题的建议之一了,它不起作用。

#include <iostream>
#include <stdio.h>
#include <ctype.h>


int main ()
{
 int a;

 printf("Please type in your number: ");
 scanf_s("%d", &a);

 if(isdigit(a))
 {
    printf("True.");
 }
 else
 {
 printf("False.");
 }

 std::cin.get();
 std::cin.get();

 return 0;

}

I don't know what i'm doing wrong but my output is always "False" when i type in a number. 我不知道自己在做什么错,但是当我输入数字时,我的输出始终为“ False”。 When i type in a letter the compiler has an error. 当我输入字母时,编译器出现错误。

  1. a is already an integer variable. a已经是一个整数变量。 std::isdigit only checks whether a character corresponds to a digit, ie the characters '0' to '9' . std::isdigit仅检查字符是否对应于数字,即字符'0''9'

  2. Try not to mix C libraries ( printf , scanf etc.) with C++ libraries ( cout and cin ). 尽量不要将C库( printfscanf等)与C ++库( coutcin )混合使用。 Stick to either one. 坚持任一个。

  3. As for how to actually check whether the user entered a number or not, see this answer . 至于如何实际检查用户是否输入了数字, 请参阅此答案

You are using isdigit function incorrectly. 您没有正确使用isdigit函数。

Even though isdigit receives an int as its only parameter, it expects a char value (a byte/number representing an ASCII letter) not a pure int as you are now using it. 即使isdigit接收一个int作为其唯一参数,它也希望char值(表示ASCII字母的字节/数字)不是您现在正在使用的纯int

IE: IE浏览器:

is_digit('1'); // true
is_digit('a'); // false

scanf will already return a parsed integer value, so you don't need to check if it is a digit or not. scanf已经返回一个已解析的整数值,因此您无需检查它是否为数字。

Perhaps if you specify what exactly you are trying to accomplish, we could help some more. 也许如果您指定要完成的任务,我们可以提供更多帮助。

Although isdigit() takes an int as an argument, it checks the character value of your variable. 尽管isdigit()int作为参数,但它会检查变量的字符值。 This: 这个:

scanf_s("%d", &a);

gives you an integer value, not a character value. 给您一个整数值,而不是一个字符值。

You're using scanf with %d, which will convert the digit(s) to an integer, but isdigit is intended to work with raw characters that have not been converted yet. 您正在使用带有%d的scanf ,它将把数字转换为整数,但是isdigit旨在用于尚未转换的原始字符。 If you use it, you'd (probably) want to read a string, then check whether all the characters entered were digits, (with isdigit ) and only after you've done that would you try to convert to an integer. 如果使用它,您(可能)想读取一个字符串,然后检查输入的所有字符是否都是数字(带有isdigit ),只有在这样做之后,您才尝试转换为整数。

Alternatively, you could use something like strtol to convert the string to an integer, and tell you where (and if) it failed. 或者,您可以使用诸如strtol东西将字符串转换为整数,并告诉您失败的地方(以及是否失败)。

If you need to do this in c, follow the answers other ppl already posted. 如果需要在c中执行此操作,请遵循已经发布的其他ppl的答案。

If you want to do this in c++, I'd recommend: 如果您想用c ++做到这一点,我建议:

int num = boost::lexical_cast<int>( somestring );

And the documentation on boost::lexical_cast 以及关于boost :: lexical_cast的文档

isdigit takes a character and return true or false depending on whether the character is a digit or not. isdigit接受字符,并根据字符是否为数字返回真或假。 So you could use this on each character of the the string representation of your integer, but your 'a' is already an integer, as set by scanf_s 因此,您可以在整数的字符串表示形式的每个字符上使用此字符,但是您的“ a”已经是由scanf_s设置的整数

scanf_s will only translate the first digits of the input into the equivalent integer, then will stop scanning. scanf_s只会将输入的前几位转换为等效的整数,然后将停止扫描。 You need instead to process the actual characters entered, so you probaly want something like fgets. 相反,您需要处理输入的实际字符,因此您可能想要fgets之类的东西。

Once you have the string, you can loop over every character in it checking if it is a digit (or you can use a library function like strtol to do this for you and return the integer value, checking afterwards that it consumed all the input when it did so (to reject things like 123X) 有了字符串后,您可以遍历字符串中的每个字符,以检查它是否是数字(或者您可以使用诸如strtol之类的库函数为您完成此操作,然后返回整数值,然后检查该字符串是否消耗了所有输入它这样做(拒绝像123X这样的东西)

I suggest reading a line into a string and then trying to parse that string according to your needs. 我建议将一行读入字符串,然后尝试根据需要解析该字符串。 If the parse fails, simply prompt the user again. 如果解析失败,只需再次提示用户。 You can bury the messy details in a function template: 您可以将杂乱的细节埋在函数模板中:

#include <iostream>
#include <sstream>
#include <string>

template <typename T>
T read(std::string prompt)
{
    for (; ;)
    {
        std::cout << prompt;
        std::string line;
        getline(std::cin, line);
        std::istringstream ss(line);
        T x;
        if ((ss >> x) && (ss >> std::ws).eof()) return x;
    }
}

int main ()
{
    int a = read<int>("Please type in your number: ");
    std::cout << "You entered " << a << '\n';
}

Don't use scanf and family. 不要使用scanf和家人。 Use fgets then strtol / strtoul /etc. 使用fgets然后使用strtol / strtoul / strtol to parse numbers. 解析数字。

If you're really determined to use scanf, you can verify if the conversion took place by checking scanf's return value. 如果您确实确定要使用scanf,则可以通过检查scanf的返回值来验证转换是否发生。 It returns the number of successfully processed format items, or -1 on error. 它返回成功处理的格式项的数量,如果错误则返回-1。 In your case, successful input should return 1 from scanf. 在您的情况下,成功输入应从scanf返回1。

http://www.cplusplus.com/reference/clibrary/cstdio/scanf/ http://www.cplusplus.com/reference/clibrary/cstdio/scanf/

Here's another method that's more in the spirit of C++ (although I am not a C++ expert, so there's probably a better way to do this): 这是更符合C ++精神的另一种方法(尽管我不是C ++专家,所以可能有更好的方法来做到这一点):

#include <iostream>
#include <exception>
#include <cctype>

int main()
{
  using namespace std;

  int a;
  cout << "Please type in your number: " << flush;

  /**
   * Tell the input operation to throw an exception if the input
   * is not properly formatted for the target data type; note that
   * this will only catch bad input that *starts* with a non-numeric 
   * character.
   */
  cin.exceptions(ios_base::failbit); 

  try
  {
    cin >> a;
    if (!isspace(cin.get())
      cout << "false" << endl; // non-numeric, non-whitespace character found
                               // at end of input string, e.g. "12w"
    else
      cout << "true" << endl;
  }
  catch(ios_base::failure& e)  // non-numeric, non-whitespace character found
  {                            // at beginning of input string, e.g. "x23"
    cout << "false" << endl;
  }

  return 0;
}

Now i have found a solution which works for me, but there is still a little problem. 现在,我找到了适合我的解决方案,但是仍然存在一些问题。 This is my modified code: 这是我修改的代码:

#include <iostream>
#include <stdio.h>
#include <ctype.h>


int main ()
{
 int a;

 printf("Please type in your number: ");

 if(scanf_s("%d", &a) == 1)
 {
 printf("True.");
 }
 else
 {
 printf("False.");
 }

 std::cin.get();
 std::cin.get();

 return 0;

}

Now the problem is that i must put a "std::cin.get()" for each letter i type in. That's crazy. 现在的问题是,我必须为输入的每个字母添加一个“ std :: cin.get()”。这太疯狂了。 So when i want to check if "hello" is a number or not i must put a total amount of 7x "std::cin.get()" to hold the screen so that i can see the result. 因此,当我要检查“ hello”是否为数字时,我必须总共放入7倍的“ std :: cin.get()”来保持屏幕,以便我可以看到结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM