1

それはまた私であり、進歩しています...私の最後の質問にコメントしてくれたすべての人に感謝したいと思います。それは非常に役に立ちました。これまでのところコンパイルできましたが、解決できない奇妙なバグがいくつかあります。

void addRecord(){//carries users input data

numRecs++;//increments numRecs by 1 

struct record library; //this will hold info for user input

printf ("Please enter your first name:\n");
fgets(library.fName, sizeof(library.fName), stdin);
printf ("Please enter your last name:\n");
fgets(library.lName, sizeof(library.lName), stdin);
printf ("Please enter your hometown:\n");
fgets(library.hometown, sizeof(library.hometown), stdin);


printf("You entered %s for your first name.\n", library.fName);
printf("You entered %s for your last name.\n", library.lName);
printf("You entered %s for your hometown.\n", library.hometown);


struct record *myNewRecord;//creates a new struct pointer to store   all the old data and new data


myNewRecord = malloc(numRecs * sizeof(struct record));      //allocates space to fit all old data plus the new struct data
if (myNewRecord == NULL)
{
fprintf(stderr,"Out of memory\n");
}

*myNewRecord = library;

fprintf(stderr, "You made it here!!\n");

これらは、ターミナルから取得した結果です。ソース コードの構文はすべて正しいように見えますが、何らかの理由で最初の名前 fgets がスキップされていることが問題です。また、プリントアウトするとなんとなくリターンを実行します。何が起こっているかわかりますか?PS スイッチのケースを削除し、メインに addrecord() しかない場合、これは行われません。

ubuntu@ubuntu:~$ 
ubuntu@ubuntu:~$ gcc lab222.c -o lab222
ubuntu@ubuntu:~$ ./lab222

Please select from the following:
 1. Print all records.
 2. Print number of records.
 3. Print size of database.
 4. Add record.
 5. Delete record.
 6. Print number of accesses to database.
 7. Exit.
Enter a number 1-7:4
Please enter your first name:
Please enter your last name:
Don
Please enter your hometown:
Mega
You entered 
 for your first name.
You entered Don
 for your last name.
You entered Mega
 for your hometown.
You made it here!!
4

2 に答える 2

2

変化する:

scanf("%d",&sel);
if (scanf("%d", &sel) == 0) {
    fprintf(stderr, "Error, not a valid input. Must be a number from 1 to 7.\n");
    scanf("%s", &c);
    continue;
}

に:

char reponse[MAX];
fgets(response, sizeof response, stdin);
int result = sscanf(response, "%d", &sel);
if (result != 1) {
    fprintf(stderr, "Error, not a valid input. Must be a number from 1 to 7.\n");
    continue;
}

fgets()続いて使用すると、単独sscanf()で使用したときに改行が読み取られないという問題が解決scanf()されます。scanf()で再度呼び出しifていたため、入力を 2 回読み取っていました。

于 2013-10-04T01:16:55.327 に答える
1

いくつかの観察、

  • 配列の再割り当てを保存し、すべてのレコードの以前の値をコピーします
  • 新しいレコードへのポインターの配列を割り当て、レコードを追加するときにその配列を埋める
  • データレコードよりもはるかに安価にそのポインター配列を再割り当てできます
  • メニュー表示とメニュー選択の決定を別々の機能に移動
  • おそらくリンクされたリスト(ヘッド、ムーバー?)を追加するので、ポインター配列は近いです
  • fgets を使用して入力を読み取ります。scanf よりもけいれんしません。
  • sscanf を使用してメニューの選択肢を抽出することもできます (これで問題は解決しました)

これが改訂された記録保管庫です。

#include<stdio.h>
#include<stdlib.h> //needed for malloc, free
#include<string.h> // needed for the memcpy
#define MAX 100

struct record
{
    char fName[MAX];
    char lName[MAX];
    char hometown[MAX];
};             //structure template/declaration
struct record* records[500]; //allow room for 500 (for now)
int numRecords=0;  //stores number of records, used for several tasks

//prototypes
int addRecord();

ここにメニューを表示し、入力を読み取る関数があります(ビュー)

//********MENU***********
int menushow(FILE* fh)
{
    printf("\nPlease select from the following:\n");
    printf(" 1. Print all records.\n");
    printf(" 2. Print number of records.\n");
    printf(" 3. Print size of database.\n");
    printf(" 4. Add record.\n");
    printf(" 5. Delete record.\n");
    printf(" 6. Print number of accesses to database.\n");
    printf(" 7. Exit.\n");
    printf("Enter a number 1-7:");
    return 0;
}
int menudo(char* line)
{
    int sel;
    int choice;
    if( sscanf(line,"%d",&sel) < 1 ) {
        fprintf(stderr, "Error, not a valid input. Must be a number from 1 to 7.\n");
        return 0;
    }
    switch(choice = atoi(line))
    {

    case 1:

        break;

    case 2:

        break;

    case 3:

        break;

    case 4:
        if( addRecord() < 0 )    //This creates a new record based of input into struct library.
            fprintf(stderr,"addRecord failure\n");
        break;
    case 5:

        break;

    case 6:

        break;

    case 7:
        exit(0);
        break;

    default:
        printf("\nError, not valid input. Please enter a  number from 1 to 7.\n\n");
        break;
    }
    return choice;
}

メニュー処理を関数に抽出したメインはこちら、

#define EXITCHOICE 7
int main(void)
{
    char line[MAX+1];
    int action=0;
    while (action<EXITCHOICE)
    {
        menushow(stdout);
        if( !fgets(line,sizeof(line),stdin) ) { break; }
        //printf("entered: %s\n",line);
        if( (action=menudo(line)) < 0 ) break;
    }
    return 0;
}

これは単純な addrecord です。

//** Beginning of addRecord**
//returns -1 on failure
int
addRecord()
{//carries users input data
    struct record library; //this will hold info for user input
    struct record *myNewRecord; //creates a new struct pointer to store   all the old data and new data

    printf ("Please enter your first name:\n");
    if(!fgets(library.fName, sizeof(library.fName), stdin)) return -1;
    printf ("Please enter your last name:\n");
    if(!fgets(library.lName, sizeof(library.lName), stdin)) return -1;
    printf ("Please enter your hometown:\n");
    if(!fgets(library.hometown, sizeof(library.hometown), stdin)) return -1;

    printf("You entered %s for your first name.\n", library.fName);
    printf("You entered %s for your last name.\n", library.lName);
    printf("You entered %s for your hometown.\n", library.hometown);

    records[numRecords] = (struct record*)malloc(sizeof(struct record));      //allocates space to fit all old data plus the new struct data
    if (records[numRecords] == NULL)
    {
        fprintf(stderr,"error: Out of memory\n");
        return -1;
    }
    memcpy(records[numRecords],&library,sizeof(struct record));
    numRecords++;//increments numRecords by 1 
    fprintf(stderr, "[%d] records!!\n",numRecords);
    return(numRecords);
}
于 2013-10-04T01:56:49.850 に答える