0

Visualstuidoで次のコードを実行しようとしています。このコードを実行してから、ここに入力したコードの下で私の経験を読んでください。

#include <stdio.h>
#include <conio.h>
main()
{
int i;
struct book
{
    char name;
    float price;
    int pages;
};
struct book b[3];
printf("Enter the names prices & no. of pages of 3 books \n");
for (i = 0; i<=2; i++)
{
    printf("name of book %d : ", i +1);
    scanf("%c", &b[i].name);
    printf("price of book %d : ", i +1);
    scanf("%f", &b[i].price);
    printf("pages in book %d : ", i +1);
    scanf("%d", &b[i].pages);
}
for (i = 0; i<=2; i++)
{
    printf("Name of book : %c, Price of book: %f, Pages in book : %d \n", b[i].name, b[i].price, b[i].pages);
}
printf("Press any key to continue");
getch();
 }
void linkfloat()
{
    float a =0, *b;
    b = &a;
    a = *b;
}

ご覧のとおり、ユーザーに本の名前、ページ番号、価格を尋ねますが、Visual Basicでコードを実行すると、ユーザーが価格とページ番号を入力できる一方で、本b2以降の名前を入力できない場合があります。同じ本b[i]の場合、先に進むと、ユーザーが名前を入力できない場所に本名の空白スペースが印刷されます。

4

3 に答える 3

2

これは、入力を信頼してはいけない理由の1つですscanf()。間違った入力は、すべてを台無しにする可能性があるためです。以前に使用したコンパイラはわかりませんが、このコードは標準に準拠したcコンパイラでは機能しないはずです。

文字列を読み取ったり印刷したりするときは、formatタグを使用する必要があります%s%cは1文字のみを表すため、1文字より長い名前を入力すると、後続のすべての入力要求が台無しになります(フラッシュなどで適切に処理されない限りstdin)。

同様に、nameメンバーは完全な名前ではなく、1文字しか保存しない場合があります。配列に変更します。例:char name[64]。完全な名前を格納するのに十分な長さであることを確認してください(そしてバッファオーバーランを回避するため)。

他の間違いがあるかもしれませんが、それらはあなたが他の問題を見つけるのを妨げる最も重要なものだと思います(もしあれば)。

編集:コードを試してみましたが、改行(リターンキーを押すことによる)がまだに残っているために問題が発生しstdinます。整数またはfloatを読み取る場合、(有効な入力を形成しないため)スキップされますが、受け入れられ%cます(チェックしませんでしたが、チェックする場合は、読み取られる値がに等しいことに注意してください\n)。

これを修正するには、fflush(stdin);を使用して読んだ後に必ず呼び出してくださいscanf()。文字を読む直前にそれを行うことで十分なはずですが、それでも少しエラーが発生しやすくなります。

于 2012-04-23T09:06:47.213 に答える
2

char文字のためのスペースのみを提供します。同様に%c、文字を読み取るだけだと思います。

本の名前を保持するのに十分な大きさの char 配列に変更するか、名前を格納するためのメモリを取得するためchar *に使用します。malloc

于 2012-04-23T09:04:30.800 に答える
-1

SJuan76 が指摘した根本的な問題に加えて、行を終了すると、おそらくより適切に機能し、読みやすくなります。

printf("name of book %d:\n", i + 1);
于 2012-04-23T09:05:31.593 に答える