C ++从多行字符串中删除新行

Posted

技术标签:

【中文标题】C ++从多行字符串中删除新行【英文标题】:C++ Remove new line from multiline string 【发布时间】:2010-12-02 02:32:40 【问题描述】:

从 std::string 中删除“换行符”最有效的方法是什么?

【问题讨论】:

是否希望换行符出现在特定位置,例如字符串末尾? 没有;它可能在任何地方 【参考方案1】:

关于答案 3 仅删除最后一个 \n 关闭字符串代码:

if (!s.empty() && s[s.length()-1] == '\n') 
    s.erase(s.length()-1);

如果字符串真的为空,if条件会不会失败?

这样做不是更好吗:

if (!s.empty())

    if (s[s.length()-1] == '\n')
        s.erase(s.length()-1);

【讨论】:

不,第一个版本应该在字符串为空时中止if语句【参考方案2】:

在 for 循环中的另一种方法

void rm_nl(string &s) 
    for (int p = s.find("\n"); p != (int) string::npos; p = s.find("\n"))
    s.erase(p,1);

用法:

string data = "\naaa\nbbb\nccc\nddd\n";
rm_nl(data); 
cout << data; // data = aaabbbcccddd

【讨论】:

【参考方案3】:

这是 DOS 或 Unix 换行符:

    void chomp( string &s)
    
            int pos;
            if((pos=s.find('\n')) != string::npos)
                    s.erase(pos);
    

【讨论】:

if 更改为while 循环,您就有了一个很好的解决方案。【参考方案4】:

如果它在字符串中的任何位置都比你不能做得比 O(n) 更好。

唯一的方法是在字符串中搜索'\n'并删除它。

for(int i=0;i<s.length();i++) if(s[i]=='\n') s.erase(s.begin()+i);

换行符多于:

int n=0;
for(int i=0;i<s.length();i++)
    if(s[i]=='\n')
        n++;//we increase the number of newlines we have found so far
    else
        s[i-n]=s[i];
    

s.resize(s.length()-n);//to delete only once the last n elements witch are now newlines

它会删除所有换行符一次。

【讨论】:

这个实现不能正确处理连续的换行符,因为i不管元素是否被删除都会递增。【参考方案5】:

所有这些答案对我来说似乎有点沉重。

如果您只是完全删除“\n”并将其他所有内容移回一个位置,您很可能会以一种看起来很奇怪的方式将一些字符拼凑在一起。那么为什么不干脆做最简单(也是最有效)的事情:用空格替换所有 '\n's?

for (int i = 0; i < str.length();i++) 
   if (str[i] == '\n') 
      str[i] = ' ';
   

可能有一些方法可以提高边缘的速度,但它比在内存中移动整个字符串块要快得多。

【讨论】:

【参考方案6】:
 std::string some_str = SOME_VAL;
 if ( some_str.size() > 0 && some_str[some_str.length()-1] == '\n' ) 
  some_str.resize( some_str.length()-1 );

或(在末尾删除几个换行符)

some_str.resize( some_str.find_last_not_of(L"\n")+1 );

【讨论】:

【参考方案7】:
#include <algorithm>
#include <string>

std::string str;

str.erase(std::remove(str.begin(), str.end(), '\n'), str.end());

std::remove 的行为可能不是您所期望的。请参阅 here 的解释。

【讨论】:

如果其他平台有换行的机会,也可以删除'\r'字符。第二次调用 erase 和 std::remove 等在性能方面没什么大不了的。替代方法,例如将 std::remove_if 与谓词函数一起使用,可能会更慢。 如果您的数据最初是从以文本(ascii,非二进制)模式打开的文件加载的,我相信它会自动将所有换行符约定转换为简单的 '\n'。我正在寻找一个明确的参考来证实。 msdn.microsoft.com/en-us/library/kt0etdcs%28VS.71%29.aspx -- 那是 fread(),但我相信 iostream 读取和写入具有相同的行为。 std::remove 引用中的关键语句是 “调用 remove 之后通常会调用容器的擦除方法,该方法会擦除未指定的值并减小容器以匹配其新的逻辑大小。” 最后一行的最后一个参数可以是cend(),如str.erase(std::remove(str.begin(), str.end(), '\n'), str.cend());【参考方案8】:

代码从字符串str 中删除所有 个换行符。

O(N) 实现最好在 SO 上不使用 cmets 并且在生产中使用 cmets。

unsigned shift=0;
for (unsigned i=0; i<length(str); ++i)
    if (str[i] == '\n') 
        ++shift;
    else
        str[i-shift] = str[i];
    

str.resize(str.length() - shift);

【讨论】:

【参考方案9】:
s.erase(std::remove(s.begin(), s.end(), '\n'), s.end());

【讨论】:

【参考方案10】:

使用 std::算法。这个问题有一些适当的可重复使用的建议Remove spaces from std::string in C++

【讨论】:

【参考方案11】:

您应该使用erase-remove idiom,寻找'\n'。这适用于任何标准序列容器;不仅仅是string

【讨论】:

【参考方案12】:

如果换行符应该在字符串的末尾,那么:

if (!s.empty() && s[s.length()-1] == '\n') 
    s.erase(s.length()-1);

如果字符串可以在字符串的任何位置包含许多换行符:

std::string::size_type i = 0;
while (i < s.length()) 
    i = s.find('\n', i);
    if (i == std::string:npos) 
        break;
    
    s.erase(i);

【讨论】:

第一个版本完美。第二个版本会更容易使用 std::erase(std::removr(XXX)) 我从来没有对 remove() 的语义感到非常满意,并且总是不得不查找它,因为它并不明显。我上面的实现简单直接,但不是最有效的。如果效率很重要,则需要稍微不同的解决方案。 问题是,“什么是最有效的方法......”,所以我想效率很重要;)

以上是关于C ++从多行字符串中删除新行的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Perl 从文件中删除多行 C 注释?

c语言 从字符串中删除特定字符

从数据框中删除特定行[重复]

如何从 C 字符串中删除第一个字符?

C语言如何从数组中删除一个指定元素?

从字符串 C 中删除 char