c++如何在一定程度上读取输入

c++ how to read input up to a certain point

本文关键字:读取 输入 一定程度 c++      更新时间:2023-10-16

嗨,我有一些输入行,顺序是:

Date, Time, Price, Volume, Value,

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

此输入有4000行,偶尔还会有一个共享代码,如"CX"或"NXXT"将出现在"value"逗号后面。

我的程序无法处理此问题并崩溃。

我需要的是忽略"value"后面逗号之后的任何内容,并继续阅读下一行。这将属于"股份"类别。

以下是我的类的输入流:

类别:"日期"

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
}

类别"股票"

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
}

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

无论如何,不要只写这样的流函数,它还远远不够健壮。std::getline将允许您在分隔符上拆分行。当然,即使使用"std::getline",您最好还是进行适当的验证。你可以用各种输入来测试它,例如,你可以给Shares一个从字段中重构行的方法,然后进行单元测试,将其与输入进行比较,以验证它是相同的。

看看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    ( " -existn" )
            );
        }

    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;
    }
}

编写一个函数,跳过直到并包括行的末尾。

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

当你知道你需要跳过所有内容,直到并包括行尾时,就使用它。