c ++如何读取输入到某一点

时间:2014-04-20 01:56:27

标签: c++ iostream delimiter

嗨,我按照以下顺序输入了一些输入:

Date, Time, Price, Volume, Value,

日期的格式为DD / MM / YY 时间格式为HH / MM / SS AM / PM 和价格,数量和价值是用逗号分隔的数字。

此输入有4000行,偶尔会有一个共享代码,例如' CX' 或者' NXXT'将出现在'值'之后逗号。

我的程序无法解决此问题并崩溃。

我需要的是一种在“价值”之后忽略逗号以外的任何内容的方法。并继续阅读下一行。这将出现在' Shares'类。

以下是我班级的输入流:

课程:'日期'

istream & operator >> (istream & input, Date & C) /// An input stream for the day, month and year
{
char delim;
input >> C.day >> delim >> C.month >> delim >> C.year;

return input;   /// Returning the input value
}

课程'时间'

istream & operator >> (istream & input, Time & C) /// An input stream for the hour minutes and seconds
{
char delim;
input >> C.hour >> delim >> C.minute >> delim >> C.second;
getline(input,C.ampm,',');

return input;   /// Returning the input value
}

Class' Shares'

istream & operator >> (istream & input, Shares & C) /// An input stream for the day, month and year
{
char delim;
input >> C.price >> delim >> C.volume >> delim >> C.value >> delim;

return input;   /// Returning the input value
}

2 个答案:

答案 0 :(得分:0)

编写一个跳过并包括该行结束的函数。

void skipEOL(std::istream& in)
{
  int c;
  while ( (c = in.getc()) != '\n' && c != EOF );
}

当您知道需要跳过所有内容直到并包括该行的结尾时使用它。

答案 1 :(得分:0)

看起来股票是代表不同领域的数据结构。编写一个以更健壮的方式解析行的函数。理想情况下,如果Shares代表一行的数据,只需要输入一行输入字符串即可。即使存在其他行,该对象也不需要知道。

在任何情况下,不要只写这样的流函数,它远远不够健壮。 std::getline会让您在分隔符上拆分线条。当然,即使使用'std :: getline',您仍然可以进行适当的验证。您可以使用各种输入对其进行测试,例如,您可以给Shares一个方法来重建字段中的行,然后进行单元测试,将其与输入进行比较,以验证它是否相同。 / p>

看看这个function from torset,它解析了tor共识文件中的行,并只提取了ip地址和端口。 它将结果集存储在数据成员std::string _set;中,因为这不是将所有字段保留在数据结构中的目的。请注意,此函数不执行验证,因为它假定已正确形成tor共识文件。原则上这是一个危险的假设,理想情况下你永远不会在生产中运行它:

IpsetRestore::IpsetRestore( const std::stringstream& consensusIn, const std::string& setName )

:   consensus    ( consensusIn.str() )
  , setName      ( setName           )
  , _errorCode   ( 0                 )

{
    std::string              line      ;
    std::vector<std::string> fields    ;
    std::string              field     ;
    std::stringstream        lineStream;

    // get each line separately
    //
    while( std::getline( consensus, line ) )
    {
        fields    .clear();
        lineStream.clear();
        lineStream.str  ( line );


        // get each field
        //
        while( std::getline( lineStream, field, ' ' ) )

            fields.push_back( std::string( field ) );


        // only work on lines that interest us
        // sample: "r Unnamed VLNV4cpI/C4jFPVQcWKBtO2EBV8 2013-11-04 22:38:31 76.100.70.54 9001 9030"
        //
        if( fields.size() != 8 || fields[ 0 ] != "r" )

            continue;


        // write add lines in the ipset format
        // add [setName] [ip]:[port]
        // tor uses tcp and ipset defaults to tcp, so we won't put it in
        // fields 6 and 7 are the port fields, so if it's port 0, don't bother
        //
        for( int i = 6; i <= 7; ++i )
        {
            if( fields[ i ] == "0" )

                continue;


            _set.append
            (
                std::string( "add "      )
                .append    ( setName     )
                .append    ( " "         )
                .append    ( fields[ 5 ] )
                .append    ( ":"         )
                .append    ( fields[ i ] )
                .append    ( " -exist\n" )
            );
        }



    if( _set.empty() )
    {
        std::cerr << "Something went wrong, _set is empty. Maybe you passed the wrong inputfile or it was not formatted correctly." << std::endl;

        ++_errorCode;
    }
}