Thread: Homework Correction !!Urgent!!

  1. #1
    Registered User
    Join Date
    Jul 2009
    Posts
    16

    Homework Correction !!Urgent!!

    I've written the C code below wich seem to be correct in the syntax BUT it does not what I want!!!
    this i what it sould do:
    • ask a file name
    • read filename and memorize data in a dynamic list
    • wait for a command

    the possible command are:
    • 'I <file_name2>' which memorizes the data of filename in another dynamic list
    • 'R' looks for negative values in a record in the second list
    • 'v <string>' search the value contained in string in the list and prints the record on the screen
    • 't' terminate


    (I hope it's clear: I'm italian and the code is written in Italian as well as the exercise so...)

    If you wanna try this code you should provide file 1 and 2:
    you can copy and paste the lines below in any text editor:
    file 1:
    Code:
    2
    1234-5678-9000 Rossi Mario +1050.00
    1234-5678-9999 Bianchi Rosa +1200.50
    file 2
    Code:
    3 1234-5678-9000 10.07.2009:15.30.00 +150.00
    2 1234-5678-9999 10.07.2009:09.45.00 -200.00
    1 1234-5678-9999 09.07.2009:10.45.00 +1200.50
    2 1234-5678-9000 04.07.2009:12.00.00 -250.00
    1 1234-5678-9000 01.07.2009:10.00.00 +500.00
    and at last here is the code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h> /*dimenticato*/
    
    #define MAX_STR 100+1
    #define MAX_NOMEFILE 20+1
    
    FILE *f_conti, *f_op;
    
    typedef struct dati_s{
        char num_conto[MAX_STR];
        char cognome[MAX_STR];
        char nome[MAX_STR];
        float saldoi;
        struct dati_s *next;
    }dati;
    dati *p_testa, *p_corr;
    
    typedef struct movimenti_s{
        int num;
        char num_conto[MAX_STR];
        char data [19+1];
        float val;
        float saldo;
        struct movimenti_s *next;
    }movimenti;
    movimenti *p2_testa, *p2_corr;
    
    /*prototipi*/
    void inserisci1(dati **p_dati, char str1[], char str2[], char str3[], float tmp);
    void inserisci2(movimenti **puntdati, char cod[], char data_ora[], float valore, int num);/*AGGIUNTO int num);  l'ho lascaito aperto in caso dovessi passare altri parametri ma non ho più chiuso*/
    void libera_mem(movimenti **puntdati); /*non ho fatto a tempo a scrivere il prototipo*/
    void aggiornasaldo(dati **p1dati, movimenti **p2dati); /*FUNZIONE MANCANTE*/
    
    /*MAIN*/
    int main () /*dimenticato int*/
    {
        /*FILE IN*/
        char nf1[MAX_NOMEFILE];
        printf("Inserire nome file:\n");
        scanf("%s",nf1);
        f_conti=fopen(nf1,"r");
        if(f_conti==NULL)
        {
            printf("ERRORE LETTURA FILE!!!");
            return 0;
        }
        /*IMMAGAZZINO IN UNA LISTA*/
        int n,i;
        char s1[MAX_STR],s2[MAX_STR],s3[MAX_STR];
        float temp;
    
        fscanf(f_conti,"%d",&n);
        p_testa=NULL;
        for(i=0;(fscanf(f_conti, "%s%s%s%f", s1,s2,s3,&temp)!=EOF)&&(i<n);i++)
        {
            inserisci1(&p_testa,s1,s2,s3,temp);
        }
        fclose(f_conti);
        /*MENU'*/
        char carat[2], nf2[MAX_NOMEFILE];
        int num_op, esci;/*mancava dichiarazione di esci*/
        char cod[MAX_STR], dat[MAX_STR], n_conto[MAX_STR];/*mancava dichiarazione n_conto*/
        float valore;
    
        do
        {
            printf("Inserire il comando:\n");
            scanf("%s",carat); /*uso la scanf al posto di getchar perchè non riesco a farla funzionare*/
            switch(carat[0])
            {
                case 'i':
                case 'I':
                    scanf("%s",nf2);
                    libera_mem(&p2_testa);
                    p2_testa=NULL;
                    f_op=fopen(nf2,"r");
                    if(f_op==NULL)
                        printf("ERR. APERTURA FILE");
                    while(fscanf(f_op,"%d%s%s%f",&num_op,cod,dat,&valore)!=EOF)
                    {
                        inserisci2(&p2_testa,cod,dat, valore, num_op);
                    }
                    fclose(f_op);
                    /*aggiorna saldo*/
                    aggiornasaldo(&p_testa,&p2_testa); /*questa funzione mancava*/
                    break;
                case 'r':
                case 'R':
                    p2_corr=p2_testa;
                    int negativo;
                    while(p2_corr!=NULL)
                    {
                        if((*p2_corr).saldo<0)
                        {
                            printf("\n%s%f%s",(*p2_corr).num_conto,(*p2_corr).saldo,(*p2_corr).data);
                            negativo=1;
                        }
                        else if(negativo==1)
                        {
                            printf("%s",(*p2_corr).data); /*data è una stringa non un float*/
                        }
                    }/*macava la parentesi di chiusura del while*/
                    break;
                case 'v':
                case 'V':
                    scanf("%s", n_conto);
                    p2_corr=p2_testa;
                    while(p2_corr!=NULL) /*avevo scritto p2_corr invece di p2_testa*/
                    {
                        if((*p2_corr).num_conto==n_conto) /*avevo scritto p2_corr invece di p2_testa*/
                        {
                            printf("%s%s%f",(*p2_corr).num_conto, (*p2_corr).data,(*p2_corr).val); /* GUARDA COSA STAMPARE SUL TESTO mancava*/
                        }
                    }
                    break;
                case 't':
                case 'T':
                    esci=1; /*da dichiarare*/
                    break;
                default:
                    printf("ERRORE");
            }
        }while(esci!=1);
        return 0; /* dimenticato 0*/
    } /*END MAIN*/
    
    /* FUNZIONI */
    void inserisci1(dati **p_dati, char str1[], char str2[], char str3[], float tmp) /*non era completo*/
    {
        dati *puntcorr; /*mancava*/
        puntcorr=(dati*)malloc(sizeof(dati));/*cambiato da p_corr a puntcorr*/
        /*riempo i campi PARTE ASSENTE*/
        strcpy((*puntcorr).num_conto,str1);
        strcpy((*puntcorr).cognome,str2);
        strcpy((*puntcorr).nome,str3);
        (*puntcorr).saldoi=tmp;
        (*puntcorr).next=*p_dati;
    
        *p_dati=puntcorr;
        return;
    }
    /*LE FUNZIONI SUCCESSIVE ERANO COMLPETAMENTE MANCANTI*/
    
    void inserisci2(movimenti **p_dati, char cod[], char data_ora[], float valore, int num)
    {
        movimenti *puntcorr;
        puntcorr=(movimenti*)malloc(sizeof(movimenti));
        strcpy((*puntcorr).num_conto,cod);
        strcpy((*puntcorr).data,data_ora);
        (*puntcorr).val=valore;
        (*puntcorr).num=num;
        (*puntcorr).next=*p_dati;
        *p_dati=puntcorr;
        return;
    }
    void libera_mem(movimenti **puntdati)
    {
        movimenti *pcorr;
        pcorr=*puntdati;
        while(pcorr!=NULL)
        {
            free(pcorr);
        }
        return;
    }
    
    void aggiornasaldo(dati **p1dati, movimenti **p2dati)
    {
        dati *p1corr;
        movimenti *p2corr;
    
        p2corr=*p2dati;
    
        while(p2corr!=NULL)
        {
            p1corr=*p1dati;
            while(p1corr!=NULL)
            {
                if(strcmp((*p1corr).num_conto,(*p2corr).num_conto)==0)
                {
                    (*p1corr).saldoi+=(*p2corr).val;
                    (*p2corr).saldo=(*p1corr).saldoi;
                }
                p1corr=(*p1corr).next;
            }
            p2corr=(*p2corr).next;
        }
        return;
    }
    The problem is that when I run the file it does evrything well as soon as I type the the first command when it exit the program without any error, it just skip evrything after the switch.

    I know it's hard to read a code in a "different language" (italian)... thanks in advance!!! I'm really desperate!!!

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    can try to explain what the program is doing, in English please!

  3. #3
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    it just skip evrything after the switch.
    There's no code after your switch statement. Do you mean that the loop the switch statement is in doesn't run as many times as you expect?

  4. #4
    Registered User
    Join Date
    Jul 2009
    Posts
    16
    Sure:

    the program has to manage in and out in bank accounts (sort of)
    it acquire file1 that contain the following information:
    <number of following lines>
    <account number> <name> <surname> <money in the account>
    <account number> <name> <surname> <money in the account>
    ...
    the flie 2 contains the movements made on the previus saved account
    with this format:
    <account number> <date and time> <money deposited/preleved>

    after acquiring file one you can choos from a menu of command:
    'I <filename2>' inputs the second file and updates the account balance;
    'r' search for any account with a negative value in the <money in the account> field and print it on screen as well as the period of "negativness" (not sure it' english)
    'v <account number>' visualize all the movement of the specified account
    't' terminates the program.


    sorry for my bad English!!
    hope this helps to understand better!!

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    [Your main problem is highlighted in bold below.]

    Code:
        char nf1[MAX_NOMEFILE];
        printf("Inserire nome file:\n");
        scanf("%s",nf1);
    It's not a good idea to read strings with %s, and in particular filenames. If the filename contained spaces your program wouldn't open it properly. I'd suggest using fgets() instead (just remember to remove the newline from the string) if you get a chance to change the code.

    Code:
        int n,i;
        char s1[MAX_STR],s2[MAX_STR],s3[MAX_STR];
        float temp;
    These variables are declared in main() after you've put some real code. In other words, the variables are being declared in the middle of the block. This isn't necessarily a bad thing, but it does mean that your code isn't C89-compatible. Whether this is important or not is up to you.

    Code:
    for(i=0;(fscanf(f_conti, "%s%s%s%f", s1,s2,s3,&temp)!=EOF)&&(i<n);i++)
    fscanf() returns the number of items successfully read, and returns EOF at end of file. So you're checking for one error condition there, but not all of them -- what if fscanf() was able to read the %s's but not the %f? It's better to use
    Code:
    for(i=0;(fscanf(f_conti, "%s%s%s%f", s1,s2,s3,&temp)!=4)&&(i<n);i++)
    Here I used 4 since you specify 4 format specifiers in fscanf()'s format string.

    Code:
                    if(f_op==NULL)
                        printf("ERR. APERTURA FILE");
                    while(fscanf(f_op,"%d%s%s%f",&num_op,cod,dat,&valore)!=EOF)
                    {
                        inserisci2(&p2_testa,cod,dat, valore, num_op);
                    }
                    fclose(f_op);
    If you can't open the file, you don't want to try to read from it or try to close it. Both will cause a segmentation fault.

    By the way, this
    Code:
    (*p2_corr).data
    is exactly the same thing as
    Code:
    p2_corr->data
    except that many people consider the latter easier to read.

    Here:
    Code:
                    p2_corr=p2_testa;
                    while(p2_corr!=NULL) /*avevo scritto p2_corr invece di p2_testa*/
                    {
                        if((*p2_corr).num_conto==n_conto) /*avevo scritto p2_corr invece di p2_testa*/
                        {
                            printf("%s%s%f",(*p2_corr).num_conto, (*p2_corr).data,(*p2_corr).val); /* GUARDA COSA STAMPARE SUL TESTO mancava*/
                        }
                    }
    That will be an infinite loop if there's anything in the linked list at all, because you never change p2_corr. I think you need a line like this at the end of the loop:
    Code:
    p2_corr = p2_corr->next;
    The same problem occurs in other places in the code. Just check your loops. I see at least four while loops that are infinite.

    Code:
    void inserisci1(dati **p_dati, char str1[], char str2[], char str3[], float tmp) /*non era completo*/
    I see that in this function you use the first parameter, d_dati, to pass data out of the function. It works, but you might find that the code is simpler if you return the value, e.g.
    Code:
    dati *inserisci1(char str1[], char str2[], char str3[], float tmp) /*non era completo*/
    [edit] Quite a few posts while I was typing this up, but I think my post is still relevant. [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Registered User
    Join Date
    Jul 2009
    Posts
    16
    what do you mean with:
    There's no code after your switch statement
    the switch has a lot of "cases" just below him and there's I lot of code too...

    any way the problem is that before entering the switch he ask for a command:
    Code:
    printf("Inserire il comando:\n");
            scanf("%s",carat);
    when I reply typing
    Code:
    i filename2.txt
    he just exit the program without executing case 'i'

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    In the case 'i' code, you'll want to move the statement
    Code:
    p2_testa=NULL;
    into the while loop. Actually, you don't even need to do that at all, since the function will just overwrite the value.

    The program just exits? Does it exit normally or with a segmentation fault/"This program has stopped responding" dialog?

    Anyway, read my other comments, and especially fix your while loops, and see if that helps at all . . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Code:
    while(esci!=1);
    esci is not initialized when it is declared (which means it starts as an undefined value). You only set esci to a value when the user types in a 'T' or 't'. This means that every iteration through the loop up until that point, esci is checked to see if it equals 1, but it holds an undefined value.

    Basically, you should change your declaration to:
    Code:
    nt num_op, esci = 0;/*mancava dichiarazione di esci*/
    This is just an aside as the root of your problem is probably what dwks pointed out.

  9. #9
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    when I reply typing

    "i filename2.txt"

    he just exit the program without executing case 'i'
    The carat variable is only 2 chars in size. How is it going to fit "i filename2.txt"? You need to increase the size of your carat array.

  10. #10
    Registered User
    Join Date
    Jul 2009
    Posts
    16
    thanks everybody!!
    I'll do the modification suggested in a minute and update..

  11. #11
    Registered User
    Join Date
    Jul 2009
    Posts
    16
    to bithub:
    its just 2 in dimansion becuse it just read i filename is being read in the case i by another scanf!
    it's not very clean but it should work.

  12. #12
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    As noted the 'r' and 'v' cases are stuck in an infinte loop unless steps are taken to terminate the two while loops.

  13. #13
    Registered User
    Join Date
    Jul 2009
    Posts
    16
    yes the big problems were the infinite loops and the varible esci not initialized to zero.
    the other problems pointed out by dwks are not affecting the results... I wont correct them because I can't :-) the original program is already in the hands of the professor so I have to make only the necessary modifications to mak it work!! BUT I'll try to keep them in mind the next time!!
    so again thanks everybody!!!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. need urgent Homework help
    By zakimasmoudi in forum C Programming
    Replies: 2
    Last Post: 11-11-2007, 03:54 PM
  2. Urgent homework help for NEWBIE
    By Kazasan in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2004, 04:23 PM
  3. Urgent - Help - Homework Question
    By Sway2 in forum C++ Programming
    Replies: 12
    Last Post: 10-04-2002, 01:35 PM
  4. Urgent Maths Homework :(
    By (TNT) in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 01-09-2002, 09:01 PM