首先,对不起我的英语,因为我不是一个讲英语的人。 我们是一群试图编写这段代码(用C语言编写)的学生,以解决几周前我们给出的练习。 这个程序可能工作或不工作,但问题是:它在中央while循环时崩溃,它用于读取使用命令行传递给程序的文件(在argv [1]中指定的文件,换句话说)第二次重复。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#define VERO 1
#define FALSO 0
struct alimento{
char tipo_alimento;
float consumo;
int mesi_considerati;
float controllo_mese;
float spesa_totale;
float spesa_media_mensile;
};
int main(int argc, char* argv[])
{
FILE *fp;
int i;
struct alimento magazzino[4];
float vect[3];
char alimento;
int flag_decrescente = VERO;
int trovato_alimento = VERO;
float consumo_forfettario =0;
float acquisto_mensile;
char stringa[100];
//inizializzare mesi_considerati!!!!
//controllo parametri
if(argc!=2)
{
printf("Numero parametri non corretto\n");
exit(EXIT_FAILURE);
}
//apertura file
if((fp=fopen(argv[1], "r"))==NULL)
{
printf("Errore nell'apertura del file\n");
exit(EXIT_FAILURE);
}
/* fscanf(fp,"%c %f %f %f", &alimento, &vect[0], &vect[1], &vect[2]);
printf("\n\n\n\n\n%c %f %f %f\n", alimento, vect[0], vect[1], vect[2]);
fgetc(fp);
fscanf(fp,"%c %f %f %f", &alimento, &vect[0], &vect[1], &vect[2]);
printf("\n%c %f %f %f\n", alimento, vect[0], vect[1], vect[2]);
fgetc(fp);
fscanf(fp,"%c %f %f %f", &alimento, &vect[0], &vect[1], &vect[2]);
printf("\n%c %f %f %f\n", alimento, vect[0], vect[1], vect[2]);
fgetc(fp);
*/
while((fgets(stringa, 100, fp))!=NULL)
{
sscanf(stringa, "%c %f %f %f", &alimento, &vect[0], &vect[1], &vect[2]);
printf("\n%c %f %f %f\n", alimento, vect[0], vect[1], vect[2]);
//controllo se è decrescente
flag_decrescente = VERO;
for(i=0; (i<2)&&(flag_decrescente); i++)
{
if(vect[i]>vect[i+1])
{
flag_decrescente = FALSO;
}
}
//METTO L'ALIMENTO IN MAGAZZINO E VI ASSOCIO IL CONSUMO MENSILE
/* se il flag è decrescente il consumo è la differenza tra vect[2] - vect[0]*/
if(flag_decrescente == VERO)
{
trovato_alimento = FALSO;
for(i=0; (i<4)&&(!trovato_alimento); i++)
{
if(magazzino[i].tipo_alimento == alimento)
{
trovato_alimento = VERO;
magazzino[i].consumo += (vect[0]-vect[2]);
magazzino[i].mesi_considerati++;
//controllo la corrispondenza tra un mese e l'altro
//scelta della quantita' acquistata in base all'alimento
if(alimento == 'F') acquisto_mensile = 150;
else if(alimento == 'V') acquisto_mensile = 1200;
else if(alimento == 'Z') acquisto_mensile = 40;
else if(alimento == 'L') acquisto_mensile = 60;
//stampo se ho discordanza
if(vect[0]!=(magazzino[i].controllo_mese+acquisto_mensile))
{
printf("Alimento %c: le scorte %.2f sono differenti rispetto le rimanenze %.2f sommate all'acquisto mensile %.2f\n", alimento, vect[0], magazzino[i].controllo_mese, acquisto_mensile);
}
magazzino[i].controllo_mese = vect[2];
}
}
if(!trovato_alimento)
{
magazzino[i].tipo_alimento = alimento;
magazzino[i].consumo += (vect[0]-vect[2]);
magazzino[i].mesi_considerati++;
magazzino[i].controllo_mese = vect[2];
}
}
else
{
//devo inserire un consumo forfettario
if(alimento == 'F') consumo_forfettario = 150;
else if(alimento == 'V') consumo_forfettario = 1000;
else if(alimento == 'Z') consumo_forfettario = 30;
else if(alimento == 'L') consumo_forfettario = 50;
trovato_alimento = FALSO;
for(i=0; (i<4)&&(!trovato_alimento); i++)
{
if(magazzino[i].tipo_alimento == alimento)
{
trovato_alimento = VERO;
magazzino[i].consumo += consumo_forfettario;
magazzino[i].mesi_considerati++;
//ho già l'alimento quindi devo controllare eventuale discordanza
if(alimento == 'F') acquisto_mensile = 150;
else if(alimento == 'V') acquisto_mensile = 1200;
else if(alimento == 'Z') acquisto_mensile = 40;
else if(alimento == 'L') acquisto_mensile = 60;
if(vect[0]!=(magazzino[i].controllo_mese + acquisto_mensile))
{
printf("Alimento %c: le scorte %.2f sono differenti rispetto le rimanenze %.2f sommate all'acquisto mensile %.2f\n", alimento, vect[0], magazzino[i].controllo_mese, acquisto_mensile);
magazzino[i].controllo_mese = vect[2];
}
}
}
if(!trovato_alimento)
{
magazzino[i].tipo_alimento = alimento;
magazzino[i].consumo += consumo_forfettario;
magazzino[i].mesi_considerati++;
magazzino[i].controllo_mese = vect[2];
}
}
printf("everything is ok here1\n");
}
//calcolo della spesa totale
for(i=0; i<4; i++)
{
if(magazzino[i].tipo_alimento == 'V')
{
magazzino[i].spesa_totale = magazzino[i].consumo * 0.02;
magazzino[i].spesa_media_mensile = magazzino[i].spesa_totale = magazzino[i].mesi_considerati;
}
else if(magazzino[i].tipo_alimento == 'F')
{
magazzino[i].spesa_totale = magazzino[i].consumo * 0.20;
magazzino[i].spesa_media_mensile = magazzino[i].spesa_totale = magazzino[i].mesi_considerati;
}
else if(magazzino[i].tipo_alimento == 'Z')
{
magazzino[i].tipo_alimento = magazzino[i].consumo * 0.7;
magazzino[i].spesa_media_mensile = magazzino[i].spesa_totale = magazzino[i].mesi_considerati;
}
else if(magazzino[i].tipo_alimento == 'L')
{
magazzino[i].tipo_alimento = magazzino[i].consumo * 1.05;
magazzino[i].spesa_media_mensile = magazzino[i].spesa_totale = magazzino[i].mesi_considerati;
}
printf("tutto ok\n");
}
return 0;
}
使用Code :: Blocks 13.12编译此代码,文件的第一行被正确读取(好吧,我实际上知道可以使用fscanf而该字符串可能有点长,但都使用fscanf或者减少字符串大小显然没有解决问题),然后循环到达它的末尾(“打印一切都好”1),并且当再次调用fgets时,程序崩溃。 我无法解决这个问题。你知道为什么它在那时真的崩溃了吗?是Code :: Blocks错误还是(更可能)代码错误? 非常感谢。
顺便说一句,文件示例如下:
F 250.50 165.18 135.50
L 68.50 42.00 22.50
Z 52.00 24.50 17.00
V 1200.00 750.50 50.00
F 285.50 215.50 155.50
L 82.50 85.00 20.00
Z 57.00 32.00 12.00
V 950.00 650.00 250.00
答案 0 :(得分:1)
你正在编写超出struct alimento magazzino[4];
的末尾,它只能从索引0到3进行寻址。在你离开while循环之后,如果在第137行发生了if(!trovato_alimento)
,你可以将内容分配给magazzino [4](因为在最终的for循环之后i = 4)并覆盖你的堆栈。
停止崩溃的一个可能的变化是将第20行更改为:
struct alimento magazzino[5];
这可能不是你想要做的,所以你必须从那里弄明白。