drd*_*dot 5 c string arguments
我想将参数字符串复制到程序中的数组中.所以我写了下面的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
// go through each string in argv
int i = 0;
while(i < argc){
printf("arg %d: %s\n", i, argv[i]);
i++;
}
//let's make our own array of strings
char *states[] = {"California", "Oregon", "Washington", "Texas"};
int num_states = 4;
i = 0; //watch for this
while(i < num_states) {
printf("state %d: %s\n", i, states[i]);
i++;
}
//copy argv into strings
char **dst;
dst = (char**)malloc(sizeof(char*)*argc);
for(i = 0; i < argc; i++){
dst[i] = (char*)malloc(sizeof(char)*sizeof(argv[i]));
}
i = 0;
while(i < argc){
strncpy(*dst+i, argv[i], sizeof(argv[i]));
printf("*dst = %s\n", *dst+i);
i++;
}
for(i = 0; i < argc; i++){
free(dst[i]);
}
free(dst);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
代码工作正常.但是有一个汇编警告:
cc -Wall -g -o ex11 ex11.c
ex11.c: In function ‘main’:
ex11.c:31:34: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess]
strncpy(*dst+i, argv[i], sizeof(argv[i]));
Run Code Online (Sandbox Code Playgroud)
我怎么能摆脱这个警告?
更新1:我将dst指针的分配更改为以下内容:
for(i = 0; i < argc; i++){
//dst[i] = (char*)malloc(sizeof(char)*sizeof(argv[i]));
dst[i] = (char*)malloc(strlen(argv[i]+1));
}
// ignore malloc null return
printf("test 1 = %d\n", sizeof(char)*sizeof(argv[i]));
printf("test 2 = %d\n", strlen(argv[i]));
Run Code Online (Sandbox Code Playgroud)
我想知道测试1和测试2是否会产生相同的数字.但对于测试2,它抱怨分段错误.这是为什么?
更新2:根据评论摆脱malloc循环:
//copy argv into strings
char **dst;
dst = (char**)malloc(sizeof(char*)*argc);
i = 0;
while(i < argc){
dst[i] = strdup(argv[i]); //array version: strdup
printf("*dst = %s\n", *(dst+i));
i++;
}
Run Code Online (Sandbox Code Playgroud)
编译器是正确的,并告诉你一个危险的bug.您正在使用指针的大小,而不是指向它的字符串的大小.(实际的警告是说你要指定基于源复制的长度,这样做strcpy就像strncpy.在这种情况下它是错误的,因为它没有注意到它是指针的大小而不是数组.)
你也有一个严重的错误,与之*dst+i相同dst[0] + i,不是dst[i].你有i独立分配的指针,最好全部使用它们.
你应该改用
dst[i] = (char*)malloc(strlen(argv[i]) + 1); // remember space for the NUL character
Run Code Online (Sandbox Code Playgroud)
和
strcpy(dst[i], argv[i]);
Run Code Online (Sandbox Code Playgroud)
或者更好,只是
dst[i] = strdup(argv[i]);
Run Code Online (Sandbox Code Playgroud)
它进行分配和复制.