我有一个从第三方收到的字符串。此字符串实际上是文本文件中的文本,它可能包含用于行终止的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;
}
答案 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::istringstream
和std::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方法。然后,当你真正来自另一个字符串时,你可能就像从文件中读取文本一样。