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

C string to uppercase in C and C++

当我在 C++ 中组合一个 to-uppercase 函数时,我注意到我在 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 编译时结果会被截断?

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

导致未定义的行为。

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

简单的解决方法是使用:

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

问题是

中没有序列点
while (*beg++ = toupper(*beg));

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

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

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

把beg++移出条件即可:

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

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

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