简体   繁体   中英

Problem with comparison between pointer and integer C++

I've been getting error messages saying

[Error] ISO C++ forbids comparison between pointer and integer [-fpermissive]

and don't know how to fix it.

I've searched stackoverflow for people with same issues, but only came up with this: c++ compile error: ISO C++ forbids comparison between pointer and integer which didn't answer my question. What also confused me is that the error is on line indicated by the HERE comment, which is the if statement, but I don't see any integers in the condition part.

#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;
}

Say the input is Hello World, I am expecting output to be 1 , but I didn't get any output.

The expression " " is a string literal with type const char [2] .

The expression s.at(i) returns a char& .

So, s.at(i) == " " is trying to find an equality operator taking char& on the left and a reference to the literal array const char(&)[4] on the right.

It finds one or more candidates for operator== , but the argument types don't match any exactly, so next it tries the implicit conversion sequences - this is where the char& undergoes integral promotion to int , and the array decays to const char* .

It still doesn't find a match with these, and gives up, but that explains why it has int and const char * arguments when the error is emitted.

All that is a long way of saying that you write character literals like ' ' in C++. They're not just a string of length 1 as in some other languages (and you can't write strings with single quotes at all).

Change the if statement

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

since s.at(i) returns char&, " " is a string, and ' ' is a char.

The problem is that " " is a string literal not a character! A character literal would be ' ' .

The error is a bit misleading, because " " is acutally a const char* .

C++ differentiates between character strings and single characters in the literals by different quoting symbols ( " vs ' ). The " " in your code is the string literal that contains one space , a single space character would be written as ' ' . The function std::string::at returns a single character.

A small example will show you how the compiler looks on that

#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;
}

see online demo of above code .

But, to be precise, identical types aren't required for comparisons in C++, but the types need to be compatible . Pointers (string literals are considered constant pointers to characters, in fact pointing to the first character in the literal) and integers (to which char is promoted in your case) are not compatible . To "fix" your problem quickly, change s.at(i) == " " to s.at(i) == ' ' , but your program will remain problematic: it still contains a lot of C code that's problematic in it self, too. A possible C++ version could be this:

#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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