记事本中的代码和 VS 中的代码之间存在一些差异



所以我编了一些代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#define SMALLSTRLEN 3
#define BIGSTRLEN 4
#define SMALLASCIIA 97
#define BIGASCIIA 65
#define BIGASCIIZ 90
#define SMALLASCIIZ 122
int main(void)
{
    int i = 0,j=0,q=0;
    char str[] = "SHaddOW";
    char smallStr[SMALLSTRLEN];
    char bigStr[BIGSTRLEN];
    printf("%s", str);
    for (i = 0; str[i]; i++)
    {
        if ((str[i] >= SMALLASCIIA) && (str[i] <= SMALLASCIIZ))
        {
            smallStr[j] = str[i];
            j++;
        }
        else if ((str[i] >= BIGASCIIA) && (str[i] <= BIGASCIIZ))
        {
            bigStr[q] = str[i];
            q++;
        }
    }
    bigStr[q] = "";
    puts(smallStr);
    puts(bigStr);
    printf("nnn%s", bigStr);
    //getchar();
    system("PAUSE");
    return 0;
}

bigStr需要包含原始str中的所有大写字母,smallStr需要包含所有小写字母。带有 gcc 编译器的记事本++中的输出为:bigStr= SHOWadd , smallStr = add

有人可以告诉我问题出在哪里吗?

此代码具有缓冲区溢出和未终止的字符串。这就是使用两个编译器获得不同结果的原因:您正在调用未定义的行为。

测试字符串有七个字符,三个小写和四个大写。

您将这些字符追加到smallStrbigStr数组中,但这些数组仅具有要追加的实际字符的空间,而不允许使用 null 终止符。

设置 bigStr[q] = ""; 时,您已经用四个字符填充了bigStr数组。空终止符正在数组末尾之后的未定义位置写入。

smallStr数组根本不接收空终止符。如果是这样,它也将以与bigStr相同的方式通过数组的末尾。

smallStrbigStr的长度是硬编码的。如果使用不同的测试字符串会发生什么情况?

编写此代码的目标是什么?也许您应该考虑使用std::string C++编写它以避免这些问题。

如果您确实想在没有字符串库的情况下用 C 编写它,请考虑对源字符串进行两次传递。第一次传递将仅计算小写和大写字符的数量。然后,您可以分配两个正确大小的数组(不要忘记 null 终止符)。然后,第二次传递可以填充两个数组,并将空终止符附加到每个数组。

最新更新