Есть ли способ использовать функцию, подобную tolower(), для переменной vector<string> в C++?

Я пытаюсь загрузить и отсортировать файл по алфавиту. Чтобы сделать это проще, я должен преобразовать символы в нижний регистр.

Теперь мне нужно делать это посимвольно, когда я читаю его в массив строк (поскольку tolower() принимает только символы), или я могу как-то использовать его с контейнером vector<string>?

Вот код:

#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>

using namespace std;

int main() {

   ifstream file("phoneNumbers.txt");
   vector<string> wordStream;
   int i = 0;

    if (file.fail()) {
        cout << "Couldn't open file!";
        return 1;
    }

    while(file>>wordStream[i]) {
        wordStream[i] = tolower(wordStream[i]);
        ++i;
    }
}

Вопрос новичка, я знаю.

Я уже пробовал функцию std::transform(), которую кто-то рекомендовал на StackOverflow, но она все равно не работала.

Нет ничего плохого в том, чтобы делать это по одному персонажу за раз, если вы можете заставить его работать таким образом. std::transform тоже сработает.

john 17.05.2023 22:10

У вашего кода совсем другая проблема, ваш вектор имеет нулевой размер. поэтому wordStream[i] - это доступ к векторам за пределами границ. Используйте push_back, чтобы добавить строки в вектор.

john 17.05.2023 22:11
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем коде есть две проблемы: tolower не работает со строками, а ваш вектор имеет нулевой размер, поэтому wordStream[i] является ошибкой для любого значения i. Вот код, исправленный из этих ошибок

string temp;
while (file >> temp) { // read to a temporary string
    // convert string to lower case
    std::transform(temp.begin(), temp.end(), temp.begin(), tolower);
    // add temporary string to vector
    wordStream.push_back(temp);
}

Примечание: параметр tolower — это int, а не char, так что он может обрабатывать внеполосные коды. Это может привести к интересным проблемам с простым решением, описанным здесь.

user4581301 17.05.2023 22:23

Передача tolower также может завершиться ошибкой в ​​зависимости от реализации, особенно с OP using namespace std;, потому что в стандартной библиотеке есть еще одна перегрузка. Единственный надежный способ — передать [](unsigned char c){ return std::tolower(c); }std:: или без, если используется using namespace std;) или эквивалент.

user17732522 17.05.2023 22:28

Обратите внимание, что поскольку C++20 принимает адрес std::tolower (передавая его в качестве параметра функции), это Unspecified Behavior — ограничение адресации. Использование лямбда-оболочки — самый простой способ избежать этого. «... Поведение программы на C++ не определено... если она явно или неявно пытается сформировать указатель, ссылку... или указатель на член... на стандартную библиотечную функцию или экземпляр стандартного шаблон библиотечной функции, если он не назначен адресуемой функцией..."

Richard Critten 18.05.2023 10:48

@RichardCritten Интересно, еще одна причина использовать здесь лямбду. Я знал о проблеме с параметром int, но не об этом. Мне любопытно, однако, какова причина этого изменения? Мне кажется, это очень важно.

john 18.05.2023 12:39

@john Эта ветка Reddit содержит ссылки на документы, посвященные этой проблеме: reddit.com/r/cpp_questions/comments/hewx2o/… . Похоже, это способ использовать Стандартную библиотеку в будущем, если какие-либо сигнатуры функций изменятся.

Richard Critten 18.05.2023 13:54

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