简体   繁体   English

C - 复制没有库的字符串 function

[英]C - Copy a String without a library function

I want to create a function that takes a string literal and an array and copies the characters of string literal to the array.我想创建一个 function ,它接受一个字符串文字和一个数组,并将字符串文字的字符复制到数组中。 Could you please inform me what is the issue in the following code?您能否告诉我以下代码中的问题是什么? The output of this code is just a capital D with some whitespaces (" D") so i think a random location is accessed somehow.此代码的 output 只是带有一些空格(“D”)的大写 D,所以我认为以某种方式访问了随机位置。

#include <stdio.h>

int main(void)
{
    //Function Prototypes:
    void CopyAString(const char * s1, char s2[]);
    
    // Initialize the string literal str1 and an array s2 of size 12.
    const char *str1 = "Hello World";
    char s2[12];
    // In the function i pass the address of str1 and the array s2.
    CopyAString( &str1, s2 );

    for (int i = 0; i <= 12; i++){
        printf("%c", s2[i]);
    }

}

void CopyAString(const char * s1, char s2[])
{
    const char * p1 = s1;
    int index = 0;

    while (*p1 != '\0') {
        s2[index] = *p1;
        index++;
        p1++;
    }
}

Your program has two bugs:你的程序有两个错误:

First第一的

Your function CopyAString does not write a '\0' character to the end of the string.您的 function CopyAString不会在字符串末尾写入'\0'字符。 This means that the string s2[] does not have a '\0' character and you would not be able to pass s2[] to functions like printf() or other functions that expect an "input" string to end with '\0' .这意味着字符串s2[]没有'\0'字符,您将无法将s2[]传递给printf()之类的函数或其他期望“输入”字符串以'\0'结尾的函数'\0' .

However, in your program, this is not a problem because the for loop expects a fixed-length string.但是,在您的程序中,这不是问题,因为for循环需要一个固定长度的字符串。

Second第二

In your program, the following problem is more important:在您的程序中,以下问题更为重要:

You pass &str as first argument to CopyAString instead of str .您将&str作为第一个参数传递给CopyAString而不是str

This means that s1 (the first argument of CopyAString ) does not point to the character 'H' of "Hello world" but it points to the first byte of the value stored in the variable str ...这意味着s1CopyAString的第一个参数)不指向"Hello world"的字符'H' ,而是指向存储在变量str中的值的第一个字节......

Note that the variable str is a pointer: It does not store a "value" (here: the string "Hello world" ) but it stores an address of a value!请注意,变量str是一个指针:它不存储“值”(此处为字符串"Hello world" ),但它存储值的地址!

If the string "Hello world" is stored in the RAM at address 0x20 44 00 40 (this means: 0x40004420 on an x86 or ARM computer or 0x20440040 on a PowerPC), the variable str will contain the value 0x20 44 00 40 . If the string "Hello world" is stored in the RAM at address 0x20 44 00 40 (this means: 0x40004420 on an x86 or ARM computer or 0x20440040 on a PowerPC), the variable str will contain the value 0x20 44 00 40 .

s1[0] will be 0x20 (which is the space character). s1[0]将是0x20 (这是空格字符)。 s1[1] will be 0x44 (which is 'D' )... s1[1]将是0x44 (即'D' )...

For starters you should declare the function like对于初学者,您应该像这样声明 function

char * CopyAString( char *s1, const char *s2 );

similarly to the standard string function strcpy .类似于标准字符串 function strcpy

In this function call在这个 function 通话中

CopyAString( &str1, s2 );

the expression &str1 has the type const char ** and yields the address of the pointer str1 but the function expects an argument expression of the type const char * that points to the first element of a string (the string literal).表达式&str1的类型为const char **并产生指针str1的地址,但 function 需要类型为const char *的参数表达式,它指向字符串的第一个元素(字符串文字)。

Within the function you are not copying the terminating zero character在 function 中,您不会复制终止零字符

while (*p1 != '\0') {
    s2[index] = *p1;
    index++;
    p1++;
}

So the destination character array in general will not contain a string.所以目标字符数组一般不会包含字符串。

The function can be defined the following way function 可以通过以下方式定义

char * CopyAString( char *s1, const char *s2 )
{
    for ( char *p = s1; ( *p++ = *s2++ ); );

    return s1;
}

Within main instead of this for loop with the magic number 12 in the condition that invokes undefined behavior在调用未定义行为的条件中,在 main 而不是这个 for 循环中使用幻数 12

for (int i = 0; i <= 12; i++){
    printf("%c", s2[i]);
}

it is better to write最好写

for ( char *p = s2; *p != '\0'; ++p ){
    printf("%c", *p );
} 
putchar( '\n' );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM