Проблема со сравнением между указателем и целым числом C ++ - PullRequest
1 голос
/ 05 апреля 2019

Я получаю сообщения об ошибках:

[Ошибка] ISO C ++ запрещает сравнение между указателем и целым числом [-fpermissive]

и не знает какчтобы исправить это.

Я искал stackoverflow для людей с такими же проблемами, но только придумал следующее: Ошибка компиляции c ++: ISO C ++ запрещает сравнение между указателем и целым числом , которое не былоответь на мой вопрос.Что меня также смутило, так это то, что ошибка находится в строке, указанной в комментарии 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Мир, я ожидаю, что результат будет 1, но я не получил никакого вывода.

Ответы [ 4 ]

4 голосов
/ 05 апреля 2019

Выражение " " представляет собой строковый литерал с типом const char [2].

Выражение s.at(i) возвращает char&.

Итак, s.at(i) == " " пытается найти оператор равенства, принимая char& слева и ссылку на буквенный массив const char(&)[4] справа.

Находитодин или несколько кандидатов на operator==, но типы аргументов не совпадают точно, поэтому затем он пытается последовательности неявного преобразования - это то место, где char& проходит интегральное продвижение до int, и массив уменьшается до const char*.

Он по-прежнему не находит соответствия с ними и сдается, но это объясняет, почему он имеет int и const char * аргументыкогда выдается ошибка.

Это долгий способ сказать, что вы пишете символьные литералы, такие как ' ' в C ++.Они не просто строки длиной 1, как в некоторых других языках (и вы не можете писать строки с одинарными кавычками).

2 голосов
/ 05 апреля 2019

Изменить оператор if

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

, поскольку s.at(i) возвращает символ &, " " - строка, а ' ' - символ.

0 голосов
/ 05 апреля 2019

C ++ различает строки символов и отдельные символы в литералах по различным символам в кавычках (" против '). " " в вашем коде - это строковый литерал, который содержит один пробел , один символ пробела будет записан как ' '. Функция 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;
}

см. онлайн-демонстрацию вышеуказанного кода .

Но, если быть точным, идентичные типы не требуются для сравнения в 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;
}
0 голосов
/ 05 апреля 2019

Проблема в том, что " " - это строковый литерал, а не символ! Символьный литерал будет ' '.

Ошибка немного вводит в заблуждение, потому что " " на самом деле const char*.

...