оператор istream & gt; & gt; не распознает символ \ n

Я в основном читаю .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,

Было бы очень много значить, если бы кто-то мог помочь мне решить эту проблему.

-1

Решение

Если вы хотите игнорировать пробелы, но не '\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') {
// ....
}
0

Другие решения

Вам не нужно заглядывать в символы. я хотел бы использовать 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;
}
0

По вопросам рекламы [email protected]