将长字符串分成多个c ++

时间:2011-05-25 15:05:59

标签: c++ string line

我有一个从第三方收到的字符串。此字符串实际上是文本文件中的文本,它可能包含用于行终止的UNIX LF或Windows CRLF。如何将其分解为多个字符串而忽略空行?我打算做以下事情,但不确定是否有更好的方法。我需要做的就是逐行阅读。这里的矢量只是一个方便,我可以避免它。 *很遗憾,我无法访问实际文件。我只收到字符串对象*

string textLine;
vector<string> tokens;

size_t pos = 0;
while( true ) {
    size_t nextPos = textLine.find( pos, '\n\r' );
    if( nextPos == textLine.npos )
        break;
    tokens.push_back( string( textLine.substr( pos, nextPos - pos ) ) );
    pos = nextPos + 1;
}

6 个答案:

答案 0 :(得分:6)

您可以在从文件中读取时使用std::getline,而不是将整个内容读入字符串。这将默认逐行破坏。你可以简单地不推送任何空的字符串。

string line;
vector<string> tokens;

while (getline(file, line))
{
    if (!line.empty()) tokens.push_back(line);
}

更新:

如果您无权访问该文件,则可以使用全文初始化stringstream来使用相同的代码。 std::getline适用于所有流类型,而不仅仅是文件。

答案 1 :(得分:3)

我使用getline基于\ n创建新字符串,然后操纵行结尾。

string textLine;
vector<string> tokens;

istringstream sTextLine;
string line;
while(getline(sTextLine, line)) {
  if(line.empty()) continue;
  if(line[line.size()-1] == '\r') line.resize(line.size()-1);
  if(line.empty()) continue;
  tokens.push_back(line);
}

编辑:使用istringstream代替stringstream

答案 2 :(得分:2)

我会使用这里给出的方法(std :: getline on std :: istringstream)...

Splitting a C++ std::string using tokens, e.g. ";"

...除了省略';'参数到std :: getline。

答案 3 :(得分:1)

很大程度上取决于工具包中已有的内容。我工作了很多 文件来自Windows并在Unix下读取,副本 反之亦然,所以我有大部分工具可以将CRLF转换成LF。 如果你没有,你可能想要一个函数:

void addLine( std::vector<std::string>& dest, std::string line )
{
    if ( !line.empty() && *(line.end() - 1) == '\r' ) {
        line.erase( line.end() - 1 );
    }
    if ( !line.empty() ) {
        dest.push_back( line );
    }
}

进行插入。至于将原始文本分成行, 您可以像其他人一样使用std::istringstreamstd::getline 建议;它简单明了,即使它有点矫枉过正。 (std::istringstream是一个相当重的机制,因为它支持 您不需要的各种输入转换。)或者,您 可能会考虑一个循环:

std::string::const_iterator start = textLine.begin();
std::string::const_iterator end   = textLine.end();
std::string::const_iterator next  = std::find( start, end, '\n' );
while ( next != end ) {
    addLine( tokens, std::string( start, next ) );
    start = next + 1;
    next = std::find( start, end, '\n' );
}
addLine( tokens, std::string( start, end ) );

或者你可以将事情分解为单独的操作:

textLine.erase(
    std::remove( textLine.begin(), textLine.end(), '\r'),
    textLine.end() );

摆脱所有的CR,

std::vector<std:;string> tokens( split( textLine, '\n' ) );

,将其分解为行,split是一个通用函数 沿着上面的循环(一个有用的工具添加到你的 工具包),最后:

tokens.erase(
    std::remove_if( tokens.begin(), tokens.end(), 
                    boost::bind( &std::string::empty, _1 ) ),
    tokens.end() );

。 (一般来说:如果这是一种情况,请使用 基于std::istringstream的解决方案。如果你认为你可能不得不这样做 将来不时会出现这种情况,添加split 功能到你的套件,并使用它。)

答案 4 :(得分:0)

您可以使用strtok

  

将字符串拆分为标记

     

对此函数的一系列调用   将str拆分为令牌,这是令牌   连续字符序列   由任何字符分隔   这是分隔符的一部分。

答案 5 :(得分:0)

我会将字符串放入字符串流中,然后像前面提到的答案一样使用getline方法。然后,当你真正来自另一个字符串时,你可能就像从文件中读取文本一样。