Thread: Errors with struct and I/O

  1. #46
    Registered User
    Join Date
    Oct 2001
    Posts
    62
    Instead of the id 01, he gives me a memory adress, the same with correto
    &p.id is a memory address.

    Code:
    printf("Id: %d \n",&p.id);
    should be:

    Code:
    printf("Id: %d \n",p.id);

  2. #47
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Instead of the id 01, he gives me a memory adress, the same with correto
    Because you are telling printf() to print the address by using the ampersand.


    Jim

  3. #48
    Registered User
    Join Date
    Apr 2012
    Posts
    159
    Hi

    Thanks for your help but now:

    Perguntas na BD 1
    Id: 1
    Pergunta:
    Opcao 1: g
    Opcao 2: f
    Opcao 3: gdfgdf
    Opcao 4: teryery
    Correto: 2


    Perguntas na BD 2
    Id: 32739
    Pergunta:
    Opcao 1: ����
    Opcao 2:
    Opcao 3:
    Opcao 4:
    Correto: 0


    Perguntas na BD 3
    Id: 0
    Pergunta:
    Opcao 1: �
    Opcao 2: �
    Opcao 3: ��
    Opcao 4: ���
    Correto: 346791079


    Perguntas na BD 4
    Id: 32767
    Pergunta: ����
    Opcao 1:
    Opcao 2:
    Opcao 3:
    Opcao 4:
    Correto: 0


    Perguntas na BD 5
    Id: 9
    Pergunta:
    Opcao 1: ˯nd���X��%Ix86_64
    Opcao 2: 6_64
    Opcao 3:
    Opcao 4:
    Correto: 0


    Perguntas na BD 6
    Id: 0
    Pergunta:
    Opcao 1:
    Opcao 2:
    Opcao 3:
    Opcao 4:
    Correto: 0


    Perguntas na BD 7
    Id: 0
    Pergunta:
    Opcao 1:
    Opcao 2:
    Opcao 3:
    Opcao 4:
    Correto: 0


    Perguntas na BD 8
    Id: 0
    Pergunta:
    Opcao 1:
    Opcao 2:
    Opcao 3:
    Opcao 4:
    Correto: 0


    Perguntas na BD 9
    Id: 0
    Pergunta:
    Opcao 1:
    Opcao 2:
    Opcao 3:
    Opcao 4:
    Correto: 0


    Perguntas na BD 10
    Id: 0
    Pergunta:
    Opcao 1:
    Opcao 2:
    Opcao 3:
    Opcao 4:
    Correto: 0


    Perguntas na BD 30
    Id: 1291874163
    Pergunta: ANDATORY_PATH=/usr/share/gconf/xsession.mandatory.path
    Opcao 1: local/bin:/usr/bin:/bin:/usr/games
    Opcao 2: bin:/bin:/usr/games
    Opcao 3: ames
    Opcao 4: t_PT
    Correto: 1162297678


    I only have one question, he give 30 questions, and only the first record is right

    Perguntas na BD 1
    Id: 1
    Pergunta:
    Opcao 1: g
    Opcao 2: f
    Opcao 3: gdfgdf
    Opcao 4: teryery
    Correto: 2

    And he jump between the id question in opcao 1, you can see that "Pergunta" is empty...

    Don't get why...

  4. #49
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    //funcao para adcionar perguntas num ficheiro
    void ad_perguntas()
    {
        struct perg p;
        FILE *f= fopen("perguntas", "wb");
        if ((f == NULL))
           {
            printf("Erro na abertura do ficheiro.");
            }
            else{
    //Lê do teclado e grava no ficheiro
            printf("Introduza o ID da pergunta \n");
            scanf("%c",&p.id);
            fflush(stdin);
            if (p.id != 0)
            {
            printf("Introduza a pergunta: \n");
            fgets(p.ques,200, stdin);
            printf("Opcao 1:  \n");
            fgets(p.op1, 15, stdin);
            printf("Opcao 2:  \n");
            fgets(p.op2, 15, stdin);
            printf("Opcao 3:  \n");
            fgets(p.op3, 15, stdin);
            printf("Opcao 4:  \n");
            fgets(p.op4, 15, stdin);
            printf("Introduza numero da resposta certa \n");
            scanf("%d", &p.res);
            fwrite(&p, sizeof(struct perg), 100 , f);
      
            rewind(f); // doesn't make sense but shouldn't be a problem
            }
            }
        }
    You write 100 struct perg. 99 of them don't contain any useful data.
    Kurt

  5. #50
    Registered User
    Join Date
    Apr 2012
    Posts
    159
    Hi

    Thanks

    Now it works

    Perguntas na BD 1
    Id || Pergunta || Opcao 1|| Opcao 2|| Opcao 3|| Opcao 3 || Correto
    1 || || ben || zpor || por || and || 1

    Perguntas na BD 2
    Id || Pergunta || Opcao 1|| Opcao 2|| Opcao 3|| Opcao 3 || Correto
    2 || || gfdg || fdg || ghdfhd || tweyt || 3

    The only problem is he jump when i use the ad_perguntas function in the second question

    see:

    Introduza o ID da pergunta
    02
    Introduza a pergunta:
    Opcao 1:
    gfdg

    I can't write anything in "Introduza a pergunta" because he jump to Opcao 1.

    What's wrong there??

    Code:
     printf("Introduza o ID da pergunta \n");
            scanf("%d",&p.id);
            fflush(stdin);
            if (p.id != NULL)
            {
            printf("Introduza a pergunta: \n");
            gets(p.ques);
            printf("Opcao 1:  \n");
            gets(p.op1);

  6. #51
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
           printf("Introduza o ID da pergunta \n");
           scanf("%d",&p.id);
           // fflush(stdin); // this is undefined bhaviour
           while ((ch = getchar()) != '\n' && ch != EOF);
           if (p.id != NULL) {
               printf("Introduza a pergunta: \n");
               gets(p.ques); // never use that
               printf("Opcao 1:  \n");
               gets(p.op1);   // never use that


    Read the FAQs for explainations
    Kurt

  7. #52
    Registered User
    Join Date
    Apr 2012
    Posts
    159
    Hi

    You mean use fgets??

    regards

  8. #53
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by Gil Carvalho View Post
    Hi

    You mean use fgets??

    regards

    I prefer fgets combined with sscanf

    Example in FAQ FAQ > Validate user input - Cprogramming.com

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  9. #54
    Registered User
    Join Date
    Apr 2012
    Posts
    159
    Thanks

    Now i have a small problem.

    With this function i want to remove a record, everything is working, i put the id, he gives the record but when i choose to remove....he add another one..

    Code:
    void remov_perguntas()
    {
        char ch;
        int id_reg;
        struct perg p;
        FILE *f, *fp;
        fp=fopen("temp.dat", "rb+");
        if ((f= fopen("perguntas.dat", "rb+")) == NULL)
        {
            printf("Erro ao abrir ficheiro\n");
        }
        printf("Introduza o Id a apagar: \n");
        scanf("%d",&id_reg);
        while(fread(&p,sizeof(struct perg),1,f))
           {
             if(id_reg==p.id)
               {
    printf("Este registo tem como dados: \n %d ||    %s    ||   %s   ||   %s   ||   %s   ||   %s    ||    %d \n" ,p.id, p.ques, p.op1, p.op2, p.op3, p.op4, p.res);
    printf("Quer apagar este registo: ? (S/N)");
    scanf("%s",&ch);
    if (ch=='S'|| ch=='s')
    {
    rewind(f);
    while(fread(&p,sizeof(struct perg),1,f)==1)
    {
        if(id_reg!=p.id)
        {
            fwrite(&p, sizeof(struct perg), 0 , f);
            printf("Registo apagado :) \n");
        }
        else
        {
            printf("Este registo nao foi apagado :( \n");
        }
    }
    }
               }
           }
        fclose(f);
        fclose(fp);
        remove("perguntas.dat");
        rename("temp.dat", "perguntas.dat");
        return;
    }
    And now?? What's wrong?

  10. #55
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    This doesn't look right to me
    Code:
    if(id_reg!=p.id)
        {
            fwrite(&p, sizeof(struct perg), 0 , f); // should write 0 records
            printf("Registo apagado :) \n");
        }
    Kurt

  11. #56
    Registered User
    Join Date
    Apr 2012
    Posts
    159
    Hi

    I changed the line to 1 and

    Introduza o Id a apagar:
    2
    Este registo tem como dados:
    2 || || sdsd || dasds || ffggh || yiyui || 2
    Quer apagar este registo: ? (S/N)s
    Registo apagado

    He says the record is deleted (check the id =2)

    I call the function ver_perguntas and i have

    Id || Pergunta || Opcao 1|| Opcao 2|| Opcao 3|| Opcao 3 || Correto
    1 || || gdfh || ghfdh || fhhfd || hdfhf || 4
    Perguntas na BD 3

    Id || Pergunta || Opcao 1|| Opcao 2|| Opcao 3|| Opcao 3 || Correto
    2 || || sdsd || dasds || ffggh || yiyui || 2

    So the record wasn't deleted.

    My code is this...don't know what i miss now.
    Code:
    void remov_perguntas()
    {
        char ch;
        int id_reg;
        struct perg p;
        FILE *f, *fp;
        fp=fopen("temp.dat", "rb+");
        if ((f= fopen("perguntas.dat", "rb+")) == NULL)
        {
            printf("Erro ao abrir ficheiro\n");
        }
        printf("Introduza o Id a apagar: \n");
        scanf("%d",&id_reg);
        while(fread(&p,sizeof(struct perg),1,f))
           {
             if(id_reg==p.id)
               {
    printf("Este registo tem como dados: \n %d ||    %s    ||   %s   ||   %s   ||   %s   ||   %s    ||    %d \n" ,p.id, p.ques, p.op1, p.op2, p.op3, p.op4, p.res);
    printf("Quer apagar este registo: ? (S/N)");
    scanf("%s",&ch);
    if (ch=='S'|| ch=='s')
    {
    rewind(f);
    while(fread(&p,sizeof(struct perg),1,f)==1)
    {
        if(id_reg!=p.id)
        {
            fwrite(&p, sizeof(struct perg), 1 , f);
            printf("Registo apagado :) \n");
            return;
        }
        else
        {
            printf("Este registo nao foi apagado :( \n");
            return;
        }
        fclose(f);
        fclose(fp);
        remove("perguntas.dat");
        rename("temp.dat", "perguntas.dat");
        return;
    }
    }
    }
    }
    }

  12. #57
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    fp=fopen("temp.dat", "rb+");
    I would try "wb" as openmode. After all you want to write the file.
    Kurt

  13. #58
    Registered User
    Join Date
    Apr 2012
    Posts
    159
    Thanks for helping me
    After that change:

    4
    Introduza o Id a apagar:
    2
    Este registo tem como dados:
    2 || || sdsd || dasds || ffggh || yiyui || 2
    Quer apagar este registo: ? (S/N)
    s
    Registo apagado

    And after call the ver_perguntas function

    Id || Pergunta || Opcao 1|| Opcao 2|| Opcao 3|| Opcao 3 || Correto
    1 || || gdfh || ghfdh || fhhfd || hdfhf || 4
    Perguntas na BD 3

    Id || Pergunta || Opcao 1|| Opcao 2|| Opcao 3|| Opcao 3 || Correto
    2 || || sdsd || dasds || ffggh || yiyui || 2


    Still the same, he identify the id, ask me if i want to delete him, i choose yes, the if statement

    if(id_reg != p.id)
    {
    fwrite(&p, sizeof(struct perg), 1 , f);
    printf("Registo apagado \n");
    return;

    enter because i have the sentence "Registo apagado" but after i see there is no changes in my file..


    Regards

  14. #59
    Registered User
    Join Date
    Apr 2012
    Posts
    159
    Hi

    Strange behaviour now, i can delete records but it does more than one,

    I had 3 records, and choosed the record 2 to delete, after i had only one record (3)
    the 1º and the 2º disapear

    Anything worng in this code?
    Code:
    void remov_perguntas()
    {
        char ch;
        int id_reg, contador=0;
        struct perg p;
        FILE *f, *fp;
        fp=fopen("temp.dat", "wb");
        if ((f= fopen("perguntas.dat", "rb")) == NULL)
        {
            printf("Erro ao abrir ficheiro \n");
        }
        printf("Introduza o Id a apagar: \n");
        scanf("%d",&id_reg);
        while(fread(&p,sizeof(struct perg),1,f))
           {
             if(id_reg==p.id)
               {
    printf("Este registo tem como dados: \n  %d ||    %s    ||   %s   ||   %s   ||   %s   ||   %s    ||    %d \n" ,p.id, p.ques, p.op1, p.op2, p.op3, p.op4, p.res);
    printf("Quer apagar este registo: ? (S/N) \n");
    scanf("%s",&ch);
    fseek(f, (contador-1) *sizeof(struct perg), SEEK_SET);
    fread(&p,sizeof(struct perg),1,f);
        if(p.id== id_reg)
        {
        }
        else
        {
        fseek(f, (contador-1) *sizeof(struct perg), SEEK_SET);
        fwrite(&p,sizeof(struct perg),1,fp);
        printf("Registo apagado \n");
        }
        fclose(f);
        fclose(fp);
        remove("perguntas.dat");
        rename("temp.dat", "perguntas.dat");
        return;
               }
           }
    }

    regards

  15. #60
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Forget about all the seeks in that function.
    The calculation of the seek position gives a negative offset. That messes everything up.
    No seeking is necessary. Just write one recods after the other skip writing when the id's match.
    Kurt

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 03-06-2011, 09:12 PM
  2. struct holding data inside a linked list struct
    By icestorm in forum C Programming
    Replies: 2
    Last Post: 10-06-2009, 12:49 PM
  3. Making a (atom) class in a (struct) class makes big errors!
    By Yarin in forum Windows Programming
    Replies: 4
    Last Post: 09-11-2007, 07:18 PM
  4. Script errors - bool unrecognized and struct issues
    By ulillillia in forum Windows Programming
    Replies: 10
    Last Post: 12-18-2006, 04:44 AM
  5. Struct errors...
    By Cale in forum C Programming
    Replies: 2
    Last Post: 12-12-2002, 11:49 PM