Язык C. Дан текст. Выделить все слова в предложениях, состоящих только из цифр. Определить сумму чисел во всех предложениях

Текст представляет собой массив строк. Предложением является строка, а слово представляет собой обособленный ряд цифр типа " 453 ", т.е. с рядом с ним не должно быть прочих символов, не являющихся цифрами. Таким образом, искомым предложением является предложение вида "432 543 235 64". Требуется определить сумму всех чисел в строке без использования функций, к примеру, atoi().

Пробовал написать, но застрял на нахождении слова и вычислении суммы слов. Код:

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

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

    int s, n, i, j = 0, l = 0, summa = 0;
    bool nalichie = false;

    printf("Введите размеры (количество строк и количество символов в строке)\n");
    scanf_s("%d %d", &s, &n);


    char** str = (char**)malloc(s * sizeof(char*));
    for (i = 0; i < s; i++) {
        str[i] = (char*)malloc((n + 1) * sizeof(char));
    }

    printf("Введите текст\n");
    rewind(stdin);
    for (i = 0; i < s; i++) {
        fgets(str[i], n, stdin);
    }
    for (i = 0; i < s; i++) {
        for (j = 0; str[i][j]; j++) {
            if ((int)(str[i][j]) > 32 && (int)(str[i][j]) < 48 || (int)(str[i][j]) > 57) { // если символ вне списка цифр, то сумма, то обнуляем сумму и скипаем строку
                summa = 0;
                break;
            }
            else 
            {
                if ((int)(str[i][j]) >= 48 && (int)(str[i][j]) <= 57)
                {
                    l = str[i][j] - '0';
                    summa += l;
                }
            }
        }
        printf("Сумма %d строки равна : %d\n", i, summa);
        summa = 0;
        l = 0;
    }
    for (int k = 0; k < s; k++) {
        free(str[k]);
    }
    free(str);

    return 0;
}

Ответы (2 шт):

Автор решения: Harry

Ну, как я понимаю, отрицательных чисел не ожидается. Тогда все просто - читаем по одному символу и обрабатываем. У меня написано для чтения из входного потока, пока он не закроется через ^Z. Вы можете написать по-своему, но принцип остается тем же:

int main()
{
    int sum = 0;
    int num = 0;
    int c;
    while((c = fgetc(stdin)) != EOF)
    {
        if (isdigit(c))
            num = num*10+c-'0';
        else
        {
            sum +=num;
            num = 0;
        }
    }
    printf("%d\n",sum);
}

Если нельзя использовать isdigit, перепишите if (isdigit(c)) как

if (c >= '0' && c <= '9')

Выделять слова, использовать дополнительную память etc etc совершенно не нужно...

→ Ссылка
Автор решения: Kradar

Проблема решена, вот код:

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

int clearStdin() // функция для проверки
{
    int rv = 1, ch;
    while (1) {
        ch = getchar();
        if (ch == '\n' || ch == EOF) {
            break;
        }
        rv = 0;
    }
    return rv;
}

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

    int isEmpty, readCount; // переменные для проверки ввода

    int string_num; // кол-во строк
    int char_num; // кол-во символов в строке

    printf("Введите количество строк в тексте: ");
    while (1)
    {
        readCount = scanf_s("%d", &string_num);
        isEmpty = clearStdin();
        if (readCount == 1 && isEmpty != 0 && string_num > 0)
        {
            break;
        }
        printf_s("Wrong number. Try again:\n");
    }
    // проверка на вводимое число

    printf("Введите количество символов в строке: ");
    while (1)
    {
        readCount = scanf_s("%d", &char_num);
        isEmpty = clearStdin();
        if (readCount == 1 && isEmpty != 0 && char_num > 0)
        {
            break;
        }
        printf_s("Wrong number. Try again:\n");
    }
    // проверка на вводимое число

    int i; // счетчик

    char** A = (char**)malloc(string_num * sizeof(char*));
    for (i = 0; i < string_num; i++)
    {
        A[i] = (char*)malloc((char_num + 1) * sizeof(char));
    }
    // создание дин. массива символов

    printf("Введите текст\n");
    rewind(stdin); // сбрасывает индикатор ошибок потока данных и устанавливает указатель на начало 

    for (i = 0; i < string_num; i++)
    {
        fgets(A[i], char_num, stdin);
    }
    // ввод строки

    int j = 0; // счетчик по символам
    int temp = 0; // для подсчета числа
    int sum = 0; // сумма чисел

    for (i = 0; i < string_num; i++)
    {
        while (A[i][j] && A[i][j] != '.')
        {
            if (((int)(A[i][j]) > 32 && (int)(A[i][j]) < 48 || (int)(A[i][j]) > 57))
            {
                temp = 0;
                sum = 0;
                printf("В строке есть буква. Строка с индексом %d пропущена. ", i);
                break;
            }
            // если есть символ-не-цифра, то прекращаем цикл

            if (A[i][j] == ' ')
            {
                sum += temp;
                temp = 0;
            }
            // зануляем число при знаке пробела

            if ((int)(A[i][j]) >= 48 && (int)(A[i][j]) <= 57)
            {
                temp = temp * 10 + (A[i][j] - '0');
            }
            j++;
        }

        if (A[i][j] == '\0' || A[i][j] == '.')
        {
            sum += temp;
            temp = 0;
        }

        printf("Сумма %d строки равна : %d\n", i, sum);

        sum = 0;
        temp = 0;
        j = 0;
        // зануляем сумму, индекс начала строки j и temp
    }

    for (i = 0; i < string_num; i++) {
        free(A[i]);
    }
    free(A);
    // очистка памяти от массива A

    return 0;
}
→ Ссылка