Thread: Particular problem with a for loop

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    78

    Particular problem with a for loop

    I have a particular problem with a for loop. This should write to a text file of the structures belonging to an ordered list in order to get a table.
    Here is the code:

    Code:
    struct comp
    {
        int code;
        char name[27];
        char des[52];
        int disp;
        struct comp *n;
    };
    
    struct comp *comps = 0, *p;
    
    FILE *fw = fopen("miofile.txt", "w");
    
    for(p = comps; p; p = p->n)
    {
    s1 = ((((float)(25 - strlen(p->name))) + 0.5) / 2);
    s2 = ((((float)(25 - strlen(p->name))) - 0.5) / 2);
    s3 = ((((float)(52 - strlen(p->des))) + 0.5) / 2);
    s4 = ((((float)(52 - strlen(p->des))) - 0.5) / 2) - 1;
    fprintf(fw, "|  %09.9i  ", p->code);
    fprintf(fw, "| %*s%.25s%*s ", s1, " ", p->name, s2, " ");
    fprintf(fw, "| %*s%.50s%*s ", s3, " ", p->des, s4, " "); fprintf(fw, "|    %09.9i    |\n", p->disp);
    }
    
    fclose(fw);


    But the cycle continues indefinitely, and the output file size becomes huge, although there are written only a few structures (tested with notepad ++). The strange thing is that if I try to visualize the structures on the screen, the same cycle adapted to the purpose and ends properly and if I try to write to a file only the code and the availability of components, leaving out the name and description, in this If the loop ends correctly.

    Here is the code:

    Code:
    for(p = comps; p; p = p->n)
    {
    s1 = ((((float)(25 - strlen(p->name))) + 0.5) / 2);
    s2 = ((((float)(25 - strlen(p->name))) - 0.5) / 2);
    s3 = ((((float)(52 - strlen(p->des))) + 0.5) / 2);
    s4 = ((((float)(52 - strlen(p->des))) - 0.5) / 2) - 1;
    fprintf(fw, "|  %09.9i  ", p->code);
    // fprintf(fw, "| %*s%.25s%*s ", s1, " ", p->name, s2, " "); not compiled
    // fprintf(fw, "| %*s%.50s%*s ", s3, " ", p->des, s4, " "); not compiled
    fprintf(fw, "|    %09.9i    |\n", p->disp);
    }
    Any suggestion?

  2. #2
    Registered User
    Join Date
    Aug 2010
    Posts
    231
    Where do you allocate memory for your structs?

  3. #3
    Registered User
    Join Date
    Sep 2011
    Posts
    78
    Here is the complete code of program:

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    void insert(void);
    void visualize(void);
    void save(void);
    int llinea(char *str, int n);
    
    struct comp
    {
        int code;
        char name[27];
        char des[52];
        int disp;
        struct comp *n;
    };
    
    struct comp *comps = 0;
    
    int main()
    {
        int c;
        for(;;)
        {
            fputs("________________________________________________________________________________\n", stdout);
            fputs("Database componenti ©2011\n\n", stderr);
    
            fputs("1 - Inserisci componente nel database\n\n", stderr);
            fputs("2 - Visualizza il database\n\n", stderr);
            fputs("3 - Salva database\n\n", stderr);
            fputs("4 - Esci dal programma\n", stderr);
            fputs("________________________________________________________________________________\n", stderr);
            fputs("Inserisci il codice corrispondente all'operazione: ", stderr);
    
            fflush(stdin);
            scanf("%i", &c);
    
            if(c == 1)
            {
                inserisci();
            }
            else if(c == 2)
            {
                visualizza();
            }
            else if(c == 3)
            {
                salva();
            }
            else if(c == 4)
            {
                return 0;
            }
            else
            {
                fputs("\nIl codice inserito non è valido.\n\n------------------------Premere un tasto per continuare---------------------\n", stderr);
                fflush(stdin);
                getchar();
                fputs("\n\n", stderr);
            }
    fputs("\n------------------------Premere un tasto per continuare---------------------\n", stderr);
                fflush(stdin);
                getchar();
                fputs("\n\n", stderr);
    
        }
    }
    
    void insert()
    {
        struct comp *p, *c, *nn = calloc(1, sizeof(struct comp));
    
        if(!nn)
        {
            fputs("Memoria piena. Impossibile aggiungere il componente.\n", stderr);
        }
    
        fputs("\nInserisci il codice del componente (max. 99999999): ", stderr);
        fflush(stdin);
        scanf("%9i", &nn->code);
    
        for(c = comps, p = 0; c && nn->code > c->code; p = c, c = c->n);
        if(c && (nn->code == c->code))
        {
            fputs("Il componente esiste gia'. Impossibile aggiungere il componente.\n", stderr);
            return;
        }
    
        fputs("Inserisci il nome del componente: ", stderr);
        llinea(nn->name, 25);
        fputs("Inserisci la descrizione del componente: ", stderr);
        llinea(nn->des, 100);
        fputs("Inserisci la disponibilita' del componente: ", stderr);
        fflush(stdin);
        scanf("%i", &nn->disp);
    
        nn->n = c;
        if(!p)
        {
            comps = nn;
        }
        else
        {
            p->n = nn;
        }
    }
    
    void visualize()
    {
        struct comp *p;
        for(p = comps; p; p = p->n)
            {
                fprintf(stderr, "\nCodice del componente:           %i\n", p->code);
                fprintf(stderr, "Nome del componente:             %s\n", p->name);
                fprintf(stderr, "Descrizione del componente:      %s\n", p->des);
                fprintf(stderr, "Disponibilita' del componente:   %i\n\n", p->disp);
            }
    }
    
    void save()
    {
        FILE *fw;
        struct comp *p;
    
        if((fw = fopen("C:\\Users\\Utente\\Desktop\\prova.txt", "w")) != NULL)
        {
         int s1;
         int s2;
         int s3;
         int s4;
    
                fputs("\n|    CODICE   |           NOME           |                     DESCRIZIONE                    |  DISPONIBILITA' |\n", fw);
                fputs("\n|             |                          |                                                    |                 |\n", fw);
    
                for(p = comps; p; p = p->n)
                {
                    s1 = ((((float)(25 - strlen(p->name))) + 0.5) / 2);
                    s2 = ((((float)(25 - strlen(p->name))) - 0.5) / 2);
                    s3 = ((((float)(52 - strlen(p->des))) + 0.5) / 2);
                    s4 = ((((float)(52 - strlen(p->des))) - 0.5) / 2) - 1;
                    fprintf(fw, "|  %09.9i  ", p->code);
                    fprintf(fw, "| %*s%.25s%*s ", s1, " ", p->name, s2, " ");
                    fprintf(fw, "| %*s%.50s%*s ", s3, " ", p->des, s4, " ");
                    fprintf(fw, "|    %09.9i    |\n", p->disp);
                }
        }
        fclose(fw);
    }
    
    int llinea(char *str, int n)
    {
        int c, i = 0;
    
        fflush(stdin);
        while(isspace(c = getc(stdin)));
    
        while(c != '\n')
        {
            if(i < n)
            {
                str[i++] = c;
            }
            c = getc(stdin);
        }
    
        if(n == i)
        {
            str[i++] = (int) "*";
        }
        str[i] = '\0';
    
        return i;
    }

  4. #4
    Registered User
    Join Date
    Nov 2011
    Posts
    29
    well, it doesn't compile...
    I don't know where you get the functions inserisci(), visualizza() from.
    It would also help if it where english...

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I don't know where you get the functions inserisci(), visualizza() from.
    You can't guess that inserisci() has been renamed to insert() and visualizza() to visualize()?

    > struct comp *p, *c, *nn = calloc(1, sizeof(struct comp));
    You should write
    nn->n = NULL;
    to explicitly set the next pointer to being NULL.
    See Question 5.17

    > fputs("Inserisci il nome del componente: ", stderr);
    stderr is for errors, not the normal flow of the program.

    > fflush(stdin);
    Oh dear - more bad news.
    SourceForge.net: Fflush - cpwiki

    > int llinea(char *str, int n)
    > if(n == i)
    The buffer is FULL and you're adding more data to it!

    Tell me, what is llinea doing that fgets() can't do?

    > str[i++] = (int) "*";
    If this is trying to add a * to the end of the line, then it's failing badly.
    Replace the " " with single quotes, and remove the cast.


    > s4 = ((((float)(52 - strlen(p->des))) - 0.5) / 2) - 1;
    Now look back carefully at your potential buffer overflows, and what might be the result of applying a NEGATIVE field width to printf.
    visualize() probably works ok because it doesn't attempt any fancy field width formatting.
    Also, you're repeating the same calculation 4 times - make it a function with some parameters.

    > fputs("Il componente esiste gia'. Impossibile aggiungere il componente.\n", stderr);
    > return;
    And what about nn - which you allocated.
    Where has that gone to?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with While loop
    By Arthurdent in forum C Programming
    Replies: 5
    Last Post: 07-10-2011, 04:56 AM
  2. Problem with loop.
    By Squish in forum C++ Programming
    Replies: 2
    Last Post: 10-12-2010, 09:21 AM
  3. loop problem
    By me77 in forum C Programming
    Replies: 2
    Last Post: 03-21-2009, 04:40 PM
  4. Plz help with this loop problem,Thanks!
    By blue_blue in forum C Programming
    Replies: 4
    Last Post: 04-28-2008, 11:34 PM
  5. problem with loop
    By bilt in forum C++ Programming
    Replies: 4
    Last Post: 04-17-2003, 11:15 AM