2014-06-20 135 views
0

首先,對不起我的英語,因爲我不是一個說英語的人太多。 我們是一羣試圖編寫這段代碼(用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; 
} 

編譯此代碼與代碼:: Blocks的13.12,該文件的第一行是正確地將讀(好吧,其實我知道的的fscanf可以用來代替和該字符串可能有點長,但都使用fscanf或減少字符串大小顯然不能解決問題),然後循環到達它的末端(「打印出一切正常here1」),並且當再次調用fgets時,該程序崩潰。 我無法解決這個問題。你知道爲什麼它真的在這一點上崩潰嗎?是一個代碼::塊錯誤或(更可能)代碼錯誤? 非常感謝。

順便說一句,一個文件的例子是下列之一:

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

請在此處顯示您的代碼*,而不是在某些外部網站上。 –

+0

對不起!我添加了代碼以及一個文件示例。 – user3761144

回答

1

你正在寫超出struct alimento magazzino[4];結束後你走出while循環僅根據索引0尋址到3,如果線137上的if(!trovato_alimento)發生,則將內容分配給magazzino [4](因爲在最後一個for循環後i = 4)並覆蓋您的堆棧。

一個可能的變化停止崩潰是改變線路20: struct alimento magazzino[5];

這可能不是正是你的意思做,壽,所以你必須從那裏弄明白。

+0

非常感謝!我們肯定不得不重新考慮這段代碼,以使其成功運行(目前這種做法並不奏效,但不幸的是),但我們發現它爲什麼真的崩潰了,這真是太棒了。 – user3761144