我正在将一个脚本从Bash转换为C。我是C的新手。有很多东西需要我学习。我有代码,我有调试。一个变量的printf与从substr构建的内容输出意外的结果。
作为一个学习概念:
#include <stdio.h>
#include <string.h>
int main() {
char one[5] = "abcde";
char two[3] = "fgh";
char three[8] = "ijklmnop";
int size = strlen( one ) + strlen( two ) + strlen( three );
char str[ size ];
strcpy( str, one );
strcat( str, "_" );
strcat( str, two );
strcat( str, "_" );
strcat( str, three);
printf( "string is: %s\n", str );
return 0;
}
字符串
我得到的结果如下:
string is: nop abcdefghijklmnopabd
型
很明显,内存没有得到适当的管理,我很困惑,因为上面的例子看起来像是一个很好的函数教科书用例。
我尝试了许多调试技术;然而,这是我用过的最低层的堆栈语言。
2条答案
按热度按时间oymdgrw71#
你有未定义的行为,因为你的数组没有为null终止符留下空间。
字符串
这不是有效的C字符串。以下是:
型
或者让编译器计算出数组需要多大:
型
完成后,您需要使
str
足够大,以容纳空终止符和两个'_'
字符。虽然在这种情况下不太可能有任何实际影响,但将size
输入为size_t
比int
更正确。型
由于您没有修改
one
、two
或three
,因此可能只是将它们声明为指向字符串的指针。型
5cnsuln72#
让编译器为您计数:
char one[5] = "abcde";
->char one[] = "abcde";
或者更好的是:
const char *one = "abcde";
,如果你不需要修改这些字符串。strcpy
和strcat
容易发生缓冲区溢出,请考虑使用snprintf
,snprintf
的一个优点是(在malloc
的帮助下)您不需要硬编码最终大小(在您的情况下为size + 3
)字符串
当然,你可以像在你的代码片段中那样使用
char str[size];
,但我个人更喜欢避免使用VLA。