Копирование строки в C с использованием указателей не показывает ожидаемый результат - PullRequest
1 голос
/ 20 сентября 2019

Я пытался реализовать функцию копирования строк, используя указатели, как показано ниже:

#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 destination was :   
The source is       :   A string to be copied.
The destination is  :   A string to be copied.

Но вывод, который я получаю:

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

Как видно, даже источник не имеет инициализированного значения.Что я тут не так делаю?

Ответы [ 4 ]

3 голосов
/ 20 сентября 2019

Одна проблема в том, что вы не инициализируете char strDestination[50];.Таким образом, он не представляет допустимую строку, и когда вы пытаетесь напечатать ее здесь:

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

Это неопределенное поведение.Вы можете инициализировать его так:

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

Это явно устанавливает первый char в '\0', делая его допустимой строкой.И остальная часть массива затем инициализируется по умолчанию '\0' в любом случае.

Кроме того, после цикла while ваши src и dst будут указывать на нулевой терминатор в концестроки, поэтому, когда вы печатаете их, он ничего не печатает.Вместо этого сохраните копии оригинальных указателей и напечатайте их:

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);
}
1 голос
/ 20 сентября 2019

Мне просто нужно было сделать небольшую модификацию следующим образом:

#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';
}

И все работало просто отлично.Как указал @Jabberwocky в своем комментарии, указатели *src и *dst в copyStringPtr переместились в конец строки символов и указывали на терминатор NULL.

1 голос
/ 20 сентября 2019

Просто сделайте резервную копию оригинальных указателей, прежде чем делать приращение.Причина, по которой вы теряете эти указатели, заключается в том, что в ходе итерации в while начальный адрес строки теряется, а функция printf() не знает, где начинается строка.Поскольку оба исходных указателя указывают на \0 в конце цикла, функция printf() не видит фактической строки для печати до

. Вы даже можете сделать эти резервные указатели 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);
}

Также, как отмечено в ответе Blaze, вызов printf() для массива неинициализированных символов вызывает неопределенное поведение.

0 голосов
/ 20 сентября 2019
#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 );
}
...