@zakatzakatom

Почему программа на СИ не прекращает ввод?

Написал курсовую работу на СИ, требуется ввести текст а далее с ним будут различные манипуляции, и когда я ввожу текст, ничего не происходит, нажимаю Enter, и консоль просто переходит на новую строку, а если нажимать ctrl + d то ввод принимается и программа завершается, а мне нужно еще выбрать пункт меню, но она сразу завершается
#include <stdlib.h>
#include <stdio.h>
#include <locale.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>

struct string
{
    char* pointer;
    int length;
};

struct strings
{
    char** pointers;
    int size;
};

struct string InputToText()
{
    char character = EOF;
    struct string text = { .pointer = malloc(sizeof(char)), .length = 1 };
    while (scanf("%c", &character) == 1 && character != EOF)
    {
        text.pointer[text.length - 1] = character;
        text.pointer = realloc(text.pointer, ++text.length);
    }
    text.pointer[text.length - 1] = '\0';
//    printf("\Проверка корректного чтения:%s %d\n\n", text.pointer, strlen(text.pointer));
    return text;
}

struct strings TextToSentences(const struct string* text)
{
    struct strings sentences = { .pointers = NULL, .size = 0 };
    int start = 0;
    for (int index = 0; index < text->length; index++)
    {
        if (text->pointer[index] == '.')
        {
            sentences.pointers = (char**)realloc(sentences.pointers, ++sentences.size * sizeof(char*));
            sentences.pointers[sentences.size - 1] = malloc(index - start + 1);
            sentences.pointers[sentences.size - 1][index - start] = '\0';
            memcpy(sentences.pointers[sentences.size - 1], &text->pointer[start], index - start);
            start = index + 1;
        }
    }

    return sentences;
}

void RemoveString(struct strings* sentences, int index)
{
    sentences->pointers[index] = sentences->pointers[sentences->size - 1];
    sentences->pointers = (char**)realloc(sentences->pointers, --sentences->size * sizeof(char*));
}

void RemoveDuplicates(struct strings* sentences)
{
    for (int current = 0; current < sentences->size - 1; current++)
    {
        for (int index = current; index < sentences->size - 1; index++)
        {
            if ((strcmp(sentences->pointers[current], sentences->pointers[index + 1])) == 0)
            {
                RemoveString(sentences, index + 1);
                index--;
            }
        }
    }
}

void PrintSentences(struct strings* sentences)
{
    for (int index = 0; index < sentences->size; index++)
    {
        printf("%s\n", sentences->pointers[index]);
    }
}

char* ChangeSentenceIfItContainsWordRobin(char* sentence, char* result)
{
    int position = result - sentence;
    int robin_length = 5;
    int i_am_batman_length = 11;

    char* new_string = malloc(sizeof(char) * (strlen(sentence) + i_am_batman_length - robin_length + 1));

    strncpy(new_string, sentence, position);

    strncpy(new_string + position, "I am Batman", i_am_batman_length);

    strncpy(new_string + position + i_am_batman_length,sentence + position + robin_length, (strlen(sentence) - position - robin_length));

    new_string[strlen(sentence) + i_am_batman_length - robin_length] = '\0';

    return new_string;
}

void ChangeAllSubstringWithRobin(struct strings* sentences)
{
    for (int index = 0; index < sentences->size; ++index)
    {
        char* result;
        while (result = strstr(sentences->pointers[index], "Robin"))
        {
            sentences->pointers[index] = ChangeSentenceIfItContainsWordRobin(sentences->pointers[index], result);
        }
    }
}

int CountCommasInSentence(const char* sentence)
{
    int count = 0;
    for (int index = 0; index < strlen(sentence); index++)
    {
        if (sentence[index] == ',')
        {
            count++;
        }
    }
    return count;
}

int comparator(const void* first, const void* second)
{
    const char* first_sentence = *(const char**)first;
    const char* second_sentence = *(const char**)second;
    const int count_commas_first_sentence = CountCommasInSentence(first_sentence);
    const int count_commas_second_sentence = CountCommasInSentence(second_sentence);
    if (count_commas_first_sentence > count_commas_second_sentence)
        return 1;
    if (count_commas_first_sentence < count_commas_second_sentence)
        return -1;
    return 0;
}

void SortByCountOfCommasInAscendingOrder(struct strings* sentences)
{
    qsort(sentences->pointers, sentences->size, sizeof(char*), comparator);
}

int SumDigit(char* sentence)
{
    int sum = 0;
    for (int index = 0; index < strlen(sentence); index++)
    {
        if (isdigit(sentence[index]))
        {
            sum += sentence[index] - '0';
        }
    }
    return sum;
}

void RemoveSentencesWithSumDigit13(struct strings* sentences)
{
    for (int index = 0; index < sentences->size; index++)
    {
        if (SumDigit(sentences->pointers[index]) == 13)
        {
            RemoveString(sentences, index);
            index--;
        }
    }
}

bool CheckCharacterOnVowelAndDigit(char character)
{
    if (character == 'A' || character == 'E' || character == 'I' || character == 'O' || character == 'U')
        return true;
    if (character == 'a' || character == 'e' || character == 'i' || character == 'o' || character == 'u')
        return true;
    if (isdigit(character))
        return true;

    return false;
}

void PrintSentencesWhereTheFirstCharacterIsVowelLetterOrDigit(struct strings* sentences)
{
    for (int index = 0; index < sentences->size; index++)
    {
        if (CheckCharacterOnVowelAndDigit(sentences->pointers[index][0]))
        {
            printf("\n%s", sentences->pointers[index]);
        }
    }
}

void Menu()
{
    printf("Введите текст:\n");
    struct string text = InputToText();
    struct strings sentences = TextToSentences(&text);

    RemoveDuplicates(&sentences);

    printf("Выберите действие:\n");
    printf("0) Заменить в тексте подстроки “Robin” (могут быть внутри слова) на подстроку “I am Batman”.\n");
    printf("1) Отсортировать предложения по увеличению количества запятых в предложении.\n");
    printf("2) Удалить все предложения в которых сумма цифр в предложении равняется 13.\n");
    printf("3) Вывести все предложения в которых первое слово начинается с гласной буквы или цифры.\n");
    printf("4) Выйти из программы.\n");

    int choise;
    if (scanf("%d", &choise) != 1)
    {
        choise = -1;
    }

    switch (choise) {
        case 0: {
            ChangeAllSubstringWithRobin(&sentences);
            PrintSentences(&sentences);
            break;
        }
        case 1: {
            SortByCountOfCommasInAscendingOrder(&sentences);
            PrintSentences(&sentences);
            break;
        }
        case 2: {
            RemoveSentencesWithSumDigit13(&sentences);
            PrintSentences(&sentences);
            break;
        }
        case 3: {
            PrintSentencesWhereTheFirstCharacterIsVowelLetterOrDigit(&sentences);
            break;
        }
        case 4: {
            exit(0);
        }
        default:
            printf("Данные некорректны");
            exit(0);
    }
}

int main()
{
    setlocale(LC_ALL, "Rus");

    Menu();
  • Вопрос задан
  • 174 просмотра
Решения вопроса 1
myjcom
@myjcom
Зачем scanf для чтения одного чара?
Вот, посмотри Example
https://en.cppreference.com/w/c/io/getchar
+
https://en.cppreference.com/w/c/io/clearerr

struct string InputToText()
{
    char character = EOF;
    struct string text = { .pointer = malloc(sizeof(char)), .length = 1 };
    while ((character = getchar()) != EOF)
    {
        text.pointer[text.length - 1] = character;
        text.pointer = realloc(text.pointer, ++text.length);
    }
    text.pointer[text.length - 1] = '\0';
//    printf("\Проверка корректного чтения:%s %d\n\n", text.pointer, strlen(text.pointer));
    if(feof(stdin)) clearerr(stdin);
    return text;
}


Это если с ctrl + D

Если по Enter, то нужно проверять на Enter
#define ENTER 10
while ((character = getchar()) != ENTER)
//...


Тогда
if(feof(stdin)) clearerr(stdin);
не нужно
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы