在 C 和 C++ 中将 C 字符串转换为大写

Posted

技术标签:

【中文标题】在 C 和 C++ 中将 C 字符串转换为大写【英文标题】:C string to uppercase in C and C++ 【发布时间】:2016-01-10 05:17:24 【问题描述】:

当我在 C++ 中组合一个大写函数时,我注意到在 C 中我没有收到预期的输出。

C++ 函数

#include <iostream>
#include <cctype>
#include <cstdio>

void strupp(char* beg)

    while (*beg++ = std::toupper(*beg));


int main(int charc, char* argv[])

    char a[] = "foobar";
    strupp(a);
    printf("%s\n", a);
    return 0;

按预期输出:

FOOBAR


C 函数
#include <ctype.h>
#include <stdio.h>
#include <string.h>

void strupp(char* beg)

    while (*beg++ = toupper(*beg));


int main(int charc, char* argv[])

    char a[] = "foobar";
    strupp(a);
    printf("%s\n", a);
    return 0;

输出是缺少第一个字符的预期结果

OOBAR

有谁知道为什么在 C 中编译时结果会被截断?

【问题讨论】:

如果你真的想在C++中这样做:std::transform(a, a + strlen(a), a, std::toupper); 您能解释一下为什么您希望这会将字符串转换为大写吗?具体来说,您为什么希望 = 的右侧在左侧之前被评估? 感谢所有提供反馈和提供宝贵信息的人 @Schullz 我坚信从错误中吸取教训是避免再次犯同样错误的最有效方法。因此,由于这个问题完全源于实验,而不是在团队项目环境中,我认为编写这段代码 sn-p 开始是一个错误 @MillieSmith 在这种情况下,将哪个项目变为大写的顺序是否重要?无论如何,大多数(如果不是全部)改变字符串的经典 C++ 方法都使用std::transform 【参考方案1】:

问题是里面没有序列点

while (*beg++ = toupper(*beg));

所以我们有未定义的行为。在这种情况下,编译器正在做的是在 toupper(*beg) 之前评估 beg++ 在 C 中,而在 C++ 中它以另一种方式进行。

【讨论】:

这是否意味着经典的 c 字符串复制单行 while(*s++ = *t++) ; 具有未定义的行为? @markh 否,因为这是两个不同的变量。这是while (*s++ = *s++)的同义词 @SteveJessop 实际上,while(*s++ = *t++); 已经定义了行为,即使 s == t 也是如此。 strcpy 未定义重叠区域的原因是 strcpy 不一定用 while(*s++ = *t++); 实现。 @immibis:公平点,同意它的定义。然而,即使strcpy 是通过该循环实现的,它对于一个重叠的“方向”仍然具有未定义的行为。如果目标大于源并且它们重叠,则终止的 nul 在读取之前被覆盖,最终缓冲区溢出!在两个“方向”上禁止重叠的原因是可能的其他实现。【参考方案2】:
while (*beg++ = std::toupper(*beg));

导致未定义的行为。

未指定*beg++ 是在std::toupper(*beg) 之前还是之后排序。

简单的解决方法是使用:

while (*beg = std::toupper(*beg))
   ++beg;

【讨论】:

【参考方案3】:

线

while (*beg++ = toupper(*beg));

包含对被使用两次的实体的副作用。您无法知道 beg++ 是在 *beg 之前还是之后执行(在 toupper 内部)。您很幸运,两种实现都显示了两种行为,因为我很确定 C++ 也是如此。 (但是,c++11 有一些规则更改,我不确定 - 仍然是不好的风格。)

只需将 beg++ 移出条件即可:

while (*beg = toupper(*beg)) beg++;

【讨论】:

【参考方案4】:

关于上面的答案,'f' 永远不会在函数内部传递,你应该尝试使用这个:

     while ((*beg = (char) toupper(*beg))) beg++;

【讨论】:

转换为 char 很重要,因为 int 类型的值可能不适合接收器类型 char 那个演员没有任何成就,如果没有它就不会发生。

以上是关于在 C 和 C++ 中将 C 字符串转换为大写的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中将字符串转换为向量

在c ++中将小写字符更改为大写

如何在 C++ 中将字符串转换为字符? [复制]

c++ 不使用 C 标准库将字符串和 int 转换为 char*

如何在c ++中将数组字节转换为字符串?

在c ++中将负整数转换为二进制字符串