Замена строк в C - PullRequest
       0

Замена строк в C

0 голосов
/ 30 апреля 2020

Хорошо, ребята, мне нужно написать программу, которая формирует новую строку на основе заданного шаблона и заданных строк. Шаблон задается в виде строки, где необходимо заменить все вхождения символа "%" конкретной строкой. Если шаблон содержит больше символов «%», чем введенные строки, символы «%» заменяют строки циклически. Если строка не введена, выведите «ERROR». Количество строк заранее неизвестно. Конец записи обозначается пустой строкой ("\ n"). Кроме того, есть некоторые условия, которые мне нужно выполнить, а именно:

1) Реализация функции char * readLine (); который читает одну строку из стандартного ввода и возвращает указатель на эту загруженную строку.

2) Реализовать функцию char ** readLines (int * n); который читает строки, которые изменяют все вхождения символа '%' в шаблоне. Функция возвращает массив указателей на строки, введенные в качестве возвращаемого значения. Кроме того, функция возвращает количество значений, введенных через аргумент n.

3) Реализовать функцию формата char * (char * format , char ** values ​​, int N ); который форматирует строку формат , изменяя каждое вхождение символа '%' на соответствующую строку из строки значений длины n .

4) Напишите основную программу, которая, используя ранее реализованные функции, считывает шаблон и строки из стандартного ввода, формирует новую строку, как описано, и печатает результат в стандартный вывод.

Я едва понимаю, что Я должен сделать это, поэтому я пришел сюда, чтобы попросить о помощи. То, что я сделал на данный момент, является первой задачей, но на выходе я получаю на 1 пустую строку больше, чем должен, и не могу найти способ исправить это. Любая помощь приветствуется, так как я действительно застрял здесь, даже объясняя, что я должен делать в некоторых задачах, или упрощение текущего кода - это здорово. Заранее спасибо. Вот мой код.

РЕДАКТИРОВАТЬ: Добавлены примеры.

Ввод:

% быть или не%%.

К

Выход:

Быть или не быть.

Ввод:

% и% сделать фиолетовым.

Синий

красный

Вывод:

Синий и красный делают фиолетовым.

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


char* readLine() {
    char* line = malloc(100), * linep = line;
    size_t lenmax = 100, len = lenmax;
    int c;

    if (line == NULL)
        return NULL;

    for (;;) {
        c = fgetc(stdin);
        if (c == EOF)
            break;

        if (--len == 0) {
            len = lenmax;
            char* linen = realloc(linep, lenmax *= 2);

            if (linen == NULL) {
                free(linep);
                return NULL;
            }
            line = linen + (line - linep);
            linep = linen;
        }

        if ((*line++ = c) == '\n')
            break;
    }
    *line = '\0';
    return linep;
}


int main() {

    printf("%s", readLine());
    return 0;
}

РЕДАКТИРОВАТЬ: Для 2-го задания я пытался сделать что-то подобное, как в первом, но я не мог не могу понять, как сделать так, чтобы это работало. Вот что я сделал:

char** readLines(int* n) {
    char* line = malloc(100), * linep = line;
    size_t lenmax = 100, len = lenmax;
    int c, flag = 0;

    if (line == NULL && flag > 1) {
        char* linen = realloc(linep, lenmax *= 2);
    }

    else if (line == NULL && flag == 0)
        return NULL;

    for (;;) {
        c = fgetc(stdin);
        if (c == EOF || c == '\n')
            break;

        if (--len == 0) {
            len = lenmax;
            char* linen = realloc(linep, lenmax *= 2);

            size_t diff = line - linep;
            if (linen == NULL) {
                free(linep);
                return NULL;
            }
            line = linen + diff;
            linep = linen;

            flag++;
        }

        *line++ = c;
    }
    *line = '\0';
    char* temp = linep;
    return linep;
}

Ответы [ 2 ]

2 голосов
/ 30 апреля 2020

Если вы хотите прочитать строку до EOF или '\n', но без новой строки в вашей строке, вам нужно сделать это:

for (;;) {
    c = fgetc(stdin);
    if (c == EOF)
        break;

    // realloc logic comes here

    if (c == '\n')
        break;

    *line++ = c;
}
2 голосов
/ 30 апреля 2020

По крайней мере, эта проблема

line = linen + (line - linep); - это UB, поскольку код не может использовать linep после того, как он был освобожден в realloc().

Вместо этого рассчитайте и сохраните разницу line - linep до realloc()

    size_t diff = line - linep;  // add
    char* linen = realloc(linep, lenmax *= 2);
    if (linen == NULL) {
       ...;
    }
    // line = linen + (line - linep);
    line = linen + diff;

ОП, очевидно, не хочет сохранять '\n'. Изменить

    // if ((*line++ = c) == '\n') break;
    if (c == '\n') break;
    *line++ = c; 

Я бы также рекомендовал правильный размер realloc() шаг в конце.

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