Скопируйте строку, используя динамическую функцию - PullRequest
0 голосов
/ 19 октября 2019

Я пытаюсь скопировать строку в другую строку. Возникла проблема с окончательным выводом. Пожалуйста, укажите ожидаемый и фактический выходные данные.

Это для копирования строки между другой строкой.

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

int main()
{
    int n1, n2, loc;
    char *p1, *p2, *output;

    printf("Enter size of p1: ");
    scanf("%d", &n1);

    p1 = malloc(n1 * sizeof(char));

    printf("Enter the P1 String: ");
    scanf("%s", p1);

    printf("\nEnter the size of p2: ");
    scanf("%d", &n2);

    p2 = malloc(n2 * sizeof(char));

    printf("Enter the P2 String: ");
    scanf("%s", p2);

    printf("\nEnter the Location to copy: ");
    scanf("%d", &loc);

    output = realloc(p1, sizeof(char) * (n1 + n2));

    for (int i = loc - 1; i <= n1; i++)
        *(output + i + n2) = *(p1 + i);

    for (int i = 0; i < n2; i++)
        *(output + i + loc) = *(p2 + i);

    printf("\nFinal copy is: ");
    printf("%s\n", output);

    free(p1);
    free(p2);
    free(output);

    return 0;
}

Ожидаемый I / O / P:

Size of string: 6
Enter string: google
size of 2nd string: 6
Enter string: amazon
Location to copy: 2
Final copy: goamazonogle

Фактический I & O / P:

Size of string: 6
Enter string: google
size of 2nd string: 6
Enter string: amazon
Location to copy: 2
Final copy: goamazonW //Here W is the unknown value is printing instead of "ogle".

Ответы [ 2 ]

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

sizeof(char) всегда 1. Вы можете упростить свой код, исключив его.

Как только вы узнаете размер строки, которую собираетесь прочитать, вы не сможете использовать scanf (3), чтобы ограничить вводимые данные размером буфера, который вы распределили. В общем, мы не полагаемся на входные данные для точного описания себя.

В вашем случае, даже если описание точное, код не такой: scanf обещает завершить чтение строки %s символом NUL, поэтому для вашего 6-байтового ввода требуется 7-байтовыйбуфер для размещения этого NUL. Это одна ошибка.

Есть причудливый способ заставить scanf выделить память для вас. Традиционно, однако, вы использовали бы для этого getline (3) и strlen (3), чтобы узнать, сколько он прочитал.

Как указывает один комментарий, realloc (3) делает недействительным свой первый аргумент, что означает, что на p1 нельзя положиться после этого вызова. Вы действительно хотите, чтобы output был отдельным буфером, в который вы будете копировать данные из p1 и p2.

Однако после того, как вы выделите выходной буфер, вы можете быть удивлены, узнав, что sprintf (3) - ваш друг. Один вызов этой функции с конструкциями %.*s для динамического ограничения вывода строки и арифметикой указателей на входах создаст то, что вам нужно.

0 голосов
/ 20 октября 2019

Вот правильный код для копирования строки с использованием динамического метода. Обратитесь к пункту 1, чтобы получить больше ясности.

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

int main()
{
    int n1, n2, loc;
    char *p1, *p2, *output;

    printf("Enter size of p1: ");
    scanf("%d", &n1);

    p1 = malloc((n1 + 1) * sizeof(char));

    printf("Enter the P1 String: ");
    scanf("%s", p1);

    printf("\nEnter the size of p2: ");
    scanf("%d", &n2);

    p2 = malloc((n2 + 1) * sizeof(char));

    printf("Enter the P2 String: ");
    scanf("%s", p2);

    printf("\nEnter the Location to copy: ");
    scanf("%d", &loc);

    output = malloc((n1 + n2 + 1) * sizeof(char)); //After allocating a memory to both sizes of string along with adding memory for NULL.

    for (int i = 0; i < loc; i++)
        *(output + i) = *(p1 + i);

    for (int i = loc - 1; i <= n1; i++)
        *(output + i + n2) = *(p1 + i);

    for (int i = 0; i < n2; i++)
        *(output + i + loc) = *(p2 + i);

    printf("\nFinal copy is: ");
    printf("%s\n", output);

    free(p1);
    free(p2);
    free(output);

    return 0;
}
...