删除空格 - 按引用传递

removing spaces - pass by reference

提问人:jjjzzz 提问时间:11/17/2022 最后编辑:jjjzzz 更新时间:11/17/2022 访问量:250

问:

提示 - C++

编写一个程序,从给定的输入中删除所有空格。

例如:如果输入为:“你好,我的名字是约翰”,则输出为:

你好,我的名字是约翰。 程序必须定义并调用以下函数。该函数应返回一个字符串,表示不带空格的输入字符串。 void RemoveSpaces(字符串 &userString)

问题 - 我相信我的代码是正确的;我只是不太清楚通过引用传递的概念,所以我的代码在我的任务方面是错误的。这就是为什么我的输出在我的提交中仍然显示为带空格的字符串。

我如何使用引用传递来写这个?

我的代码 -

#include <iostream>
using namespace std;

void RemoveSpaces ( string &userString )
{
   unsigned int i ; 
   
   for ( i = 0 ; i < userString.size() ; i ++ )
   {
      if ( userString.at(i) != ' ' )
      {
         cout << userString.at(i) ;
      }
   }
} 

int main() {
   
   string userInputString ;
   
   getline ( cin, userInputString ); 
   
   RemoveSpaces ( userInputString ) ;
   
   cout << userInputString ; 

   return 0;
}

对于通过引用,我以为userString会在函数中“更新”并输出为更新版本?

C++ 字符串 按引用传递

评论

4赞 463035818_is_not_an_ai 11/17/2022
taks 要求您编写一个从字符串中删除空格的函数。您的代码不会这样做。您的函数打印字符串中不是空格的字符,这不是任务所要求的
0赞 463035818_is_not_an_ai 11/17/2022
您确实通过引用传递了字符串,但函数中的任何内容都不会修改字符串上的任何内容,那么为什么要修改字符串呢?main
0赞 jjjzzz 11/17/2022
@463035818_is_not_a_number通过创建另一个字符串并修改该字符串,同时将其设置为等于我的当前字符串来修改字符串?不知道该怎么做。
0赞 463035818_is_not_an_ai 11/17/2022
en.cppreference.com/w/cpp/string/basic_string

答:

4赞 john 11/17/2022 #1

这似乎是一个常见的新手困惑。打印与其他概念混淆。如果函数打印了某些内容,则该函数将“返回”打印的内容。这是完全不正确的,印刷就是印刷,仅此而已。

如果你想编写一个从字符串中删除空格的函数,那么这就是该函数必须做的。不知何故,必须创建一个没有空格的新字符串。该函数如何返回修改后的字符串是一个附带问题。

下面是一个从字符串中删除空格的函数。

void RemoveSpaces ( string &userString )
{
   string temp;
   for (size_t i = 0 ; i < userString.size() ; i ++ )
   {
      if (userString.at(i) != ' ' )
          temp.push_back(userString.at(i));
   }
   userString = temp;
}

此函数的工作原理是查找 中的非空格并将它们添加到新字符串中。这是没有空格的字符串。然后在函数结束时,它将此字符串赋回 。由于已通过引用传递,因此此赋值在 main 中修改。这就是通过引用传递的意义。更改以实际更改所引用的字符串。userStringtempuserStringuserStringuserInputStringuserString

可以编写一个直接修改的函数,但那是更复杂的代码,所以我选择用第二个字符串来做到这一点。userStringtemp

0赞 Serge Ballesta 11/17/2022 #2

首先几点意见:

  • 避免。它可能会在当前名称中加载过多的标识符,从而导致名称冲突。最好在标准标识符前加上前缀,或者显式导入您将使用的标识符using namespace stdstd::
  • 您正在使用标准标头中声明的版本,但不包括该标头。它在您的实现中有效,因为 C++ 允许标准标头的隐式包含,但在我的实现中失败了,因为没有自动加载......getline<string>iostreamstring

现在是你真正的问题。 可以在这里使用,因为它可以擦除字符串中的字符。您只需要使用迭代器浏览字符串并擦除所有空格字符即可。代码可以是:erase

void RemoveSpaces(string& userString)
{
    for (auto it = userString.begin(); it != userString.end();) { // no automatic increment here
        if (' ' == *it) {
            it = userString.erase(it);  // erase a space character
        }
        else {
            ++it;                       // or skip to next one
        }
    }
}
2赞 compli 11/17/2022 #3

在函数 RemoveSpaces 中,您正在打印不带空格的 srting,但不会更新它。因此,例如,字符串是“This is an example”,它只会打印“Thisisanexample”,但字符串的值仍然保持不变。您必须更新函数中字符串的值才能更新原始字符串值,通过引用传递不会自动执行此操作。

void RemoveSpaces ( string &userString )
{
   unsigned int i ; 
   int count = 0;
   for ( i = 0 ; i < userString.size() ; i ++ )
   {
      if ( userString.at(i) != ' ' )
      {
          userString.at(count++) = userString.at(i);
          cout << userString.at(i) ;
      }
   }
   userString.resize(count);
}

resize(count) 被添加,例如 原始字符串 - “This is an example” size - 18 更新的字符串 - “Thisisanexampleple” 大小 - 18 发生这种情况是因为更新的字符串的大小为 15(“Thisisanexample”),但原始字符串的大小为 18,因此它将从原始字符串中获取 18-15 = 3 个字符并将其保留在更新的字符串中。因此,您需要将更新的字符串大小调整为 15,即跟踪更新字符串大小的 count 变量。