2010-02-10 83 views
4

我正尝试使用重载的“>>”来扫描来自文件的输入。突破重载提取操作符? (C++)

问题是,我不知道如何处理文件结束。 在这种情况下,我的文件是由许多,由几个字符

例:

9rl

8D

6FF

istream &operator>>(istream &is, Move &move) 
{ 
    char c; 
    int i = 0; 

    c = is.get(); 

    if (!isalnum(c)) 
     return; 

    move.setNum(c); // I convert the char to an int, but I'l edit it out 

    while ((c = is.get()) != '\n') 
    { 
    move.setDirection(i, c); //sets character c into in array at index i 
    i++; 

    } // while chars are not newline 

    return is; 
} // operator >> 

测试的字符当我把它作为一个常规函数时,它的字母数字是有效的,但是在这里不起作用,因为它期望返回一个输入流。我试过也返回NULL。建议?

编辑:这是在一个while循环中调用,所以我试图找出一些方法来让这个触发器一些标志,以便我可以跳出循环。在我以前的函数中,我返回了一个布尔值,如果成功或错误返回true,如果字符不是字母数字

回答

2

返回is。呼叫者应该检查流错误。

一定要设置错误位酌情:

std::istream &operator>>(std::istream &is, Move &move) 
{ 
    char c; 
    int i = 0; 

    c = is.get(); 
    if (is.eof()) 
    return is; 
    else if (c < '0' || c > '9') { 
    is.setstate(std::ios::badbit); 
    return is; 
    } 
    else 
    move.setNum(c-'0'); 

    while ((c = is.get()) != '\n' && is) 
    move.setDirection(i++, c); 

    if (c != '\n') 
    is.setstate(std::ios::badbit); 
    return is; 
} 

使用它作为在以下几点:

int main(int argc, char **argv) 
{ 
    std::stringstream s; 

    s << "9rl\n" 
    << "8d\n" 
    << "6ff\n"; 
    s.seekg(0); 

    Move m; 
    while (s >> m) 
    std::cout << m; 

    if (s.bad()) 
    std::cerr << argv[0] << ": extraction failed\n"; 

    return 0; 
} 

请注意,该代码只成功提取后使用实例m

+1

而在这里,'错误'将设置移动到null或一些无效状态。 – Tanzelax 2010-02-10 03:09:02

+0

感谢你们俩。返回并标记这一举措是我最终做的 – kevin 2010-02-10 03:18:34

2

您可以使用ios::setstate将流的标志设置为诸如ios::badios::fail的状态。这将允许调用者测试流,或者在为流启用异常的情况下,将引发异常。

您也无法检查您的流的状态。 C++ FAQ lite有一个解释这个的great section。为了澄清这一点,我添加了下面的代码片段。

c = is.get(); 
// the stream has not been tested to see if it read into c correctly 
if (!isalnum(c)) 
    return;