Я в основном читаю .txt
файл и хранение значений.
Например:
Student- Mark
Tennis
Будет хранить Mark
в память как studentName
,
Теперь … Если это просто
Student-
Tennis
Тогда он будет работать нормально и выдаст ошибку.
Однако, если файл выглядит так
Student-(space)(nothing here)
Tennis
Будет хранить Tennis
в память как studentName
, если факт не должен ничего хранить и выдавать ошибку. я использую '\n'
характер, чтобы определить, есть ли что-нибудь после -
персонаж. Это мой код …
istream& operator>> (istream& is, Student& student)
{
is.get(buffer,200,'-');
is.get(ch);
if(is.peek() == '\n')
{
cout << "Nothing there" << endl;
}
is >> ws;
is.getline(student.studentName, 75);
}
Я думаю, что это потому, что is.peek()
распознает пробел, но если я попытаюсь удалить пробел, используя is >> ws
удаляет '\n'
характер и до сих пор магазины Tennis
как studentName
,
Было бы очень много значить, если бы кто-то мог помочь мне решить эту проблему.
Если вы хотите игнорировать пробелы, но не '\n'
ты не можешь использовать std::ws
как легко: он пропустит все пробелы и в стороне от ' '
персонажи '\n'
(новая линия), '\t'
(вкладка) и '\r'
(возврат каретки) считаются пробелами (я думаю, что на самом деле есть даже еще несколько). Вы мог переопределить, что пробелы означают для вашего потока (заменив поток std::locale
с обычаем std::ctype<char>
аспект, который изменил представление о том, что означает пробел), но это, вероятно, немного более продвинутый (насколько я могу судить, есть несколько людей, которые могли бы сделать это прямо сейчас; спросите об этом, и я отвечу на этот вопрос, если Я замечаю это, хотя …). Более простой подход — просто прочитать хвост строки, используя std::getline()
и посмотрим, что там.
Другой альтернативой является создание собственного манипулятора, скажем, skipspace
и используйте это перед проверкой новой строки:
std::istream& skipspace(std::istream& in) {
std::istreambuf_iterator<char> it(in), end;
std::find_if(it, end, [](char c){ return c != ' '; });
return in;
}
// ...
if ((in >> skipspace).peek() != '\n') {
// ....
}
Вам не нужно заглядывать в символы. я хотел бы использовать std::getline()
и пусть он обрабатывает разрывы строк для вас, а затем используйте std::istringstream
для разбора:
std::istream& operator>> (std::istream& is, Student& student)
{
std::string line;
if (!std::getline(is, line))
{
std::cout << "Can't read student name" << std::endl;
return is;
}
std::istringstream iss(line);
std::string ignore;
std::getline(iss, ignore, '-');
iss >> std::ws;
iss.getline(student.studentName, 75);
/*
read and store className if needed ...
if (!std::getline(is, line))
{
std::cout << "Can't read class name" << std::endl;
return is;
}
std::istringstream iss2(line);
iss2.getline(student.className, ...);
*/
return is;
}
Или, если вы можете изменить Student::studentName
в std::string
вместо char[]
:
std::istream& operator>> (std::istream& is, Student& student)
{
std::string line;
if (!std::getline(is, line))
{
std::cout << "Can't read student name" << std::endl;
return is;
}
std::istringstream iss(line);
std::string ignore;
std::getline(iss, ignore, '-');
iss >> std::ws >> student.studentName;
/*
read and store className if needed ...
if (!std::getline(is, student.className))
{
std::cout << "Can't read class name" << std::endl;
return is;
}
*/
return is;
}