大写字母

Ama*_*One 2 c++ algorithm iterator loops stdstring

我有一个小问题。我想利用字符串中的双字母大写。我设法编译了一个程序,但没有成功。

#include <iostream>
#include <cctype>
#include <string>

std::string::iterator function(
   std::string::const_iterator a, 
   std::string::const_iterator b,
   std::string::const_iterator e)
{
   for (; a < b; a++) 
   {
      if (*a == *(a + 1)) 
      {
         toupper(*a);
         toupper(*(a + 1));
      }
   }
}

int main()
{
   std::string in = "peppermint 1001 bubbles balloon gum", out(100, '*');
   auto e = function(in.cbegin(), in.cend(), out.begin());

   int n = e - out.begin();
   std::string s = out.substr(0, n);
   bool b = (s == "pePPermint 1001 buBBles baLLOOn gum");
   std::cout << std::boolalpha << b << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我做错了什么?

JeJ*_*eJo 5

你有几个问题。

首先,你的函数承诺返回 std::string::iterator

std::string::iterator function(....)
{
  //... return statement is missing here!
}
Run Code Online (Sandbox Code Playgroud)

而你没有遵守诺言。这将导致未定义的行为。例如,在您的情况下,它只是编译而不提供输出。

为了获得定义的行为,您应该从函数返回

std::string::iterator function(...)
{
   // ... code
   return {}; // return appropriately iterator of std::string
}
Run Code Online (Sandbox Code Playgroud)

其次,要修改字符串的字符,这需要一个可修改的迭代器而不是std::string::const_iterator.

然后在循环中,您需要char通过重新分配来更改大写的ector。例如:

*a = toupper(*a);
Run Code Online (Sandbox Code Playgroud)

第三,您应该小心在函数的 for 循环中执行此操作

 for(; a < b; a++)
 {
     if(*a == *(a + 1))  // --->here
     // ... code
 }
Run Code Online (Sandbox Code Playgroud)

如果a== str.end()-1,您仍然会执行增量(即 *(a + 1)),会发生什么情况,对吗?。再次增加结束迭代器会导致您未定义的行为

在这种情况下,您可以使用std::nextfrom <iterator>header 来安全地检查这一点。

以下是清除上述问题的演示代码:

#include <iostream>
#include <string>
#include <iterator>  // std::next

std::string::iterator function(
   std::string::iterator a, 
   std::string::iterator b, 
   std::string::iterator e)
{
   auto beg = a;
   for (; a < b; a++)
   {
      if (std::next(a) != b && *a == *std::next(a)) {
         *a = toupper(*a);
         *std::next(a) = toupper(*std::next(a));
      }
   }
   std::cout << std::string{ beg, b };
   return {}; // return appropriately iterator of std::string
}
Run Code Online (Sandbox Code Playgroud)

现在打印:https : //godbolt.org/z/ZsLHxw

pePPermint 1001 buBBles baLLOOn gum
Run Code Online (Sandbox Code Playgroud)

我假设您想以某种方式将输出输出到第三个函数参数std::string::iterator e。我会让那部分让你弄清楚。同时,看看标准算法函数std::transform,它可能会很方便地进行这种转换。