为什么不能将一个阵列复制到另一个阵列?

时间:2019-06-15 13:34:21

标签: c c-strings

int main(int argc, char *argv[])
{
    char string[100];
    string = *argv[1];
}

为什么这行不通?我是否真的需要使用循环来遍历每个元素,并做长远的事情?

4 个答案:

答案 0 :(得分:4)

  

为什么不起作用?

因为这就是在C语言中的工作方式。尝试使用string = argv[1](不带*)会是一个更好的猜测,但是您不能使用简单的分配复制数组。

  

我是否真的需要使用循环来遍历每个元素并做长远的事情?

除非您准备使用strcpystrncpystrdup之类的功能或类似的功能,否则可以。在代码中使用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"

您可以自己玩:

https://godbolt.org/z/lag4uL