1

私の C コードに問題があります。助けていただければ幸いです。プログラムは基本的な本「データベース」を作ることです。次のコードを (Xcode で) 実行すると、次の文がスキップされる理由がわかりません。

gets(名前[i]);

メニューからオプション1を選択すると、端末では次のように直接出力されます。

Bienvenido al catalogo de libros.

Catalogo de tarjetas: 1. イントロデューサー 2. 作者の検索 3. タイトルの検索 4. Salir

Elija opcion:1 警告: このプログラムは gets() を使用していますが、これは安全ではありません。

Introduzca el nombre del libro:Introduzca el autor del libro:

わかりましたので、scanf("%d", &opcion); をテストしました。printf("%d", オプション) の使用; scanf が私の入力を正しく読み取ることを証明する直後。驚いたことに、私が導入したオプションを正しく読み取ります。さらに、gets(nombre[i]) が機能するかどうかを確認するために、「\n」を使用せずにプログラムを実行しようとしましたが、それでもジャンプします...

何か案は?

これは完全なコードです (長くはありません):

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

#define MAX 100

char nombre[MAX][20];
char autor[MAX][20];
char edit[MAX][20];
char buscar[20];
char buscar_t[20];
char buscar_a[20];


int opcion,i,j,k,l;

void menu(void);
void intro(void);
void buscar_autor(void);
void buscar_tit(void);
void salir(void);

void main(void)
{
    printf("Bienvenido al catalogo de libros. \n");
    menu();
}




void menu(void)
{
    printf("\n Catalogo de tarjetas:");
    printf("\n 1. Introducir");
    printf("\n 2. Buscar por autor");
    printf("\n 3. Buscar por titulo");
    printf("\n 4. Salir");

    printf("\n Elija opcion:");
    scanf("%d", &opcion);

    switch (opcion) {
        case 1:
            intro();
            break;
        case 2:
            buscar_autor();
            break;
        case 3:
            buscar_tit();
            break;
        case 4:
            salir();
            break;

    }


}

void intro(void)
{
        for (i=0; i<MAX; i++) 
        {
            printf("Introduzca el nombre del libro:");
            gets(nombre[i]);

            if (!strcmp(nombre[i],"salir")) 
            {
                break;
            }

            printf("Introduzca el autor del libro:");
            gets(autor[i]);
            printf("Introduzca la editorial del libro:");
            gets(edit[i]);
        }

    menu();

}

void buscar_tit(void)
{
    printf("Introduzca el titulo del libro que quiera buscar:");
    gets(buscar_t);

    for (j=0; j<MAX+1; j++) 
    {
        if (!strcmp(nombre[j],buscar_t)) 
        {
            printf("El libro se ha encontrado, el titulo es %s. ", nombre[j]);
            break;
        }
        if (j=MAX) 
        {
            printf("El libro no se ha encontrado.");
            break;
        }

    }

}

void buscar_autor(void)
{
    printf("Introduzca el autor del libro que quiera buscar:");
    gets(buscar_a);

    for (k=0; k<MAX+1; k++) 
    {
        if (!strcmp(autor[k],buscar_a)) 
        {
            printf("El libro se ha encontrado, el titulo es %s. ", nombre[k]);
            break;
        }
        if (k=MAX) 
        {
            printf("El autor no se ha encontrado.");
            break;
        }
    }
}

void salir(void)
{
    printf("Muchisimas gracias por usar el catalogo de libros. \n");
}

エラーを理解するのを手伝ってくれることを願っています。

みんなありがとう。

4

1 に答える 1

1

gets の使用は避けてください。stdinをストリームとして 指定するfgetsを使用します。

 char *fgets(char *s, int size, FILE *stream);

コードでこの関数を変更します。

void intro(void)
{
        getchar(); //added this to avoid escaping at early stage of loop
        for (i=0; i<MAX; i++)
        {
            printf("Introduzca el nombre del libro %d : ",i+1); //modified this statement to know which iteration is going on by printing the loop counter value
            fgets(nombre[i],sizeof(nombre[i]),stdin); //  replaced  gets(nombre[i]);

            if (!strcmp(nombre[i],"salir"))
            {
                break;
            }

            printf("Introduzca el autor del libro: %d : ",i+1);
            gets(autor[i]);  //here also use fgets
            printf("Introduzca la editorial del libro %d : ",i+1);
            gets(edit[i]);   //here also use fgets 
        }

    menu();

}

小さな提案:

デバッグを簡単にするために、次のように変更#define MAX 100します#define MAX 5

この安全な代替手段を参照してください

あなたの場合、fgets で問題が繰り返される場合は、getchar();を追加するだけです。
fgets の前に、これも参照してくださいfgets オーバーフロー後に入力バッファーをクリアする方法は?

gets の man ページから

バグ gets() は絶対に使用しないでください。データを事前に知らなければ gets() が読み取る文字数を知ることは不可能であり、gets() はバッファの末尾を超えて文字を格納し続けるため、使用するのは非常に危険です。コンピューターのセキュリティを破るために使用されています。代わりに fgets() を使用してください。

于 2013-08-28T12:00:38.377 に答える