【问题标题】:toupper function in C with for loopC中的toupper函数与for循环
【发布时间】:2016-09-21 13:43:36
【问题描述】:

我不明白为什么下面的代码不能按我想要的那样工作。

int main()
{
    char sentence[] = "this will be capitalised";
    int i;

    for (i=0; i<strlen(sentence); i++)
    {
        toupper(sentence[i]);
        putchar(sentence[i]);
    }

    printf("\n\n");

    return (0);
}

我最终得到了这个:

this will be capitalised

Program ended with exit code: 0

谢谢

【问题讨论】:

  • toupper 返回大写字母。您必须分配回源字符串:sentence[i] = toupper(sentence[i]);
  • putchar(toupper(sentence[i])) 如果不再需要结果。
  • 技术上应该是toupper((unsigned char)sentence[i]),以防我们在EBCDIC机器上
  • @M.M 在 EBCDIC 机器上,unsigned char 通常不需要,因为char 通常在那里没有签名。它是在其他具有char 签名的常见情况的机器上,需要(unsigned char) 演员。

标签: c string loops


【解决方案1】:

换行:

   toupper(sentence[i]);

用这个:

   sentence[i] = toupper(sentence[i]);

您的代码的问题是toupper 没有进行适当的转换,而是将转换后的字母作为返回值返回。

如果您不想修改字符串,只想以大写形式打印,请使用 WolfieeifloW 的解决方案。

编辑:正如其他人指出的那样,strlen 是一个慢速函数(它必须扫描整个字符串,因此需要Θ(n) 时间),此处提供的解决方案将阻止编译器从进行智能优化到评估一次。因此,最好自己预先评估它,如下所示:

int len = strlen(sentence);

for (i=0; i<len; i++)

【讨论】:

  • 这段代码修改了sentence[],这当然是OP想要/需要的。副作用是代码无法优化对strlen() 的调用,因此需要重复strlen() 调用。结果:O(n*n) 运行时。更改循环结束条件将有助于改进代码。
【解决方案2】:

toupper(sentence[i]); 不会修改它的参数,而是返回它。因此,解决方案是将循环体中的第一条语句替换为

sentence[i] = toupper((unsigned char)sentence[i]);

为了便携性,我还加入了(unsigned char) 演员表(致谢@M.M)。 (EBCDIC 编码要求字母数字字符为 8 位。)

另外,因为你正在改变sentence,我想地球上没有编译器会将strlen(sentence) 的多个调用优化为单个调用。你的 O(N) 算法突然变成了 O(N * N)!考虑预先计算它,向后运行循环,还是使用sentence[i] 作为停止表达式来实现它? (致谢@nwellnhof)。

【讨论】:

    【解决方案3】:

    尝试使用 while 循环:

    int i = 0;    
    
    while(sentence[i]) {
        putchar(toupper(sentence[i]));
        i++;
    }
    

    这也有助于避免在每个循环中计算 strlensentence[]

    【讨论】:

    • 赞成。这要好得多:它避免了我提到的strlen 的重复计算。
    • @redneb 的答案更好,但我会提出putchar(toupper(sentence[i]));
    • 为什么不for (i = 0; sentence[i]; i++)
    • @WolfieeifloW - 是的,有理由投反对票 - 尽管我没有。 OP 没有阅读 toupper 的手册页,这是一个致命错误。
    猜你喜欢
    • 2022-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多