使用scanf

时间:2018-11-02 13:20:53

标签: c netbeans scanf

使用以下代码从键盘读取字符串并将其保存在结构化向量中时,我得到的是一个无限运行的程序。

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 Version

Complier Version

2 个答案:

答案 0 :(得分:1)

代码中的许多问题。请至少修复在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:您需要在strcat()中包含string.h。

答案 1 :(得分:0)

  

我尝试了一下,对我来说效果很好。不确定此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为我的三行代码提供了一个更为紧凑的版本,但是我认为,一开始,您将可以更轻松地逐段组装此类格式字符串,同时学习如何a)更改个人字符串中的字符,如何以基本方式使用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;
}

希望有帮助。