Как я могу вырезать строку в C? - PullRequest
0 голосов
/ 02 февраля 2019
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "Usage: greeting message name\n");
        exit(1);
    }
    char greeting[20];
    char *name = argv[2];

    // Your code goes here
    for (int i = 0; i < strlen(argv[1]); i++) {
        if (i < 20) {
            greeting[i] = argv[1][i];
        }
        else {
            greeting[i] = '\0';
        }
    }

    int greeting_len = strlen(greeting);
    strcat(greeting, " ");
    strncat(greeting, name, 20-greeting_len-2);

    printf("%s\n", greeting);
    return 0;
}

В этой практике мне необходимо объединить два аргумента командной строки, которые greeting и name, вместе и разделены пробелом.Более того, приветствие и строка после концентрации не могут быть длиннее 20 символов.

Когда я запускаю ./a.out "Good morninggggggggggggggggggg" "Emmanuel", возникает ошибка, говорящая

*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped)

Как это исправить?

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

следующий предложенный код:

  1. безупречная компиляция
  2. выполняет желаемую функциональность
  3. правильно проверяет (и обрабатывает) ошибки
  4. имеетнет открытий для неопределенного поведения и переполнения буфера
  5. ставит пробел между argv[1] и argv[2]

и теперь предлагаемый код:

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

int main(int argc, char **argv) 
{
    if (argc != 3) 
    {
        fprintf(stderr, "Usage: greeting message name\n");
        exit(1);
    }


    char *greeting = malloc( strlen( argv[1] ) + strlen( argv[2] ) +1 +1 );
    if( !greeting )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }


    strcpy( greeting, argv[1] );
    strcat( greeting, " " );
    strcat( greeting, argv[2] );


    printf("%s\n", greeting);

    free( greeting );
    return 0;
}
0 голосов
/ 02 февраля 2019

Если аргумент message длиннее 20 символов, ваш первый цикл будет писать за пределами greeting.Оператор if не останавливает цикл, он продолжает идти, но назначает нулевые байты вместо argv[1][i].

И если аргумент message вписывается в greeting, вы никогда не добавите нольбайт вообще.Цикл останавливается после копирования последнего символа, не включая нулевого терминатора.

Вы можете просто использовать strncpy(), а затем установить последний байт greeting в нулевой байт.

strncpy(greeting, argv[1], sizeof greeting);
greeting[sizeof greeting - 1] = '\0';

Перед добавлением пробела необходимо проверить, достигли ли вы предела:

if (greeting_len < 18) {
    greeting[greeting_len] = ' ';
    greeting[greeting_len+1] = '\0';
    greeting_len++;
}
if (greeting_len < 18) {
    strncat(greeting, name, 19-greeting_len);
}

Но если вы можете использовать snprintf(), все будет гораздо проще:

snprintf(greeting, sizeof greeting, "%s %s", argv[1], name);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...