这是一个在图书馆中注册书籍的程序,其中包含标题、作者和价格。以及计算平均值、最高价格书籍等内容...当我使用 vector {struct livro Livros[1000] 时,它运行得很好]} 而不是指针 {struct livro *Livros}。 我使用指针为书籍列表动态分配内存,并且注册书籍的一切都运行良好。但是当我尝试计算平均值(它调用另一个函数到 main )时,程序崩溃并且编译器(我在学校使用 Visual Studio)显示该消息:
Livraria.exe 中 0x00ec174c 处未处理的异常:0xC0000005:读取位置 0xcccccd94 时发生访问冲突。
我尝试使用该函数按编写器而不是平均值进行定位,但在我放置字符串后它就崩溃了。当然,当它使用“Livros[i].autor”来比较字符串时
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define flush_toilet (fflush(stdin))
//mude o #define dependendo do seu SO
//__fpurge(stdin); "linux"
//fflush(stdin); "windows"
struct livro {
char titulo [100];
char autor [100];
float prec;
};
//register
void cadastro (int *qtd, struct livro *Livros){
int i;
Livros=NULL;
printf("Insira a quantidade de livros:");//defines the quantity(variable "qtd") of books which will pass to the main function(it worked when i used vectors)
scanf ("%i",qtd);
flush_toilet;
Livros = malloc( *qtd *sizeof(struct livro)); //allocates the memory for the list
printf ("insira os dados de cada livro:");
for (i=0;i<*qtd;i=i+1){
printf ("\n\n\ninsira o titulo:");
gets (Livros[i].titulo); //title
flush_toilet;
printf ("\ninsira o nome:");
gets (Livros[i].autor); //writer
flush_toilet;
printf ("\ninsira o preco :");
scanf ("%f",&Livros[i].prec);//price
flush_toilet;
}
}
//calculate average of prices
float media (int qtd, struct livro *Livros){
int i;
float media=0;
for (i=0;i<qtd;i=i+1){
media=media+Livros[i].prec;
}
media=media/qtd;
return media;
}
//calculate number of books above average
int qtd_acima_med (float media, struct livro *Livros, int qtd){
int acima=0,i;
for (i=0;i<qtd;i=i+1){
if(Livros[i].prec>media){
acima=acima+1;
}
}
return acima;
}
//locate a book by writer
void localizar(int qtd, struct livro *Livros){
int i;
char autor[100];
printf("\ndigite o nome do autor cujos livros deseja encontrar:\n");
gets (autor);
flush_toilet;
printf("\n");
for (i=0;i<qtd;i=i+1){
if((strcmp (autor, Livros[i].autor))==0){
puts(Livros[i].titulo);
printf("\n");
}
}
}
//finds and displays the most expensive book
void mais_caro (int qtd, struct livro *Livros ){
int i, ncaro;
float caro=0;
for (i=0;i<qtd;i=i+1){
if (Livros [i].prec>caro){
caro=Livros [i].prec;
ncaro=i;
}
}
puts (Livros[ncaro].titulo);
printf ("preco: %f\n", Livros[ncaro].prec);
}
void main (){
struct livro *Livros;
int qtd=-1, selec=1, nacima=-1;
float med=-1;
while (selec!=0){
printf ("\n\n\nDigite 0 para sair,\n 1 para cadastrar,\n 2 para calcular a media,\n 3 para calcular os livros acima da media,\n 4 para localizar o livro pelo autor,\n 5 para achar o mais caro.\n\n");
scanf("%i", &selec);
flush_toilet;
switch (selec){
case 0:
break;
case 1:{
cadastro(&qtd, Livros);
break;
}
case 2:{
if(qtd<0){
printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
break;
}
med=media(qtd, Livros);
printf("A media e igual a: %f \n", med);
break;
}
case 3:{
if(med<0){
printf("erro a media n foi calculada\n");
break;
}
nacima = qtd_acima_med (med, Livros, qtd);
printf("A qtd de livros com preco acima da media e: %i \n", nacima);
break;
}
case 4:{
if(qtd<0){
printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
break;
}
localizar(qtd, Livros);
break;
}
case 5:{
if(qtd<0){
printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
break;
}
mais_caro (qtd, Livros);
break;
}
}
}
free(Livros);
}
最佳答案
编译时出现以下错误:
1>main.c(138) : warning C4700: uninitialized local variable 'Livros' used
这似乎是该错误的原因。要修复此问题,您需要从 cadastro 返回分配的数组:
struct livro * cadastro (int *qtd){
int i;
struct livro *Livros =NULL;
printf("Insira a quantidade de livros:");//defines the quantity(variable "qtd") of books which will pass to the main function(it worked when i used vectors)
scanf ("%i",qtd);
flush_toilet;
Livros = malloc( *qtd * sizeof(struct livro)); //allocates the memory for the list
printf ("insira os dados de cada livro:");
for (i=0;i<*qtd;i=i+1){
printf ("\n\n\ninsira o titulo:");
gets (Livros[i].titulo); //title
flush_toilet;
printf ("\ninsira o nome:");
gets (Livros[i].autor); //writer
flush_toilet;
printf ("\ninsira o preco :");
scanf ("%f",&Livros[i].prec);//price
flush_toilet;
}
return Livros;
}
然后在main()
中使用return:
void main (){
struct livro *Livros = NULL;
int qtd=-1, selec=1, nacima=-1;
float med=-1;
while (selec!=0){
// Snip
switch (selec){
// snip
case 1:
{
if (Livros != NULL)
{
free(Livros);
Livros = NULL;
}
Livros = cadastro(&qtd);
}
break;
您还需要检查 scanf()
和 gets()
的返回值,以防没有更多输入或无效输入,并且有默认情况用户为 selec
输入无效值的事件。您还应该考虑替换 gets()
with fgets()
以防止缓冲区溢出。但崩溃的直接原因是未初始化的变量。想必您的编译器也会报告类似的警告,如果确实如此,则应始终修复此类警告。
关于不能使用结构体指针作为多个函数的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27434950/