int main(int argc, char *argv[])
{
char string[100];
string = *argv[1];
}
为什么这行不通?我是否真的需要使用循环来遍历每个元素,并做长远的事情?
答案 0 :(得分:4)
为什么不起作用?
因为这就是在C语言中的工作方式。尝试使用string = argv[1]
(不带*)会是一个更好的猜测,但是您不能使用简单的分配复制数组。
我是否真的需要使用循环来遍历每个元素并做长远的事情?
除非您准备使用strcpy
,strncpy
或strdup
之类的功能或类似的功能,否则可以。在代码中使用strncpy
如下:
char string[100];
strncpy(string, argv[1], sizeof(string));
string[sizeof(string) - 1] = 0;
最后一行是确保string
被终止。笨拙?是的。在诸如strlcpy
之类的某些编译器中,有更好的功能,该功能在POSIX系统上可用,但是它不是C标准的一部分。如果您使用strlcpy
而不是strncpy
,则可以跳过最后一行。
如果您打算进行大量的字符串复制并且没有支持strlcpy
的编译器,则最好编写自己的实现(好的做法)或仅复制现有的实现。这是我发现的一个:
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
break;
}
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}
来源:https://android.googlesource.com/platform/system/core.git/+/brillo-m7-dev/libcutils/strlcpy.c
答案 1 :(得分:0)
在C的main函数中,argv
是字符串的向量,字符串本身就是字符数组。因此argv
是指向指针的指针(例如**char
)。
您的代码为一个指针(第一个参数)分配了一个引用。
char* string = argv[1];
可以做到。要复制整个字符串(字符数组),请使用strcpy
。要复制所有参数,请使用memcpy
。
但是通常在C程序中,您不复制参数,而只使用对它们的引用。
答案 2 :(得分:0)
在C中,数组名称不是L值表达式。因此,您不能在赋值语句中使用它。要复制字符数组,可以使用for语句或strcpy函数,该函数在string.h头文件中声明。
答案 3 :(得分:0)
简单的答案是:因为是。在C语言中,仅按值复制结构和联合,但有一个例外:
初始化数组
void foo(void)
{
char x[] = "This string literal will be copied! Test it yourself";
char z[] = "This string literal will be copied as well But because it is much loger memcpy will be used! Test it yourself";
float y[] = {1.0,2.0, 3,0,4.0,5.0,1.0,2.0, 3,0,4.0,5.0,1.0,2.0, 3,0,4.0,5.0};
long long w[] = {1,2,3,4,5,6,7,8,9,0};
foo1(x,z); // this functions are only to prevent the variable removal
foo2(y,w);
}
和已编译的代码:
foo:
push {r4, lr}
sub sp, sp, #320
mov ip, sp
ldr lr, .L4
ldr r4, .L4+4
ldmia lr!, {r0, r1, r2, r3}
stmia ip!, {r0, r1, r2, r3}
ldmia lr!, {r0, r1, r2, r3}
stmia ip!, {r0, r1, r2, r3}
ldmia lr!, {r0, r1, r2, r3}
stmia ip!, {r0, r1, r2, r3}
ldm lr, {r0, r1}
str r0, [ip], #4
strb r1, [ip]
add r0, sp, #208
mov r2, #110
ldr r1, .L4+8
bl memcpy
mov r1, r4
add r0, sp, #56
mov r2, #72
bl memcpy
mov r2, #80
add r1, r4, #72
add r0, sp, #128
bl memcpy
add r1, sp, #208
mov r0, sp
bl foo1
add r1, sp, #128
add r0, sp, #56
bl foo2
add sp, sp, #320
pop {r4, pc}
.L4:
.word .LC2
.word .LANCHOR0
.word .LC3
.LC2:
.ascii "This string literal will be copied! Test it yoursel"
.ascii "f\000"
.LC3:
.ascii "This string literal will be copied as well But beca"
.ascii "use it is much loger memcpy will be used! Test it y"
.ascii "ourself\000"
通过值复制结构和联合,因此赋值会将整个结构复制到另一个。
typedef struct
{
char str[100];
}string;
string a = {.str = "This string literal will be copied before main starts"},b;
void foo3(string c)
{
string g = a;
b = a;
foo4(g);
}
和代码:
foo3:
sub sp, sp, #16
push {r4, r5, r6, lr}
mov r6, #100
sub sp, sp, #104
ldr r5, .L4
add ip, sp, #116
add r4, sp, #4
stmib ip, {r0, r1, r2, r3}
mov r2, r6
mov r1, r5
mov r0, r4
bl memcpy
mov r2, r6
mov r1, r5
ldr r0, .L4+4
bl memcpy
add r1, sp, #20
mov r2, #84
add r0, sp, #136
bl memcpy
ldm r4, {r0, r1, r2, r3}
add sp, sp, #104
pop {r4, r5, r6, lr}
add sp, sp, #16
b foo4
.L4:
.word .LANCHOR0
.word b
a:
.ascii "This string literal will be copied before main star"
.ascii "ts\000"
您可以自己玩: