【问题标题】:Problem with comparison between pointer and integer C++指针和整数C++之间的比较问题
【发布时间】:2019-08-27 05:20:33
【问题描述】:

我一直收到错误消息说

[错误] ISO C++禁止指针和整数比较[-fpermissive]

不知道怎么解决。

我在 stackoverflow 中搜索过有同样问题的人,但只想到了这个:c++ compile error: ISO C++ forbids comparison between pointer and integer 没有回答我的问题。让我感到困惑的是,错误在 HERE 注释指示的行上,即 if 语句,但我在条件部分看不到任何整数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;

int main() {
    char in[100];
    gets(in);
    int len = strlen(in);
    std::string s(in);
    int count = 0;
    for (int i = 0; i < len; i++) {
        if (s.at(i) == " ") {        // <-- HERE
            count += 1;
        }
    }

    cout << count;
}

假设输入是 Hello World,我希望输出是 1,但我没有得到任何输出。

【问题讨论】:

  • 永远不要永远使用gets!这是一个 dangerous 函数,已从 C 和 C++ 中删除。如果要从标准输入读取一行,请使用std::getline 读入std::string。
  • 至于你的问题,我建议你退后几步,回到你的书、教程或课堂笔记,想想字符串之间的区别(用双引号分隔@987654331 @) 和字符(由单引号 ' 分隔)。
  • 我知道您很困惑——在您非常熟悉 C++ 中的隐式类型转换之前,该消息毫无意义。
  • @Some 程序员老兄 std::getline 如果输入超过一行,不会给出 \n 吗?

标签: c++ arrays string pointers type-conversion


【解决方案1】:

表达式" " 是string literal,类型为const char [2]。

表达式s.at(i) 返回char&amp;。

所以,s.at(i) == " " 正试图找到一个相等运算符 左侧为char&amp;,右侧为对文字数组const char(&amp;)[4] 的引用。

它找到operator== 的一个或多个候选对象,但参数类型不完全匹配,所以接下来它尝试implicit conversion sequences - 这是char&amp; 经历integral promotion 到int 的地方,并且数组衰减到const char*。

它仍然没有找到与这些匹配的,并放弃了,但这解释了为什么在发出错误时它有 int 和 const char * 参数。

在 C++ 中编写像 ' ' 这样的字符字面量是很长的一段话。它们不只是像其他一些语言那样长度为 1 的字符串(而且你根本不能用单引号编写字符串)。

【讨论】:

  • :) 我不仅来晚了,而且还忘记了促销的事情。有趣的是,错误消息对于初学者来说总是太少,而对于有经验的程序员来说却太多了。很好的解释!
  • 是的,我尝试了几次才能正确写出它。我觉得编译器应该真正描述重载决议序列,而不是只在最后显示提升的类型。
【解决方案2】:

更改 if 语句

if (s.at(i) == ' ') {
    count += 1;
}

因为s.at(i)返回char&," "是一个字符串,' '是一个字符。

【讨论】:

  • 这个答案虽然在技术上是正确的,但如果您能准确地解释为什么按所述更改循环可以解决问题,以及根本问题实际上是什么,则会得到改进。
【解决方案3】:

问题是" " 是字符串文字而不是字符!字符文字将是' '。

这个错误有点误导,因为" "实际上是const char*。

【讨论】:

  • " " 实际上是一个const char* ... 是一个指针,而所涉及的字符得到promoted to int。 C++ 错误消息总是让初学者感到困惑。
【解决方案4】:

C++ 通过不同的引用符号区分字符串和单个字符(" vs ')。代码中的" " 是包含一个空格 的字符串文字,单个空格字符将写为' '。函数std::string::at 返回单个字符。

一个小例子将向您展示编译器的外观

#include <iostream>
#include <string>
#include <typeinfo> // for typeid
using namespace std;

int main() {
    string s = "Hello, world!";
    cout << typeid(" ").name() << endl;
    cout << typeid(' ').name() << endl;
    cout << typeid(s.at(0)).name() << endl;
    return 0;
}

见online demo of above code。

但是,准确地说,C++ 中的比较不需要相同的类型,但类型需要兼容。指针(字符串文字被认为是指向字符的常量指针,实际上指向文字中的第一个字符)和整数(在您的情况下提升为 char)是不兼容的。要快速“修复”您的问题,请将s.at(i) == " " 更改为s.at(i) == ' ',但您的程序仍然存在问题:它仍然包含许多本身也存在问题的C 代码。一个可能的 C++ 版本可能是这样的:

#include <iostream>
#include <string>
using namespace std;

int main() {
    int count = 0;
    string line;
    std::getline(cin, line);
    for (const auto c: line) {
        if (c == ' ') {
            count++;
        }
    }
    cout << "Your input \""<< line << "\" contains " << count << " space(s)." << endl;
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多