Как избежать sscanf () в C, вызывая бесконечный цикл while вместо хранения пользовательского ввода? - PullRequest
0 голосов
/ 23 сентября 2019

Я уже некоторое время работаю над проектом C, и я довольно плохо знаком с C, я уже пробовал несколько вещей, но, похоже, ничего не работает.Всякий раз, когда я вхожу в цикл while и попадаю в функцию sscanf (), цикл становится бесконечным, и нет возможности принять входные данные.Это означает, что я не могу взять и сохранить его в массиве mt 2d

Я также пытался использовать strtok () в качестве другого варианта, но код стал слишком грязным.

typedef struct item {
    char name[50];
    double price;
} item;


int main() {
    // 1 begins
    char userInput[100];
    printf("Hello, welcome to the shelf-O-matic!\n");

    printf("Please press enter and then type the number of shelves followed by ',' and number of slots\n");
    int shelf = 0;
    int slot = 0;
    scanf("%d , %d", &shelf, &slot);

    struct item **thing = malloc(shelf * sizeof(item));
    for (int i = 0; i < slot; i++) {
        thing[i] = malloc(slot * sizeof(item));
    }
    while (strcmp(userInput , "quit")!= 0) {

        //variables symbolizing the slots and shelves
        printf("type quit to exit or set input to the array\n");
        //scanf("%100s", userInput);

        //Putting the size in memory location


        double *cash = malloc(sizeof(cash));
        int *x = malloc(sizeof(x));
        int *y = malloc(sizeof(y));
        //scanf("%100s", userInput);

        // 1 ends
        char *itemName = malloc(sizeof(itemName));
        printf("Please add things to the shelves and slots by specifying <name> <price> <shelf> <slot> or type quit to finish adding\n");
        sscanf(userInput,"%100s, %lf, %d, %d", itemName, &cash, &x, &y);

     printf(itemName);
     printf(cash);
     printf(x);
     printf(y);


}

    return 0;
    }

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

1 Ответ

0 голосов
/ 25 сентября 2019

Цикл while отчасти бесконечен, потому что запрос на ввод закомментирован, а sscanf анализировать нечего.
Другая проблема может заключаться в использовании %s для разбора itemName.Если в itemName есть пробелы,% s остановится на первом пробеле.Если вы хотите использовать запятую для разделения значений, %s будет воспринимать запятую как еще один символ как часть itemName.
Сканирование может помочь с этим.Scanset %[^,] говорит sscanf сканировать символы, которые не являются запятыми, и помещать их в itemName.Так что %49[^,], отсканирует до 49 символов, которые не являются запятыми, а затем отсканирует запятую.
Подумайте об использовании fgets для всего ввода и проанализируйте с помощью sscanf.Некоторые другие полезные функции для разбора: strtol, strtod, strspn и strcspn.Есть много других.

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

typedef struct item {
    char name[50];
    double price;
} item;

int main ( void) {
    char userInput[100];
    int result = 0;
    int shelf = 0;
    int slot = 0;

    printf ( "Hello, welcome to the shelf-O-matic!\n");
    do {
        printf ( "Please enter the number of shelves\n");
        if ( fgets ( userInput, sizeof userInput, stdin)) {
            result = sscanf ( userInput, "%d", &shelf);
        }
        else {
            fprintf ( stderr, "fgets EOF\n");
            return 0;
        }
    } while ( 1 != result || 0 >= shelf);
    printf ( "shelf = %d\n", shelf);
    do {
        printf ( "Please enter the number of slots\n");
        if ( fgets ( userInput, sizeof userInput, stdin)) {
            result = sscanf ( userInput, "%d", &slot);
        }
        else {
            fprintf ( stderr, "fgets EOF\n");
            return 0;
        }
    } while ( 1 != result || 0 >= slot);
    printf ( "slot = %d\n", slot);
    //allocate pointers then allocate structures to the pointers
    struct item **thing = malloc ( sizeof *thing * shelf);
    if ( NULL == thing) {
        fprintf ( stderr, "malloc problem\n");
        return 0;
    }
    for (int i = 0; i < shelf; i++) {//iterate through shelf number of pointers
        thing[i] = malloc( sizeof **thing * slot);
        if ( NULL == thing[i]) {
            fprintf ( stderr, "malloc problem\n");
            return 0;
        }
    }

    while ( 1) {//keep looping
        double cash = 0.0;
        int x = 0;
        int y = 0;
        char itemName[50] = "";

        result = 0;
        printf ( "Please add things to the shelves and slots\n");
        printf ( "specify:        name, price, shelf, slot\n");
        printf ( "when finished type quit or exit\n");
        if ( fgets ( userInput, sizeof userInput, stdin)) {//get input
            if ( ( strcmp ( userInput, "quit\n") == 0)
            || ( strcmp ( userInput, "exit\n") == 0)) {//exit loop
                break;
            }
            result = sscanf ( userInput, "%49[^,], %lf ,%d ,%d"
            , itemName, &cash, &x, &y);//sscanf to parse input

            if ( 4 == result
            && 0 < x && x < shelf
            && 0 < y && y < slot) {//scanned four items. shelf slot in range
                printf ( "%s\n", itemName);
                printf ( "%f\n", cash);
                printf ( "%d\n", x);
                printf ( "%d\n", y);

                //store in thing[x][y]
            }
            else {
                printf ( "\n\tproblem with input.");
                if ( 0 > x || x >= shelf) {
                    printf ( " bad shelf.");
                }
                if ( 0 > y || y >= slot) {
                    printf ( " bad slot.");
                }
                printf ( " try again\n\n");
            }
        }
        else {
            fprintf ( stderr, "fgets EOF\n");
            //free structures then the pointers
            for (int i = 0; i < shelf; i++) {
                free ( thing[i]);
            }
            free ( thing);

            return 0;
        }
    }
    //free structures then the pointers
    for (int i = 0; i < shelf; i++) {
        free ( thing[i]);
    }
    free ( thing);

    return 0;
}
...