【问题标题】:Validating user input is valid number or not [invalid conversion from 'char' to 'char*']验证用户输入是否为有效数字 [从 'char' 到 'char*' 的无效转换]
【发布时间】:2019-01-26 21:18:38
【问题描述】:

好的,所以我是 c/c++ 的初学者,我正在创建这个小程序,用于检查用户提供的输入是否为有效数字,如果是,则打印“它是一个数字”,否则打印"它是一个字符串"

一些示例输出

1 - is a number
-1.1 - is a number
1......1 - is a character string
three - is a character string
.12 is a character string
+0.12 is a number
ABC123ABC - is a character string

我的代码中出现此错误。如果有人能帮我解决这个问题,我将不胜感激。 TIA

cpp:52:23: 错误:从 'char' 到 'char*' 的无效转换 [-fpermissive]

如果 (!isNum(c[i]))

{ ~~~^ task1.cpp:5:19:注意:初始化 'bool isNum(char*)' 的参数 1 bool isNum(char * p){

我的代码

#include <iostream>



bool isNum(char * p){
if (NULL == p || *p == '\0'){
    return false;
}
int dot = 0;
int plus = 0;
int minus = 0;

while(*p){
    char a = *p;
    switch (a)
    {
        //Only allows 1 dot
        case '.':
            if (++dot > 1){
                return false;
            }
            break;
        //only allows 1 plus sign
        case '+':
            if (++plus > 1){
                return false;
            }
        //only allows 1 minus sign
        case '-':
            if (++minus > 1){
                return false;
            }
        //Only allows 0-9
        default:
            if (a < '0' || a > '9'){
                return false;
            }

       }
        p++;
    }
    return true;
}

int main(){
    //char array of size 1024
    char c[1024];
    std::cout << "Enter something: ";
    std::cin >> c;

    for(int i = 0; i < sizeof(c); i++){
        if (!isNum(c[i])){
            std::cout << c << " is a character string";    
        }
        else {
            std::cout << c << " is a number";
        }

    }

}

【问题讨论】:

  • 你的函数需要一个 char* 并且你正在传递一个 char
  • 抱歉,我是新手,您能帮我解决这个问题吗?
  • 最好阅读book on C++,会节省大量时间(真的)。
  • 我会看看这个。谢谢
  • @JohnCasey 如果您记录下来,您的代码会更容易理解。例如,isNum 没有关于它作为输入的文档,这可能会导致您使用错误的输入调用它。如果它有文档说“输入p 是一个指向要测试的字符的指针”,那么你就会知道你需要向它传递一个指向要测试的字符的指针。至少没有这样的注释,你可以很容易地传递一个错误的东西。

标签: c++ arrays pointers c++98


【解决方案1】:

如果你想练习复杂的算法,解析数字是一个很好的练习。但是,如果您的目标是编写有用的简单程序,那么您就走错了路。在 C++ 中,C++ 标准库已经解决了许多常见任务,您只需使用它们即可。

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

int main() {
    std::string line;

    if (!std::getline(std::cin, line)) {
        std::cerr << "error reading the line\n";
        return 1;
    }

    std::istringstream in{line};
    double num;

    if (in >> num && in.peek() == EOF) {
        std::cout << "it's a number, " << num << "\n";
    } else {
        std::cout << "it's not a number\n";
    }
}

上面的代码比你的代码更高级。最重要的是它可以处理任意长的行而不会使程序崩溃。

我对 C++ 头文件不是很熟悉,所以我可能忘记包含其他一些头文件。不过剩下的代码应该没问题,虽然我没测试过。

【讨论】:

    【解决方案2】:

    下面的函数isNumber 会为你工作。

    • 这里我使用了一个动态字符序列std::string,它使我们能够输入小于std::string::max_size的任何大小的字符串。

    • 我们可以通过std::isdigit检查给定的字符是否为数字。

    • 没有额外的副本和对象创建将显示良好的性能。

    • 输入字符串的左右两边不允许有空白字符。

    我还编写了迭代器的显式类型并避免使用auto,因为您正在标记C++98

    #include <string>
    #include <cctype>
    
    bool isNumber(const std::string& s)
    {
        // this also validates the following access to s[0]
        if(s.empty()){
            return false;
        }
    
        const std::size_t offset = (s[0] == '+' || s[0] == '-') ? 1 : 0;
        std::string::const_iterator begin = s.begin() + offset;
    
        // this also validates the following dereferencing begin
        if(begin == s.end()){
            return false; // false if just a sign "+" or "-"
        }
    
        if(!std::isdigit(static_cast<unsigned char>(*begin))){
            return false; // e.g. "+.123"
        }
    
        bool isdecimal = false;
        for(std::string::const_iterator it = ++begin; it != s.end(); ++it) 
        {
            if (!std::isdigit(static_cast<unsigned char>(*it)))
            {
                if(!isdecimal && (*it == '.'))
                {
                    isdecimal = true;
    
                    if((it+1) == s.end()){
                        return false; // e.g. "+1."
                    }
                }
                else{
                    return false;
                }
            }
        }
    
        return true;
    }
    

    现在实现 main 函数很简单直接:

    DEMO

    #include <iostream>
    
    int main()
    {
        std::string s;
    
        std::cout << "Enter something: ";
        std::getline(std::cin, s);
        std::cout << std::endl;
    
        std::cout 
            << s << " is a " 
            << (isNumber(s) ? "number." : "character string.");
    
        return 0;
    }
    

    【讨论】:

    • @Spinkoo 的代码满足我使用的所有要求,但由于某种原因,它打印 + 和 - 作为数字。知道为什么吗?
    • @JohnCasey 他在最后一次评论后修复了他的代码行为。在那个版本中,它会将+- 打印为字符,但我认为它仍会将+1. 打印为数字。但是我的回答有什么问题? :) 请检查我的答案描述中链接的DEMO
    • 我必须使用一个 char 数组来存储用户输入
    • @JohnCasey 嗯...没有必要使用 C 风格的 char 数组在 C++ 中执行此操作。 std::string::data 返回 char*const char*std::string::size 返回它的大小。您还可以使用各种公共方法对其进行编辑。那么,你为什么使用 C++?
    • 我正在学习一个操作系统课程,我们正在使用非常旧的操作系统,它只使用老式的 c 和 c++98
    【解决方案3】:

    你去吧,我已经评论了我改变的事情

    #include <iostream>             
    bool isNum(char * p) {
        if (NULL == p || *p == '\0') {
            return false;
        }
        int dot = 0;
    
        char a = *p;
        if (a<'0' || a>'9') {
            if (a != '-' && a != '+') { return false; }
            else p++;
    
        }
    
    
        if (*p<'0' || *p>'9') return false;
        p++;
        while (*p != '\0') {
            a = *p;
            switch (a)
            {
                //Only allows 1 dot
            case '.':
                if (++dot > 1) {
                    return false;
                }
                p++;
                if (*p == '\0') return false;
                break;
    
            default:
                if (a < '0' || a > '9') {
                    return false;
                }
                p++;
                break;
            }
        }
    
        return true;
    }
    
        int main() {
            //char array of size 1024
            char c[1024];
            std::cout << "Enter something: ";
            std::cin >> c;
    
            // you don't need to loop through every character just pass your array of characters & your function is looping through it
            if (!isNum(c)) {
                std::cout << c << " is a character string";
            }
            else {
                std::cout << c << " is a number";
            }
    
        }
    

    【讨论】:

    • 嘿,由于某种原因,这是将所有前面带有负数和正数的数字作为字符串计算,知道为什么吗?
    • 另外 .1 也被算作数字,它应该是 char 字符串
    • 你忘了在案件之后“打破”,所以无论如何它都会进入默认值
    • 我为每个案例添加了 break ,它仍然在做同样的事情
    • 您应该检查第一个字符是 + 或 - 或数字但不是点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多