使用以下代码从键盘读取字符串并将其保存在结构化向量中时,我得到的是一个无限运行的程序。
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);
}
答案 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;
}
希望有帮助。