Я пытаюсь загрузить и отсортировать файл по алфавиту. Чтобы сделать это проще, я должен преобразовать символы в нижний регистр.
Теперь мне нужно делать это посимвольно, когда я читаю его в массив строк (поскольку 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, но она все равно не работала.
У вашего кода совсем другая проблема, ваш вектор имеет нулевой размер. поэтому wordStream[i] - это доступ к векторам за пределами границ. Используйте push_back, чтобы добавить строки в вектор.





В вашем коде есть две проблемы: 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, так что он может обрабатывать внеполосные коды. Это может привести к интересным проблемам с простым решением, описанным здесь.
Передача tolower также может завершиться ошибкой в зависимости от реализации, особенно с OP using namespace std;, потому что в стандартной библиотеке есть еще одна перегрузка. Единственный надежный способ — передать [](unsigned char c){ return std::tolower(c); } (с std:: или без, если используется using namespace std;) или эквивалент.
Обратите внимание, что поскольку C++20 принимает адрес std::tolower (передавая его в качестве параметра функции), это Unspecified Behavior — ограничение адресации. Использование лямбда-оболочки — самый простой способ избежать этого. «... Поведение программы на C++ не определено... если она явно или неявно пытается сформировать указатель, ссылку... или указатель на член... на стандартную библиотечную функцию или экземпляр стандартного шаблон библиотечной функции, если он не назначен адресуемой функцией..."
@RichardCritten Интересно, еще одна причина использовать здесь лямбду. Я знал о проблеме с параметром int, но не об этом. Мне любопытно, однако, какова причина этого изменения? Мне кажется, это очень важно.
@john Эта ветка Reddit содержит ссылки на документы, посвященные этой проблеме: reddit.com/r/cpp_questions/comments/hewx2o/… . Похоже, это способ использовать Стандартную библиотеку в будущем, если какие-либо сигнатуры функций изменятся.
Нет ничего плохого в том, чтобы делать это по одному персонажу за раз, если вы можете заставить его работать таким образом.
std::transformтоже сработает.