结构和malloc代码得到奇怪的输出
又是我在进步。。。我想感谢所有对我最后一个问题发表评论的人,这非常有帮助。到目前为止,我已经编译了这个,但是有一些奇怪的错误,我无法解决结构和malloc代码得到奇怪的输出,c,struct,malloc,switch-statement,C,Struct,Malloc,Switch Statement,又是我在进步。。。我想感谢所有对我最后一个问题发表评论的人,这非常有帮助。到目前为止,我已经编译了这个,但是有一些奇怪的错误,我无法解决 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
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。而且,当它打印出来时,它会以某种方式执行一个返回。你们能看到发生了什么吗???另外,当我去掉开关的情况,并且在main中只有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!!
更改:
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;
}
致:
使用fgets()
后跟sscanf()
解决了单独使用scanf()
时不读取换行符的问题。您还在if
中再次调用scanf()
,因此它读取了两次输入。一些观察结果
- 保存重新分配数组和复制每个记录以前的值
- 为新记录分配一个指针数组,并在添加记录时填充该数组
- 您可以比数据记录更便宜地重新分配指针数组
- 将菜单显示和菜单选择确定移动到单独的功能
- 您可能会添加一个链表(head、mover?),这样指针数组就接近了
- 使用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();
我只是想知道,这是我将句子的第二部分放在另一行的原因,因为我为空间分配了50个字节,并且它使用了所有的空间?当你要求从菜单中进行选择时,你调用了两次
scanf()
。您还需要做一些事情来读取选择后的换行符,否则它将被视为addRecord()
中的第一个输入。将3scanf()
,替换为while((scanf(“%d”,&sel)!=1)|(sel<1)|(sel>7)){
我想我需要这三个scanf。第一个选项允许用户在switch语句中选择他们想要的选项。第二个选项说明所有不在1-7范围内的数字。最后,第三个选项是可怕的字符项的故障保护,这会创建一个不确定的循环。@Kevin是的,使用fgets()然后使用sscanf()我不得不在main的开头将结果声明为int,并将stding改为stdin。除此之外,效果很好…谢谢大家。哇,恰克!!!你们是救命恩人…我的老师没有帮我很多忙,但这一切都很有意义。非常感谢!!学习编程可能很难。我已经做了一段时间了。我很高兴能帮上忙!
#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);
}