【问题标题】:Transform uppercase letters to lowercase and vice-versa using single parameter function (C++)使用单参数函数 (C++) 将大写字母转换为小写字母,反之亦然
【发布时间】:2022-01-08 03:03:39
【问题描述】:

我有 trans 函数,它使用单个参数,必须为 void,并通过 c 返回 main 中输入的单词的字母的相反大小写。

Example:
input: dOgdoG
output: DoGDOg

该函数确实改变了大小写,但我无法找到构建新词/替换旧词的方法,因为我不断收到有关“const char”或“无效转换”的编译错误。

以下程序给出错误“从charconst char* 的无效转换

我只是出于示例目的更改了函数的类型。

#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;

char trans(char c)
{
    if(c >= 'a' && c <= 'z')
        return c-32;
    else
        if(c >= 'A' && c <= 'Z')
            return c+32;
}

int main()
{
    char s[101], s2[101] = "";
    cin >> s;
    int i;
    for(i=0; i<strlen(s); i++)
    {
        strncat(s2, trans(s[i]), 1);
    }
    cout<<s2;
    return 0;
}

编辑: 我从char 函数更改为void 函数并删除了for 的主体。

void trans(char c)
{
    if(c >= 'a' && c <= 'z')
        c-=32;
    else
        if(c >= 'A' && c <= 'Z')
            c+=32;
}

int main()
{
    char s[101], s2[101] = "";
    cin >> s;
    int i;
    for(i=0; i<strlen(s); i++)
    {
        /// i dont know what to put here
    }
    cout<<s2;
    return 0;
}

【问题讨论】:

  • 查找touppertolower 函数。
  • 不要乱搞strncat;你知道s2 足够大来保存结果,因为你是这样写的。所以就去做吧:s2[i] = trans(s[i]);。并且不要忘记 nul 终止符;它在最后一个字符之后,所以循环到strlen(s) 不会到达它。
  • @PeteBecker:或者直接对s进行更改。
  • @ScottHunter - 也许,但问题是关于“构建新词/替换旧词”,问题中的代码构建新词。
  • for 循环中包含i&lt;strlen(s) 可能意味着您的循环具有O(N*N) 时间复杂度,其中Ns 的长度,因为strlen(s) 本身具有@987654346 @ 复杂性,for 循环本身运行 N 次。我建议在循环之前使用语句int len = strlen(s);,然后使用i&lt;len 而不是i&lt;strlen(s)。 (看看joelonsoftware.com/2001/12/11/back-to-basics/.

标签: c++ string word uppercase lowercase


【解决方案1】:

不要重新发明轮子。标准库具有识别大写和小写字母以及更改大小写的功能。使用它们。

char trans(char ch) {
    unsigned char uch = ch; // unfortunately, character classification function require unsigned char
    if (std::isupper(uch))
        return std::tolower(uch);
    else
        return std::toupper(uch);
}

您可能倾向于将 else 分支更改为 else if (std::islower(uch) return std::toupper(uch); else return uch;,但这不是必需的; std::toupper 只是将小写字母改成大写,所以不会影响非小写字符。

然后,当你调用它时,只需复制结果:

int i = 0;
for ( ; i < strlen(s); ++i)
    s2[i] = tran(s[i]);
s2[i] = '\0';

编辑:

由于似乎需要以艰难的方式做事,所以让我们更改 trans 以匹配:

void trans(char& ch) {
    unsigned char uch = ch; // unfortunately, character classification function require unsigned char
    if (std::isupper(uch))
        ch = std::tolower(uch);
    else
        ch = std::toupper(uch);
}

现在,您可以将其应用到位:

for (int i = 0; i < strlen(s); ++i)
    trans(s[i]);

我称其为“困难方式”,因为使用 trans 的原始版本,您可以直接使用它来修改原始字符串:

for (int i = 0; i < strlen(s); ++i)
    s[i] = trans(s[i]);

你可以用它来复制字符串:

for (int i = 0; i < strlen(s); ++i)
    s2[i] = trans(s[i]);
// don't forget the terminating nul

通过引用传递,您可以就地修改;复制需要额外的步骤:

strcpy(s2, s1);
for (int i = 0; i < strlen(s); ++i)
    trans(s2[i]);

【讨论】:

  • 不想重新发明任何东西,我知道那些功能,但我需要按照我的方式去做,另外,我确实提到 char 功能仅用于示例目的,因为我需要使用void 函数,这是我不明白该怎么做我将编辑问题以使其更明显
【解决方案2】:

strncat 接受 2 个字符串 和一个数字作为参数;您的第二个参数是 char,而不是字符串。

【讨论】:

    【解决方案3】:

    您可以将std::transformstd::isupperstd::toupper 等字符串实用函数一起使用,小写字母类似。因为,问题被标记为 std::string 优于 const char*1 对于字符串。

    #include <string>
    #include <cctype>
    #include <iostream>
    #include <algorithm>
    
    char trans(unsigned char c){
    
       if (std::isupper(c)) 
          return std::tolower(c);
       else if (std::islower(c)) 
          return std::toupper(c);
       else
          return c;
    }
    
    int main(){
      std::string s = "dOgdoG12";
      std::string out;
      out.resize(s.length());
      
      std::transform(s.begin(), s.end(), out.begin(), trans);
      std::cout << out; // DoGDOg12
    }
    

    Demo


    1. 在char* vs std::string发帖

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      • 2022-11-05
      • 2017-07-29
      相关资源
      最近更新 更多