Получение бесконечно работающей программы при использовании scanf - PullRequest
0 голосов
/ 02 ноября 2018

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

scanf("%s", strk_zgr_fp->bezeichnung, (int)sizeof(strk_zgr_fp->bezeichnung - 1));

Просто ничего не происходит после того, как эта строка достигнута и программа работает бесконечно.

Я знаю, scanf() не рекомендуется. Мы используем его только в рамках нашего курса C для начинающих, и я хочу, чтобы вы помнили об этом, т.е., пожалуйста, не рекомендуйте другие функции, а не упомянутые выше на данный момент.

Любая помощь очень ценится, заранее спасибо.

#include <stdio.h>

typedef struct {
    int nummer;
    char bezeichnung;
    int menge;
    float preis;
} artikel;

void eingabe_artikel(artikel *strk_zgr_fp, int i_fp);
void ausgabe_artikel(artikel *strk_zgr_fp, int i_fp);

void main(void) {
    artikel artikelliste[10];
    artikel *strk_zgr;

    int anzahl;

    do {
        printf("Bitte eine #Artikel eingeben [<= 10]: ");
        scanf("%d", &anzahl);

        if(anzahl < 1 || 10 < anzahl)
            printf("\nEs wurde eine falsche #Artikel eingegeben.");
    } while(anzahl < 1 || 10 < anzahl);

    for(int i = 0; i < anzahl; i++)
        eingabe_artikel(&artikelliste[i], i);

    int i;
    for(strk_zgr = artikelliste, i = 0; strk_zgr < artikelliste + anzahl; 
        strk_zgr++, i++)
        ausgabe_artikel(strk_zgr, i);
}

void eingabe_artikel(artikel *strk_zgr_fp, int i_fp) {
    printf("\nBitte den %d. Artikel eingeben: ", ++i_fp);

    printf("\nNummer: ");
    scanf("%d", &strk_zgr_fp->nummer);

    printf("Bezeichnung: );
    scanf("%s", strk_zgr_fp, (int)sizeof(strk_zgr_fp->bezeichnung - 1));     /* <-- */

    printf("Menge: ");
    scanf("%d", &strk_zgr_fp->menge);

    float preis;
    printf("Preis: );
    scanf("%f", &preis);
    strk_zgr_fp->preis = preis;
}

void ausgabe_artikel(artikel *strk_zgr_fp, int i_fp) {
    printf("\n%d. Artikel: ", ++i_fp);

    printf("\nNummer:\t%d", strk_zgr_fp->nummer);
    printf("\nBezeichnung:\t%s", strk_zgr_fp->bezeichnung);
    printf("\nMenge:\t%d", strk_zgr_fp->menge);
    printf("\nPreis:\t%.2f EUR\n", strk_zgr_fp->preis);    
}

Версия NetBeans

Версия Complier

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Я попробовал, и у меня все заработало. Не уверен в этой функции sprintf (). Не могли бы вы объяснить, почему я должен это использовать? К настоящему времени я использовал этот код: char format_str [20]; format_str [0] = '%'; strcat (format_str, "s"); printf ("Bezeichnung:"); scanf (format_str, strk_zgr_fp-> bezeichnung);

Пока это работает, вы упускаете возможность ограничения длины ввода пользователя. Вот почему я предложил использовать sprintf () для создания (под) строки, содержащей максимально допустимую длину пользовательского ввода, в зависимости от того, насколько большой ваш bezeichnung определен в структуре. Предположим, что bezeichnung имеет ограничение в 100 символов, вы хотите ограничить ввод до 99 (+1 для нулевого завершения), поэтому вам нужна строка формата scanf, например: «% 99s».

chux предоставил гораздо более компактную версию моих трех строк, но я думаю, что вначале вам будет проще просто собирать такие строки формата по частям, в то же время изучая, как а) изменить индивидуальность символы в строке, как использовать sprintf () базовым способом и как объединять строки с помощью strcat ().

Был еще один пример, который я сделал, и руководитель курса предоставил функцию scanf () для чтения строки: scanf ("% s", & (strk_zgr_fp-> bezeichnung)) ;. Я думал, что когда я читаю строку, оператор адреса не используется. Разница лишь в том, что теперь используется адресный оператор, а элемент заключен в квадратные скобки.

Теперь я думаю, что это плохая практика. Это работает, но это лишнее. Рассмотрим этот небольшой фрагмент кода:

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

struct test{
    int i;
    char a_str[10];
};

int main()
{
    struct test a_test;
    printf("Normal array adress taking: %p\n", a_test.a_str);
    printf("Using '&' to take adress of array: %p\n", &(a_test.a_str));
    return 0;
}

Надеюсь, это поможет.

0 голосов
/ 02 ноября 2018

Много проблем в коде. Пожалуйста, по крайней мере исправьте пропущенные заключительные кавычки в вызовах printf ().

Теперь к говядине:

1) Ваша структура неверна. «Bezeichnung» определяется как один символ, а не строка.

typedef struct {
   int nummer;
   char bezeichnung[100];
   int menge;
   float preis;
} artikel;

2) Вы не можете использовать scanf () так, как вы это делали. Если вы хотите ограничить длину ввода (что всегда является хорошей идеей), вам нужно передать максимальную длину в строку формата. Вы должны использовать scanf () ?? Потому что это становится грязным с этого момента .... Поскольку ваша максимальная длина ввода может быть переменной или подвержена изменениям (см. 1.), вам необходимо создать строку формата для scanf. Примерно так:

char format_str[15];
format_str[0] = '%';
//Dont use itoa(), it is not C standard.
sprintf(&format_str[1], "%d", (int)sizeof(strk_zgr_fp->bezeichnung) - 1);
strcat(format_str, "s");
scanf(format_str, strk_zgr_fp->bezeichnung);     

Надеюсь, это поможет вам.

PS: вам нужно включить string.h для strcat ().

...