【问题标题】:Loop quitting for no reason无故退出循环
【发布时间】:2011-08-28 22:40:43
【问题描述】:

我有一个关于 C++ 的问题。这是我目前的功能:

string clarifyWord(string str) {
    //Remove all spaces before string
    unsigned long i = 0;
    int currentASCII = 0;

    while (i < str.length()) {
        currentASCII = int(str[i]);
        if (currentASCII == 32) {
            str.erase(i);
            i++;
            continue;
        } else {
            break;
        }
    }

    //Remove all spaces after string
    i = str.length();
    while (i > -1) {
        currentASCII = int(str[i]);
        if (currentASCII == 32) {
            str.erase(i);
            i--;
            continue;
        } else {
            break;
        }
    }
    return str;
}

只是为了让基本和显而易见的事情变得简单,我有 #include &lt;string&gt;using namespace std; 所以我可以访问字符串函数。

问题是循环正在退出,有时会跳过第二个循环。我将str 传递为" Cheese ",它应该删除字符串之前和字符串之后的所有空格。

在主函数中,我还将一个变量分配给clarifyWord(str),其中str 在上面。使用cout &lt;&lt; str; 似乎也没有打印出来。

打印出字符串或使用字符串循环时有什么遗漏吗? ASCII码32也是Space

【问题讨论】:

标签: c++ string loops iterator cout


【解决方案1】:

好的,您调用的擦除函数如下所示:

string& erase ( size_t pos = 0, size_t n = npos );

n 参数是要删除的项目数。 npos 的意思是,删除直到字符串末尾的所有内容,因此将第二个参数设置为 1。

str.erase(i,1)

[编辑]

你可以把第一个循环改成这样:

while (str.length() > 0 && str[0] == ' ')
{
   str.erase(0,1);
}

第二个循环:

while (str.length() > 0 && str[str.length() - 1] == ' ')
{
   str.erase(str.length() - 1, 1);
}

【讨论】:

    【解决方案2】:

    在您的第二个循环中,您无法将 i 初始化为 str.length()。

    str[str.length()] 将位于字符串的末尾,因此不太可能是空格(因此会触发第二个循环的中断)。

    【讨论】:

    • 嗯...好吧,我想我明白了。话虽如此,我将如何删除字符串末尾的空格?反转字符串,然后重复第一个循环,然后再反转回来?
    【解决方案3】:

    您在循环检查其大小时正在使用erase(修改字符串)。这是处理字符串的危险方式。当您返回一个新字符串时,我建议您首先搜索字符串中第一个出现的非空格字符,然后是最后一个,然后返回一个子字符串。类似于(未测试)的东西:

    size_t init = str.find_first_not_of(' ');
    if (init == std::string::npos)
        return "";
    size_t fini = std.find_last_not_of(' ');
    return str.substr(init, fini - init + 1);
    

    你看,没有循环、擦除等。

    【讨论】:

      【解决方案4】:

      unsigned long i ... while (i &gt; -1) 嗯,这不对,是吗?你希望它如何工作?编译器实际上会将两个操作数转换为相同的类型:while (i &gt; static_cast&lt;unsigned long&gt;(-1))。这只是编写 ULONG-MAX 的另一种方式,即while (i &gt; ULONG_MAX)。换句话说,while(false)

      【讨论】:

      • 好的,我想我已经解决了 :) 我已将 while (i &gt; -1) 替换为 while (i &gt;= 0),因为如果它等于 0,我希望循环运行,以检查第一个字符字符串。
      • @Brandon:i 还没有签名吗?因为 unsigned 的定义总是 >= 0。你只是把它变成了 while (true)
      【解决方案5】:

      您使用擦除不正确。它会从 pos 擦除到 npos。
      即字符串&擦除(size_t pos = 0, size_t n = npos);

      见:http://www.cplusplus.com/reference/string/string/erase/

      更好的方法是记下第一个非空格的位置以及空格出现在字符串末尾的位置。然后使用 substr 或擦除两次。

      您也不必费心这样做:

       currentASCII = int(str[i]);
             if (currentASCII == 32) {
      

      改为这样做:

      if (str[i] == ' ') {
      

      我想你会同意它更容易阅读。

      因此,您可以通过以下方式缩短它:(未经测试,但应该不会太远 关闭)

      string clarifyWord(string str) {
        int start = 0, end = str.length();
        while (str[start++] == ' ');
        while (str[end--] == ' ');
        return str.substr(start, end);
      }
      

      【讨论】:

        猜你喜欢
        • 2016-11-07
        • 2020-11-23
        • 2020-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多