@holika

Почему программа выводит неверное количество символов без учёта пробелов?

Привет, испытываю проблемы с std::string и std::string_view, хотя использую только английские буквы.

ОС: Windows 10 x64

Проблемы, которые связаны с вопросом:

1) Программа не распознаёт символы пробела в строке. При включённой оптимизации (релиз-мод) всё работает как надо, при выключенной оптимизации - нет. Касается не только Visual Studio, но и любых других сайтов/программ, где можно включить/выключить оптимизацию и сравнить результаты.

2) Странные символы вместо содержимого std::string и std::string_view в Visual Studio

Ввёл: "Hello World", в дебаге ожидаю, что будет показываться "Hello World", но получаю "0x00000080135ffae0 "o\0\0\0ц\0\0аъ_"".

Минимально воспроизводимый пример (С++latest):
#include <iostream>
#include <string>
#include <string_view>

// Функция, которая получает от пользователя его полное имя (прим. "John Doe")
std::string_view getFullName()
{
    std::cout << "Input your name: " << '\n';

    std::string fullName{};
    std::getline(std::cin, fullName); // Пытаюсь получить строку с одним и более пробелами
    std::string_view fullNameView = fullName;
    return fullNameView;
}

// Функция, которая считает количество букв в строке (пробелы не учитываются)
int countLettersInName(std::string_view fullName)
{
    int spaces{ 0 };
    for (auto ch: fullName)
    {
        if (ch == ' ') // Обнаружение символа пробела в строке
        {
            spaces += 1;
        }
    }

    /*
        std::string::length возвращает unsigned int, поэтому здесь я использовал std::ssize,
        который возвращает signed int. И поскольку std::ssize возвращает __int64, я использую
        static_cast, чтобы сконвертировать __int64 в int (строки короткие, потери информации
        быть не должно)
    */
    return static_cast<int>(std::ssize(fullName)) - spaces;
}

int main()
{
    std::string_view fullName{ getFullName() };
    std::cout << "Answer is: " << countLettersInName(fullName) << '\n';
    return 0;
}


Как пытался исправить:
- Менял язык системы, язык Visual Studio, включал/отключал юникод в консоли через настройки Студии
- Проверял кодировку cpp файлов (стоит utf-8)
- Пытался дебажить (но, увы, там непонятно что вместо англ. букв и не смог уследить, что да как)
- Пытался использовать встроенные функции для поиска символа в строке, результат тот же, что и у меня

Пожалуйста, подскажите, где может быть проблема.
  • Вопрос задан
  • 124 просмотра
Решения вопроса 1
@holika Автор вопроса
Ну конечно же проблема в string_view, а именно в месте, где я возвращаю этот тип в getFullName.

Так как std::string уничтожается после завершения функции, std::string_view будет вызывать undefined behavior (явные признаки undefined behavior как на ладони: то работает, то нет).

В голове отложилось, что C-style литералы существуют на протяжении всей программы и произошла странная путанница в мозгах, ведь std::string ведут себя иначе.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@ignat2009
14 лет, изучаю C#
я предлагаю такой код
#include <bits/stdc++.h>
using namespace std;
int main()
{ string  t , s ; int i,  k = 0 ;
getline(cin,t);t+=" ";  //вводим предложения и добовляем в конце пробел
for(i=0;i<t.size();i++) //проходимся по предложению
if(  t [ i ] ! = '  '  )  k + +;  //если символ не равняется пробелу то к переменной прибавлям 1
cout < < k ;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы