Sscanf читает то, что не должно - PullRequest
0 голосов
/ 11 января 2020

Недавно я столкнулся с проблемой с sscanf(), которую я использую для разбора полинома.

Проблема в том, что sscanf возвращает 1:

if (sscanf(pTemp, "%lfx\0", &tempBuf)) {

при чтении следующего:

4x^2\0-4x\01\t\0\0\0\0\0\0\0\0\0

но он должен возвращать 0 (очевидно).

И эта часть кода успешно прочитала правильные вещи прямо перед этим, поэтому я имею Понятия не имею, что идет не так.

Я пытался заменить \t такими вещами, как * /, это не помогло. sscanf продолжает распознавать 1 (что-то) как %lfx, в то время как предполагается возвращать 0 и двигаться вперед.

В чем проблема и как ее решить, кроме переписывания кода без использования sscanf? Вот сам код (комментарии и printfs на русском языке, но они ничего не значат для проблемы):

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <math.h>
#include <ctype.h>
#include <string.h>

typedef struct polynom {
    double* coeffs;
    int power;
} polynom;

void main() {
    setlocale(LC_ALL, "RUS");
    char bufRead, flagNeg = 0, numExp = 0, xExp = 0, powExp = 0, xNotExp = 0, powAlrSet = 0, *tempReadStr, *pTemp, tempReadC = 0;
    int power = 0, apprAcc = 0, cnt = 0, prolongCnt = 0;
    double tempBuf = 0;
    polynom* polynomIn, * polynomDer, * polynom0;

    tempReadStr = calloc(52, sizeof(char));
    if (!tempReadStr) {
        printf("Не хватает памяти для строки ввода. Попробуйте закрыть все ненужные приложения и повторить попытку.");
        return 0;
    }

    printf("Введите многочлен: ");
    //ввод самого многочлена в строку
    while (1) {
        scanf("%c", &tempReadC);
        if (tempReadC == '\n') {
            tempReadStr[cnt++] = '  ';
            break;
        }
        if (!isdigit(tempReadC) && (tempReadC != '+') && (tempReadC != '-') && (tempReadC != 'x') && (tempReadC != '^')) {
            printf("Недопустимый символ: %c. Проверьте правильность ввода.", tempReadC);
            return;
        }
        else {
            if (cnt < 50 + prolongCnt * 50) {
                if ((cnt != 0) && (tempReadC == '-')) {
                    tempReadStr[cnt++] = ' ';
                }
                if (tempReadC == '+') {
                    tempReadStr[cnt++] = ' ';
                }
                else {
                    tempReadStr[cnt++] = tempReadC;
                }
            }
            else {
                pTemp = realloc(tempReadStr, (52 + (++prolongCnt * 50)) * sizeof(char));
                if (!pTemp) {
                    printf("Не хватает памяти для строки ввода. Попробуйте закрыть все ненужные приложения и повторить попытку.");
                    return 0;
                }
                tempReadStr = pTemp;
                for (int j = 52 + ((prolongCnt - 1) * 50); j < 52 + (prolongCnt * 50); j++) {
                    tempReadStr[j] = '\0';
                }
                if ((cnt != 0) && (tempReadC == '-')) {
                    tempReadStr[cnt++] = ' ';
                }
                if (tempReadC == '+') {
                    tempReadStr[cnt++] = ' ';
                }
                else {
                    tempReadStr[cnt++] = tempReadC;
                }
            }
        }
    }
    //printf("\n%s", tempReadStr);
    pTemp = strtok(tempReadStr, " ");
    //блок интерпретации полученной строки
    while (1) {
        if (!pTemp) {
            break;
        }
        if (sscanf(pTemp, " ")) {
            break;
        }
        /*if (sscanf(pTemp, "+")) {

        }*/
        if (sscanf(pTemp, "%lfx^%d", &tempBuf, &power) == 2) {
            if (powAlrSet) {
                if (polynomIn->power < power) {
                    printf("Встечена степень, большая, чем первая введённая. Введите многочлен, начиная с наибольшей степени.");
                    return;
                }
                else {
                    polynomIn->coeffs[power] = tempBuf;
                }

            }
            else {
                polynomIn = calloc(1, sizeof(polynom));
                if (!polynomIn) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                polynomIn->power = power;
                polynomIn->coeffs = calloc(power + 1, sizeof(double));
                if (!polynomIn->coeffs) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                powAlrSet = 1;
                polynomIn->coeffs[power] = tempBuf;
            }
            pTemp = strtok(NULL, " ");
            continue;
        }
        if (sscanf(pTemp, "x^%d", &power)) {
            if (powAlrSet) {
                if (polynomIn->power < power) {
                    printf("Встечена степень, большая, чем первая введённая. Введите многочлен, начиная с наибольшей степени.");
                    return;
                }
                else {
                    polynomIn->coeffs[power] = 1;
                }
            }
            else {
                polynomIn = calloc(1, sizeof(polynom));
                if (!polynomIn) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                polynomIn->power = power;
                polynomIn->coeffs = calloc(power + 1, sizeof(double));
                if (!polynomIn->coeffs) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                powAlrSet = 1;
                polynomIn->coeffs[power] = 1;
            }
            pTemp = strtok(NULL, " ");
            continue;
        }
        if (sscanf(pTemp, "-x^%d", &power)) {
            if (powAlrSet) {
                if (polynomIn->power < power) {
                    printf("Встечена степень, большая, чем первая введённая. Введите многочлен, начиная с наибольшей степени.");
                    return;
                }
                else {
                    polynomIn->coeffs[power] = -1;
                }
            }
            else {
                polynomIn = calloc(1, sizeof(polynom));
                if (!polynomIn) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                polynomIn->power = power;
                polynomIn->coeffs = calloc(power + 1, sizeof(double));
                if (!polynomIn->coeffs) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                powAlrSet = 1;
                polynomIn->coeffs[power] = -1;
            }
            pTemp = strtok(NULL, " ");
            continue;
        }
        if (sscanf(pTemp, "%lfx", &tempBuf)) {
            if (powAlrSet) {
                polynomIn->coeffs[1] = tempBuf;
            }
            else {
                polynomIn = calloc(1, sizeof(polynom));
                if (!polynomIn) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                polynomIn->power = 1;
                polynomIn->coeffs = calloc(2, sizeof(double));
                if (!polynomIn->coeffs) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                powAlrSet = 1;
                polynomIn->coeffs[1] = tempBuf;
            }
            pTemp = strtok(NULL, " ");
            continue;
        }
        if (sscanf(pTemp, "x")) {
            if (powAlrSet) {
                polynomIn->coeffs[1] = 1;
            }
            else {
                polynomIn = calloc(1, sizeof(polynom));
                if (!polynomIn) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                polynomIn->power = 1;
                polynomIn->coeffs = calloc(2, sizeof(double));
                if (!polynomIn->coeffs) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                powAlrSet = 1;
                polynomIn->coeffs[1] = 1;
            }
            pTemp = strtok(NULL, " ");
            continue;
        }
        if (sscanf(pTemp, "-x")) {
            if (powAlrSet) {
                polynomIn->coeffs[1] = -1;
            }
            else {
                polynomIn = calloc(1, sizeof(polynom));
                if (!polynomIn) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                polynomIn->power = 1;
                polynomIn->coeffs = calloc(2, sizeof(double));
                if (!polynomIn->coeffs) {
                    printf("Ошибка выделения памяти.");
                    return;
                }
                powAlrSet = 1;
                polynomIn->coeffs[1] = -1;
            }
            pTemp = strtok(NULL, " ");
            continue;
        }
        if (sscanf(pTemp, "%lf", &tempBuf)) {
            if (!powAlrSet) {
                printf("Ввод многочлена принято начинать со старшей степени.");
                return;
            }
            else {
                polynomIn->coeffs[0] = tempBuf;
            }
        }
   }
   printf("Вы ввели многочлен:\n");

    for (int i = power; i >= 0; i--) {
        if (polynomIn->coeffs[i]) { // != 0 
            if ((polynomIn->coeffs[i] > 0) && (i != power))
                printf("+");
            if (i) { // != 0
                if (polynomIn->coeffs[i] != 1) {
                    if (polynomIn->coeffs[i] != -1) {
                        if (i != 1) {
                            printf("%.0lfx^%d", polynomIn->coeffs[i], i);
                        } 
                        else printf("%.0lfx", polynomIn->coeffs[i]);
                    }
                    else if (i != 1) {
                        printf("-x^%d", i);
                    } 
                    else printf("-x");
                }
                else if (i != 1) {
                    printf("x^%d", i);
                }
                else printf("x");
            }
            else {
                if (polynomIn->coeffs[i]) {
                    printf("%.0lf", polynomIn->coeffs[i]);
                }
            }
        }
    }
}

Он должен дать вам введенный вами многочлен. Я попытался с 4x ^ 2-4x + 1, и это дало мне 4x ^ 2 + x.

1 Ответ

0 голосов
/ 13 января 2020

Ну, я не знаю, в чем причина с sscanf(), потому что он имеет тенденцию игнорировать даже то, что происходит до первого отформатированного ввода, поэтому я просто заменил все мои "-", "x", "^" сканированием %c символы для переменных, значения которых я проверил сразу после этого. И это сработало.

...