andy zhang
andy zhang

Reputation: 21

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.

Upvotes: 1

Views: 1597

Answers (4)

Useless
Useless

Reputation: 67743

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).

Upvotes: 4

Wolf
Wolf

Reputation: 10238

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

Upvotes: 0

Tetix
Tetix

Reputation: 331

Change the if statement

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

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

Upvotes: 3

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122516

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*.

Upvotes: 0

Related Questions