Memset 和字符

Memset and characters

我的目标是将 source 字符串复制到 dest 字符串。如果我编译以下程序:

#include <stdio.h>

int main(void) {
    char dest[6];
    char source[6];
    
    strcpy(dest,source);
    
    while (*dest) { printf("%c",*dest++); }
    while (*source) {printf("%c",*source++); }
    
    return 0;
}

我收到运行时错误。我怀疑这是因为 strcpy 从源复制到目标直到它遇到 [=17=]。但是,它没有遇到空字符,而是继续从缓冲区复制,直到发生运行时错误。为了解决这个问题,我修改了代码如下:

#include <stdio.h>

int main(void) {
    char dest[6];
    char source[6];
    
    
    memset(dest, '[=11=]', 6*sizeof(dest)); //trying to set dest to '/0'
    strcpy(dest,source);
    
    while (*dest) { printf("%c",*dest++); }
    while (*source) {printf("%c",*source++); }
    
    return 0;
}

我收到以下错误:

prog.c:11:38: error: lvalue required as increment operand

 while (*dest) { printf("%c",*dest++); }
                                  ^

prog.c:11:38: error: lvalue required as increment operand

 while (*dest) { printf("%c",*source++); }
                                    ^

为什么会这样?

strcpy 不是安全函数,最好使用 strncpy.

错误是由于您尝试递增数组,它是一个右值(即常量,您不能将其放在符号 = 的左侧)。

遍历数组的常用方法是使用指针,如下所示:

char *p = dest;
while (*p) { printf("%c",*p++); }

对于初学者来说,如果您要使用标准 C 函数 strcpy 将源数组复制到另一个字符数组中,则应以零结尾的源数组。所以代替这个声明

memset(dest, '[=10=]', 6*sizeof(dest)); 

你至少应该写

memset(source, '[=11=]', 6*sizeof(source));
       ^^^^^^                ^^^^^^^

然而,即使这种说法也是错误的,因为它覆盖了为数组分配的内存。 sizeof( source ) 已经等于 6 个字节,因为它跟在数组声明

后面
char source[6];

因此你必须写

memset(source, '[=13=]', sizeof(source));
                     ^^^^^^^^^^^^^

其实也够写的喜欢

char source[6] = { '[=14=]' };

或喜欢

char source[6] = "";

或喜欢

char source[6];
source[0] = '[=16=]';

数组是不可修改的左值。因此你可能不会像下面这样写

while (*dest) { printf("%c",*dest++); }

你可以这样写

for ( char *p = dest; *p; ++p ) { printf("%c", *p); }

请注意,由于数组包含空字符串,因此不会输出任何内容。您可以使用一些非空字符串文字来初始化源数组。

以下代码可以干净地编译,并执行所需的操作。

已对发布的代码与此代码之间的差异进行了注释。

#include <stdio.h>  // printf()
#include <string.h> // strcpy()

int main(void) 
{
    char dest[6];  // declared, containing garbage
    char source[6] = "12345"; // declared, containing the string "12345[=10=]"

    strcpy(dest,source); 
    // now both arrays contain the string "12345[=10=]"

    // best to use a 'for()' statement for indexing through an array
    for( size_t i=0; dest[i];   i++ )  { printf("%c", dest[i]);  }
    printf( "\n" );  // output the buffered data to the terminal
    for( size_t i=0; source[i]; i++ )  { printf("%c", source[i]);}
    printf( "\n" );  // output the buffered data to the terminal

    // note, the following lines contain a precedence problem in
    // the increment expressions and 
    // the address of an array declaration cannot be incremented
    //while (*dest) { printf("%c",*dest++); }
    //while (*source) {printf("%c",*source++); }

    //return 0;// with modern C compilers, 
             // this line is not necessary in a 'main()' function
             // when returning 0
} // end function: main