所以我编了一些代码:
#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
有人可以告诉我问题出在哪里吗?
此代码具有缓冲区溢出和未终止的字符串。这就是使用两个编译器获得不同结果的原因:您正在调用未定义的行为。
测试字符串有七个字符,三个小写和四个大写。
您将这些字符追加到smallStr
和bigStr
数组中,但这些数组仅具有要追加的实际字符的空间,而不允许使用 null 终止符。
设置 bigStr[q] = " ";
时,您已经用四个字符填充了bigStr
数组。空终止符正在数组末尾之后的未定义位置写入。
smallStr
数组根本不接收空终止符。如果是这样,它也将以与bigStr
相同的方式通过数组的末尾。
smallStr
和bigStr
的长度是硬编码的。如果使用不同的测试字符串会发生什么情况?
编写此代码的目标是什么?也许您应该考虑使用std::string
C++编写它以避免这些问题。
如果您确实想在没有字符串库的情况下用 C 编写它,请考虑对源字符串进行两次传递。第一次传递将仅计算小写和大写字符的数量。然后,您可以分配两个正确大小的数组(不要忘记 null 终止符)。然后,第二次传递可以填充两个数组,并将空终止符附加到每个数组。