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

Ale*_*las 20 c c++ string c-strings uppercase

当我在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;
}
Run Code Online (Sandbox Code Playgroud)

按预期输出:

FOOBAR
Run Code Online (Sandbox Code Playgroud)


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;
}
Run Code Online (Sandbox Code Playgroud)

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

OOBAR
Run Code Online (Sandbox Code Playgroud)

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

Nat*_*ica 30

问题是没有序列点

while (*beg++ = toupper(*beg));
Run Code Online (Sandbox Code Playgroud)

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

  • @markh不,因为这是两个不同的变量.这与`while(*s ++ =*s ++)`同义 (3认同)

R S*_*ahu 15

while (*beg++ = std::toupper(*beg));
Run Code Online (Sandbox Code Playgroud)

导致未定义的行为.

是否*beg++std::toupper(*beg)未指定之前或之后排序.

简单的解决方法是使用:

while (*beg = std::toupper(*beg))
   ++beg;
Run Code Online (Sandbox Code Playgroud)


小智 10

这条线

while (*beg++ = toupper(*beg));
Run Code Online (Sandbox Code Playgroud)

包含对正在使用两次的实体的副作用.你无法知道,是否在*beg之前或之后执行了beg ++(在toupper内部).你很幸运,两个实现都显示了这两种行为,因为我很确定它对C++来说是一样的.(但是,c ++ 11有一些规则变化,我不确定 - 但是,它的风格很糟糕.)

只是将beg ++移出条件:

while (*beg = toupper(*beg)) beg++;
Run Code Online (Sandbox Code Playgroud)