Thread: Read error

  1. #1
    Registered User catasturslykid's Avatar
    Join Date
    Jul 2013
    Location
    Barcelona, Spain
    Posts
    72

    Read error

    Hi guys, I've got another question!

    I'm a bit lost with pointers and I've got a problem while I'm trying to read a file.

    When I execute the program and I want to print the text readed, appears something like that: "'m'm"

    And, of course, that's not a word from the text.

    Here is the code:

    Code:
     void carregaClasses(FILE *g, Classe *classe, int *nClas){
    
     int nAtac,nDefensa,nVida, i;
    char strNom[100], kk;
    
        fscanf(g,"%d",nClas); 
        fscanf(g,"%c",&kk); //\n out
        classe = (Classe*)malloc(sizeof(Classe)* *nClas);
        if(classe == NULL){
            printf("Error!\n");
            free(classe);
        }
        else{
            for(i = 0; i< *nClas; i++){
                fscanf(g,"%s", strNom);
                fscanf(g,"%c",&kk); //Space out
                fscanf(g,"%d",&nAtac);
                fscanf(g,"%c", &kk); //Space out
                fscanf(g,"%d",&nDefensa);
                fscanf(g,"%c",&kk); //Space out
                fscanf(g,"%d",&nVida);
                strcpy(strNom, classe[i].strNom);
                classe[i].nAtac = nAtac;
                classe[i].nDefensa = nDefensa;
                classe[i].nVida = nVida;
                fscanf(g,"%c",&kk); // \n out
             }
        }
    }
    The file is a file named "fitxer_classe.txt" and the structure is:

    Code:
    7
    Guerrer 20 25 100
    Mag 35 10 100
    Guilopo 30 15 100
    Sacerdot 20 15 120
    GuerrerDelEscutGran 15 30 100
    Ninja 45 0 100
    Sogra 100 100 1000
    Where the first number means the number of lines in the file.



    Can you help me please?

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Since fscanf automatically skips spaces before reading a string or number, you don't need lines like these:
    Code:
    fscanf(g,"%c",&kk); //\n out
    fscanf(g,"%c",&kk); //Space out
    And your strcpy has the args backwards (this is causing the error) :
    Code:
    strcpy(strNom, classe[i].strNom);

  3. #3
    Registered User catasturslykid's Avatar
    Join Date
    Jul 2013
    Location
    Barcelona, Spain
    Posts
    72
    Ok. I've just done that changes but the problem stills.

    Could it be a problem with the pointers and arrays?

  4. #4
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You'll have to repost the code so I can see if you made the changes correctly.

    EDIT: Oh, wait a second! You need to pass a double pointer to classe.

    EDIT2: Or return the pointer. (That's what I'd probably do.)
    Last edited by oogabooga; 07-29-2013 at 11:43 AM.

  5. #5
    Registered User catasturslykid's Avatar
    Join Date
    Jul 2013
    Location
    Barcelona, Spain
    Posts
    72
    Quote Originally Posted by oogabooga View Post
    You'll have to repost the code so I can see if you made the changes correctly.

    EDIT: Oh, wait a second! You need to pass a double pointer to classe.

    EDIT2: Or return the pointer. (That's what I'd probably do.)

    How can I return the pointer? As I said, I'm a bit lost with pointers.

    Or, in fact, how can I pass a double pointer to classe?

    Thank you for your time

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,194
    One problem is your allocation is lost when the function returns.

    Code:
    void carregaClasses(FILE *g, Classe *classe, int *nClas){
     
     int nAtac,nDefensa,nVida, i;
    char strNom[100], kk;
     
        fscanf(g,"%d",nClas);
        fscanf(g,"%c",&kk); //\n out
        classe = (Classe*)malloc(sizeof(Classe)* *nClas);
    Several points
    1. There is no need to cast malloc in a C program - see the FAQ.
    2. In the same way that nClas is a pointer to an int, so you can pass the result of fscanf back to the caller, then your classe needs to be a POINTER to a pointer, if the result of malloc is to be known to the caller as well.

    So
    void carregaClasses(FILE *g, Classe **classe, int *nClas)

    Code:
        if(classe == NULL){
            printf("Error!\n");
            free(classe);
    If malloc failed, there is nothing to free. It's not harmful to call free with a NULL pointer, it's just a waste of effort.

    > classe[i].nAtac = nAtac;
    When you've turned classe into a ** variable, you need to do this to index the array properly.
    Code:
                (*classe)[i].nAtac = nAtac;
    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.

  7. #7
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    A double pointer just means that you pass the address of the pointer variable (which of course itself is meant to hold an address). So it might look something like this:
    Code:
    void carregaClasses(FILE *g, Classe **classe, int *nClas){
        // ...
        *classe = malloc(sizeof(Classse) * *nClas);
        // ...
    }
    //...
       Classe *classe;
       int nClas;
       carregaClasses(g, &classe, &nClas)
    Returning a pointer, which is perhaps somewhat cleaner, looks like this:
    Code:
    Classe* carregaClasses(FILE *g, int *nClas){
        Classe *classe;
        // ...
        classe = malloc(sizeof(Classse) * *nClas);
        // ...
        return classe;
    }
    //...
       Classe *classe;
       int nClas;
       classe = carregaClasses(g, &nClas)

  8. #8
    Registered User catasturslykid's Avatar
    Join Date
    Jul 2013
    Location
    Barcelona, Spain
    Posts
    72
    Ok. I've just done what you said but another problem appears. I was trying to find it for a while but I didn't find it.


    Here is the new code (using the duoble pointer):

    Code:
    void carregaClasses(FILE *g, Classe **classe, int *nClas){
    
     int nAtac,nDefensa,nVida, i;
    char strNom[100];
    
        fscanf(g,"%d",nClas); 
        classe = (Classe*)malloc(sizeof(Classe)* *nClas); //Here appears an error (should it be: *classe = (Classe*)malloc(sizeof(Classe)* *nClas) ?
        if(classe == NULL){
            printf("Error!\n");
            free(classe);
        }
        else{
            for(i = 0; i< *nClas; i++){
                fscanf(g,"%s", strNom);
                fscanf(g,"%d",&nAtac);
                fscanf(g,"%d",&nDefensa);
                fscanf(g,"%d",&nVida);
                strcpy(*(classe)[i].strNom,strNom); //Petition error 
                *(classe)[i].nAtac = nAtac; //Petition error 
                *(classe)[i].nDefensa = nDefensa; //Petition error 
                *(classe)[i].nVida = nVida; //Petition error 
             }
        }
    }
     
    
    







  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,907
    It would help if you provided the #include files you need and the definition of Classe so we can get past the simple errors and focus more on the problem you're having. Also, providing the exact error message (copy-paste it) would be helpful. I added the following to the top, which may not be exact, but should take care of that:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct {
      char strNom[64];
      int nAtac;
      int nDefensa;
      int nVida;
    } Classe;
    When compiling, I got the following errors:
    Code:
    $ make foo
    gcc -Wall -ggdb3 -std=c99 -o foo foo.c -lm -lpthread
    foo.c: In function ‘carregaClasses’:
    foo.c:18:10: warning: assignment from incompatible pointer type [enabled by default]
    foo.c:29:26: error: request for member ‘strNom’ in something not a structure or union
    foo.c:30:19: error: request for member ‘nAtac’ in something not a structure or union
    foo.c:31:19: error: request for member ‘nDefensa’ in something not a structure or union
    foo.c:32:19: error: request for member ‘nVida’ in something not a structure or union
    make: *** [foo] Error 1
    Reread Salem's post #6 carefully. You're casting malloc, and doing it incorrectly. Though your guess is correct, it should be *classe = ... . classe is a pointer to the place you want to store the result of malloc, so you must dereference it to store the address there. Note, a better version would be:
    Code:
    *classe = malloc(sizeof(**classe) * *nClas);
    Note that I use the variable name in the sizeof expression, with an extra * in front of it. That basically says "use the size of the object where I will store the result of malloc". That way, if you change the type of classe for any reason, you need only change the declaration, the malloc statement will always allocate the right size for the object(s) you are allocating. Less work for you to change, and fewer bugs when you do. It's a win-win. Remember, the general form is put the thing on the left of the equals inside your sizeof expression with one extra * in front:
    Code:
    ptr_to_thing = malloc(sizeof(*ptr_to_thing) * num_things);
    If ptr_to_thing has one * in front, you need two * in the sizeof.

    Also, in post #6, Salem showed you how to access the array you malloc. Take careful note of where you put the parentheses, and where Salem put them.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,194
    > *(classe)[i].nAtac = nAtac; //Petition error
    Study my post again, and note where the * is in relation to the ( )
    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.

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,793
    To not misuse double pointer - use temp var of type Classe * just as you used it before and at the end of function assign it value to parameter

    Code:
    void carregaClasses(FILE *g, Classe **classe, int *nClas){
    Classe * cl = NULL;
    
    cl = malloc(...)
    ...
    
    cl[i].nAtac = ...
    
    
    /* if all is well */
    *classe = cl;
    
    return 0; /* it is always good idea to let the caller know if you succeed, return negative number on failure */
    }
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    David J. Wheeler

  12. #12
    Registered User catasturslykid's Avatar
    Join Date
    Jul 2013
    Location
    Barcelona, Spain
    Posts
    72
    Thank you guys! Thank you for your time and your explanations!

    You resolved my problem! You are awesome!

    I just check your post again, Salem, and now it works! Thank you guys!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Invalid read error
    By Giorgos in forum C Programming
    Replies: 14
    Last Post: 05-03-2013, 01:38 PM
  2. CSV read error
    By pcrana in forum C Programming
    Replies: 8
    Last Post: 01-10-2012, 11:57 AM
  3. why i get read accsess error?
    By transgalactic2 in forum C Programming
    Replies: 8
    Last Post: 04-09-2009, 04:53 PM
  4. SDL read error
    By MadCow257 in forum C++ Programming
    Replies: 3
    Last Post: 12-27-2005, 04:10 PM
  5. Error!- Cannot open .rc! READ!!
    By oobootsy1 in forum C++ Programming
    Replies: 3
    Last Post: 07-30-2003, 05:06 AM