一个新手关于删除非 Upper-alpha 的快速问题:为什么我的代码不工作?

A quick question from a newbie about deleting non-Upper-alpha: why isn't my code working?

您好,我正在尝试从字符串输入中删除所有非大写字母,但我不太确定我的编码中的错误在哪里。知道原因的请留言!

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

string CreateAcronym(string userPhrase) {
int i;
int stringSize;
char charAti;

stringSize = userPhrase.size();

for (i=0 ; i < stringSize ; i++ ) {
   charAti = userPhrase.at(i);
   if ( !isupper(charAti)) {
      userPhrase.erase(i,1);
   }
}
return userPhrase;
}

int main() {
string userSentence;

getline(cin , userSentence);

cout << CreateAcronym(userSentence) << endl;

return 0;
}

您的代码中有 2 个问题。

首先,您要擦除循环内的字符串(这会更改其长度),但在比较中使用预先计算的长度。

其次,你只需要在不擦除一个字符的情况下增加i。否则,您将跳过一些字符。

一个工作循环是:

for (i = 0; i < userPhrase.size();) {
   charAti = userPhrase.at(i);
   if ( !isupper(charAti)) {
      userPhrase.erase(i,1);
   }
   else {
     ++i;
   }
}

您可以使用算法简化此循环:

string CreateAcronym(string userPhrase) {

 userPhrase.erase(std::remove_if(userPhrase.begin(), 
                    userPhrase.end(), [](auto charAti) { 
                      return !isupper(charAti); }), 
                  userPhrase.end());

 return userPhrase;
}

这是 demo

  • 您缓存了旧的字符串长度并继续使用,而字符串将通过擦除字符变得更短。
  • 您跳过要擦除的字符后的字符,因为 i++ 不会在擦除后取消。
stringSize = userPhrase.size();

for (i=0 ; i < stringSize ; i++ ) {
   charAti = userPhrase.at(i);
   if ( !isupper(charAti)) {
      userPhrase.erase(i,1);
   }
}

应该是

for (i=0 ; i < static_cast<int>(userPhrase.size()) ; ) {
   charAti = userPhrase.at(i);
   if ( isupper(charAti)) {
      i++;
   } else {
      userPhrase.erase(i,1);
   }
}

这个问题已经被其他人回答了,所以我只是添加我的"simpler"解决问题的方法:

string CreateAcronym(string userPhrase) {
    string result;  // Create an empty string

    // Loop over all the characters in the original string
    for (char c : userPhrase) {
        // If the character is upper-case...
        if (isupper(c))
            result += c;  // Append it to the new string
    }

    return result;  // Return the new string
}