简体   繁体   English

使用指针的 C 中的字符串复制未显示预期结果

[英]String copy in C using pointers doesn't show expected result

I was trying to implement a string copy function using pointers as shown below:我试图使用指针实现字符串复制 function ,如下所示:

#include <stdio.h>
#include <stdlib.h>

void copyStringPtr(char *from, char *to);

int main()
{
    char strSource[] = "A string to be copied.";
    char strDestination[50];

    copyStringPtr(strSource, strDestination);       // Doesn't work.

    return 0;
}

void copyStringPtr(char *src, char *dst)
{
    printf("The destination was\t:\t%s\n", dst);

//    for(; *src != '\0'; src++, dst++)
//        *dst = *src;

    while(*src)             //  The null character is equivalent to 0, so when '\0' is reached, the condition equals to 0 or false and loop is exited.
        *dst++ = *src++;

    *dst = '\0';

    printf("The source is\t\t:\t%s\n", src);
    printf("The destination is\t:\t%s\n\n", dst);
}

The expected output is:预期的 output 为:

The destination was :   
The source is       :   A string to be copied.
The destination is  :   A string to be copied.

But the output I'm getting is:但是我得到的 output 是:

The destination was :   
The source is       :   
The destination is  :   

As it can be seen, even the source doesn't seem to have the initialized value.可以看出,即使是源似乎也没有初始化值。 What am I doing wrong here?我在这里做错了什么?

One issue is that you're not initializing char strDestination[50];一个问题是您没有初始化char strDestination[50]; . . Thus it doesn't represent a valid string and when you try to print it here:因此它不代表有效的字符串,当您尝试在此处打印时:

printf("The destination was\t:\t%s\n", dst);

It is undefined behavior.这是未定义的行为。 You can initialize it like this:您可以像这样初始化它:

char strDestination[50] = {'\0'};

This explicitly sets the first char to '\0' , making it a valid string.这将第一个char显式设置为'\0' ,使其成为有效字符串。 And the rest of the array is then default-initialized to '\0' anyway.然后阵列的 rest 无论如何都会默认初始化为'\0'

Also, after the while loop, your src and dst will point to the null terminator at the end of the strings, so when you print them, it prints nothing.此外,在while循环之后,您的srcdst将指向字符串末尾的 null 终止符,因此当您打印它们时,它不会打印任何内容。 Instead, keep a copy of the original pointers and print those instead:相反,保留原始指针的副本并打印它们:

void copyStringPtr(char *src, char *dst)
{
    char* srcOriginal = src;
    char* dstOriginal = dst;
    ...
    printf("The source is\t\t:\t%s\n", srcOriginal);
    printf("The destination is\t:\t%s\n\n", dstOriginal);
}

Just take a backup of the original pointers before doing the increment.只需在进行增量之前备份原始指针。 The reason you lose those pointers is, as part of the iteration in the while the start address of the string is lost and the printf() function does not know where the string starts.丢失这些指针的原因是,作为迭代的一部分while字符串的起始地址丢失并且printf() function 不知道字符串从哪里开始。 Since both the original pointers point at \0 at the end of the loop, the printf() function does not see a an actual string to print up-to由于两个原始指针在循环结束时都指向\0 ,因此printf() function 看不到要打印的实际字符串

You can even make these backup pointers const to disallow modifications made to them.您甚至可以将这些备份指针设为const以禁止对其进行修改。

void copyStringPtr(char *src, char *dst)
{
    printf("The destination was\t:\t%s\n", dst);
    /*
     * backing up the original source/desination 
     * pointers
     */
    const char *b_src = src; const char *b_dst = dst;

    while(*src)             //  The null character is equivalent to 0, so when '\0' is reached, the condition equals to 0 or false and loop is exited.
        *dst++ = *src++;

    *dst = '\0';

    printf("The source is\t\t:\t%s\n", b_src);
    printf("The destination is\t:\t%s\n\n", b_dst);
}

Also as noted in Blaze's answer calling printf() on a uninitialized character array invokes undefined behavior.同样如 Blaze 的回答中所述,在未初始化的字符数组上调用printf()会调用未定义的行为。

I just had to make a minor modification as follows:我只需要进行如下小修改:

#include <stdio.h>
#include <stdlib.h>

void copyStringPtr(char *from, char *to);

int main()
{
    char strSource[] = "A string to be copied.";
    char strDestination[50];

    copyStringPtr(strSource, strDestination);       // Doesn't work.

    printf("The source is\t\t:\t%s\n", strSource);
    printf("The destination is\t:\t%s\n\n", strDestination);

    return 0;
}

void copyStringPtr(char *src, char *dst)
{
    const char *srcOriginal = src;
    const char *dstOriginal = dst;

    printf("The destination was\t:\t%s\n", dstOriginal);

//    for(; *src != '\0'; src++, dst++)
//        *dst = *src;

    while(*src)             //  The null character is equivalent to 0, so when '\0' is reached, the condition equals to 0 or false and loop is exited.
        *dst++ = *src++;

    *dst = '\0';
}

And it worked just fine.它工作得很好。 As pointed out by @Jabberwocky in his comment, the pointers *src and *dst in copyStringPtr had moved to the end of the character string and was pointing to the NULL terminator.正如@Jabberwocky 在他的评论中指出的那样,copyStringPtr 中的指针*src*dst已移至字符串的末尾并指向copyStringPtr终止符。

#include <stdio.h>
#include <stdlib.h>

void copyStringPtr(char *from, char *to);

int main()
{
    char strSource[] = "A string to be copied.";
    char strDestination[50] = {0};

    copyStringPtr(strSource, strDestination);

    return 0;
}

void copyStringPtr(char *src, char *dst)
{
    char const *const dstOriginal = dst;

    if (!src || !dst){
        return;
    }

    printf("The source is\t\t:\t%s\n", src);

    while(src && *src)
        *dst++ = *src++;
    *dst = '\0';

    printf("The destination is\t:\t%s\n\n", dstOriginal );
}

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

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