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,因此它读取了两次输入。

于 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;
}

这是更简单的添加记录,

//** 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 回答