这是一个在图书馆注册书籍的程序,包括标题,作家和价格。还有计算平均值,最高价格书等内容......当我使用矢量{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);
}
答案 0 :(得分:1)
编译时,我收到以下错误:
1>main.c(138) : warning C4700: uninitialized local variable 'Livros' used
这看起来是bug的原因。要修复,您需要从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 ()
中的回报:
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()
的返回值,并且如果用户输入{的无效值,则需要检查默认情况{1}}。您还应该考虑替换gets()
with fgets()
以防止缓冲区溢出。但崩溃的直接原因是未初始化的变量。据推测,您的编译器也会报告类似的警告,如果是,则应始终修复此类警告。