istream运算符>>不承认'\ n'字符

时间:2014-12-17 22:57:51

标签: c++ char ifstream istream peek

我基本上是在阅读.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

如果有人可以帮助我解决这个问题,那真的意味着很多。

2 个答案:

答案 0 :(得分:0)

如果您想忽略空白但 '\n',您就不能轻易使用std::ws:它会跳过所有空格,除了{{1字符' '(换行符),'\n'(制表符)和'\t'(回车符)被视为空格(我认为实际上还有更多)。你可以重新定义空格对你的流的意义(通过用自定义的'\r'方面替换流std::locale,这改变了空白意味着什么)但是& #39; s可能更高级(据我所知,有一小部分人可以马上做到这一点;问一下,如果我注意到它,我会回答这个问题。 ..)。更简单的方法是使用std::ctype<char>简单地阅读该行的尾部,并查看其中的内容。

另一个选择是创建自己的操纵器,比如std::getline(),并在检查换行之前使用它:

skipspace

答案 1 :(得分: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;
}