我想进一步了解C字符串及其在幕后的工作方式。我声明了3个字符串,分别为53、11和33个字节长(包括每个字符串末尾的\0
)。然后,我将它们连接到一个新字符串to_be_used
,并将其手动设置为 33个字节长(我通过反复试验发现了该值,直到该值较小时结果字符串变得奇怪为止)然后33)。请输入以下代码:
void generate_random_password(int password_lenght, int has_special_characters)
{
const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char digits[] = "0123456789";
const char special_characters[] = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
char random_password[password_lenght + 1];
if(has_special_characters == 1)
{
char to_be_used[33];
strcat(to_be_used, letters);
strcat(to_be_used, digits);
strcat(to_be_used, special_characters);
printf("%s\n", to_be_used);
printf("%d\n%d\n%d\n%d\n", sizeof(letters), sizeof(digits), sizeof(special_characters), sizeof(to_be_used));
}
}
此代码的输出是:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
53
11
33
33
此函数调用的每个参数都将第一个参数设置为17,将最后一个参数设置为1。
来自strcat()
调用的结果字符串正是我所期望的。我的问题是:即使3个字符串的大小之和为94(不包括每个字符串结尾的\ 0)并且我将结果字符串设置为33,为什么仍会编译此代码?
我希望我解释对了。
请,如果有人知道编写此代码的更好方法(当然是这样),请回答我该代码如何更好,例如使用指向char,malloc()的指针或其他方法。谢谢!
PS:此功能尚未完成。 PS2:我是C编程的初学者。
答案 0 :(得分:0)
超出范围写入数组是未定义的行为,这意味着任何事情都可能发生。这就像玩俄罗斯轮盘赌。在这个特定程序中,您碰巧遇到了麻烦,并使其覆盖了一些相对不重要的内存(可能是button *{class: sales_button(sales) } type="button"
),因此它似乎可以正常工作。下次您可能不会那么幸运。
答案 1 :(得分:0)
分配足够的内存是您的责任。
当您违约时,编译器没有义务抓住您。 strcat
的约定是目标数组足够大以容纳结果。如果不遵守,则行为是不确定的。有关更多信息,请参见undefined behaviour。
顺便说一句,您不能strcat
未初始化的字符串。
char to_be_used[33];
strcat(to_be_used, letters); // <- uninitialised, another instance of undefined behaviour