C++ c_str() не возвращает полную строку

Я делаю присваивание C++, которое требует ввода пользователем выражения (например, 2 * (6-1) + 2) и вывода результата. Все работает правильно, если в пользовательском вводе не встречается пробел.

Требуется передать пользовательский ввод следующему методу;

double Calculate(char* expr);

Я знаю, что проблема вызвана c_str(), где символы пробела действуют как завершающий нулевой байт, хотя я не уверен, как решить эту проблему.

В идеале я хотел бы сохранить символы пробела, но согласился бы просто удалить их, так как пробел не имеет смысла в выражении. Я получаю тот же результат при использовании string::data вместо c_str.

int main(int argc, char **argv)
{
    string inputExpr;
    Calc myCalc;

    while(true) {
        cin >> inputExpr;
        if(inputExpr == "q") break;

        cout << "You wrote:" << (char*)inputExpr.c_str() << endl; // debug
        printf("Result: %.3f \n\n", myCalc.Calculate( (char*)temp.c_str() ) );
    }
    return 0;
}

3 ответа

Решение

c_str работает просто отлично. Ваша проблема cin >> inputExpr, >> Оператор читает только до следующего пробела, поэтому вы не читаете ваше уравнение полностью.

Вы хотите использовать std:: getline:

std::getline (std::cin,inputExpression);

который будет читать, пока не достигнет символа новой строки. Смотрите описание функции, если вам нужен конкретный разделитель.

Проблема не в inputExpr.c_str() и c_str как таковых, c_str() возвращает указатель на массив символов, который содержит завершенную нулем последовательность. Читая cin, вы получаете пробел или табуляцию и т. Д., Которые разделяются на несколько строк. Проверьте с содержимым строки таким образом, чтобы решить предполагаемую операцию

Во-первых, я думаю, что ваш Calculate() метод должен принимать в качестве входных данных const char* строка, так как expr должен быть входным (только для чтения) параметром:

double Calculate(const char* expr);

Обратите внимание, что если вы используете const char*Вы можете просто позвонить std::string::c_str() без какого-либо уродливого броска, чтобы удалить постоянство.

И, поскольку это C++, а не C, используя std::string было бы здорово:

double Calculate(const std::string& expr);

Что касается конкретного вопроса чтения также пробелов, это не проблема прекращения NUL байт: пробел не NUL,
Вы должны просто изменить способ чтения строки, используя std::getline() вместо простого std::cin >> перегрузка:

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

int main()
{
    string line;
    getline(cin, line);
    cout << "'" << line << "'" << endl;
}

Если вы скомпилируете и запустите этот код, и введите что-то вроде Hello World, вы получите всю строку в качестве вывода (включая пробел, разделяющий два слова).

Другие вопросы по тегам