如果我有以下代码:
main(int argc, char *argv[]){
char serveradd[20];
strcpy(serveradd, argv[1]);
int port = atoi(argv[2]);
printf("%s %d \n", serveradd, port);
打印命令行的前两个参数。但是,如果我这样做:
char serveradd[20];
strcpy(serveradd, argv[1]);
int port = atoi(argv[2]);
char versionnum[1];
strcpy(versionnum, argv[3]);
printf("%s %d %s \n", serveradd, port, versionnum);`
第一个参数(serveradd)不会打印到屏幕上而没有存储...为什么会发生这种情况?如何解决?谢谢!
答案 0 :(得分:10)
char versionnum[1];
strcpy(versionnum, argv[3]);
疯狂的猜测,但你用这些线粉碎堆栈。让versionnum
更大;就目前而言,它只能安全地保持空字符串。
答案 1 :(得分:3)
你可能正在用
来记忆char versionnum[1];
strcpy(versionnum, argv[3]);
假设任何非空的以空字符结尾的字符串将是> 1个字符长。
永远不要使用直接strcpy();改为使用strncpy()(注意 - 1以保留空终止符的空间):
char serveradd[20] = { 0 };
strncpy(serveradd, argv[1], sizeof(serveradd) - 1);
int port = atoi(argv[2]);
char versionnum[2] = { 0 };
strcpy(versionnum, argv[3], sizeof(versionnum) - 1);
printf("%s %d %s \n", serveradd, port, versionnum);
答案 2 :(得分:1)
使用strcpy
而不使用正在复制的字符串的strlen
来测试长度,以确保它适合目标缓冲区是一个非常糟糕的主意。您应该使用strncpy
,这是经过长度检查的,不会超出目标缓冲区。
您不能将字符串存储在长度为1的char数组中,因为null终止符占用一个字符,因此您可以存储的所有字符都是空字符。几乎可以肯定你是在超越你的缓冲区。
答案 3 :(得分:1)
我认为上面的答案解决了你的问题,但是在将来尝试在调试时对内存分配更加慷慨。如果您认为需要5个元素,请创建一个定义make it 10,然后如果您想为null终止符留出空间,则将其更改为5或6。此外,如果您发现自己分配了一个长度为1的数组,请停下来问问原因。如果你有一个元素,只需使用一个普通变量。
每当我遇到argc和argv的问题时,首先想到的就是将它们打印出来,看看我是否有我想的那样。
答案 4 :(得分:0)
它以你描述的方式对我有用。我的猜测是你在其中一个字符串中超过了字符限制。我使用strncpy而不是strcpy。
答案 5 :(得分:0)
另一种方法是使用strdup()在堆上分配内存,这样就不会溢出缓冲区。在你的情况下,因为变量将在程序的生命周期中存在,所以这不是很糟糕,或者你可以使用free()在上次使用变量之后立即释放内存。确保之后不要使用变量!下面是一些示例代码。
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
int main(int argc, char *argv[])
{
char *serveradd = NULL;
int port;
char *versionnum = NULL;
if (argc != 4)
{
printf("Usage: %s SERVERADD PORT VERSIONNUM\n", argv[0]);
exit(126);
}
serveradd = strdup(argv[1]);
port = atoi(argv[2]);
versionnum = strdup(argv[3]);
if ((serveradd == NULL) || (versionnum == NULL))
{
perror("Could not allocate command line arguments");
exit(125);
}
printf("%s %d %s \n", serveradd, port, versionnum);
free(serveradd);
free(versionnum);
serveradd = NULL;
versionnum = NULL;
exit(0);
}