Код не отображается для правильной печати составных строк - PullRequest
0 голосов
/ 03 февраля 2019

У меня есть некоторый код здесь, где, учитывая файл .txt, содержимое которого

find replace pre
pre
cpre

, я хочу найти каждый экземпляр «pre» и добавить к нему «k».т.е. файл должен стать "найти заменить kpre".

Итак, сначала я решил создать строку, представляющую собой конкатенацию k и pre (предположим, что k и pre равны argv [1] и argv [3] соответственно)

char appended[1024];
strcpy(appended, argv[1]);
strcat(appended, argv[3]);
printf("appended string is %s", appended); //prints kpre, which is good

char *replaced = replace(buf, argv[3], appended);

//*string is a line in  the file
char* replace(char *string, char *find, char *replace) {
    char *position; 
    char temp[1024];
    int find_length = strlen(find);
    int index = 0;

    while ((position = strstr(string, find)) != NULL) {
        strcpy(temp, string);
        index = position - string;
        string[index] = '\0';
        strcat(string, replace); //add new word to the string
        strcat(string, temp + index + find_length); //add the unsearched 
              //remainder of the string
    }
   return string;
}

.................

fputs(replaced, temp);

Проверка на консоли, appended = "kpre", это правильно, но когда код запускается, файл выглядит так:

find replace kkkkkkkkkkkkkkkk.....kkkkkkk
kkkkkkkkk......kkkkk
ckkkkk....kkkkk

k идут некоторое время, я не вижу pre при прокрутке всехпуть вправо.Мне трудно понять, почему код не заменяет экземпляр 'pre' на 'kpre', даже если добавленная переменная кажется правильной.У меня есть ощущение, что это связано с тем, что я установил 1024 символа для temp, но даже тогда я не уверен, почему k копировалось так много раз.

1 Ответ

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

Здесь

    while ((position = strstr(string, find)) != NULL) {

вы передаете string в strstr() функцию.strstr() вернет указатель на первое вхождение find в string.Когда вы заменяете pre на kpre и снова вызываете strstr(), он перенастраивает указатель на первое вхождение pre в string, которое является подстрокой строки replace.После некоторых итераций цикла while он начнет обращаться к string сверх его размера, что приведет к неопределенному поведению.

Вместо передачи string в strstr(), вы должны передать указатель на string и после каждой операции замены указатель make указывает на указанную после заменяемой части строки.Другой способ заключается в том, что вы можете перебирать строковый символ за символом, используя указатель вместо strstr(), например:

#define BUFSZ 1024

char* replace(char *string, const char *find, const char *replace) {
        if ((string == NULL) || (find == NULL) || (replace == NULL)) {
                printf ("Invalid argument..\n");
                return NULL;
        }

        char temp[BUFSZ];
        char *ptr = string;
        size_t find_len = strlen(find);
        size_t repl_len = strlen(replace);

        while (ptr[0]) {
                if (strncmp (ptr, find, find_len)) {
                        ptr++;
                        continue;
                }

                strcpy (temp, ptr + find_len);  // No need to copy whole string to temp
                snprintf (ptr, BUFSZ - (ptr - string), "%s%s", replace, temp);
                ptr = ptr + repl_len;
        }
        return string;
}

Обратите внимание, что приведенный выше код основан на примере, который вы опубликовали в своем вопросе, и простодать вам представление о том, как вы можете достичь своей цели, не используя strstr().При написании кода учитывайте и другие возможности, например: replace - огромная строка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...