0

I'm having some problems trying to write in an array position of a struct, written by me, after assigned memory with the malloc function. I have to read some data from a file.txt (format for line: int string char. Those are an id for a person, a non particular string and a char that gives the "type" of the string to read and save), line per line, and save in the struct array. Unfortunately, often I have to add a data to a previous index in the struct array, but it seems that the program doesn't let me write in a previous index of the struct array. I don't know why. Hope I was clear enough. Thank you for your help!

Here's an example of file.txt:

    6         //number of lines
    3 tPar P
    2 tPar P
    3 tArr A
    1 tPar P
    1 tArr A
    2 tArr A

Here's the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define DBG printf("Ok linea %d\n", __LINE__);


typedef enum { 
    false, 
    true 
} bool;

struct file {
    char name[15];
    int n;
    struct record *rec;
};

struct record {
    int cod;
    char tPar[10];
    char tArr[10];
};


int read(struct file *f) {

    FILE *fd;
    char str[100];
    int pCod;
    char pTime[10];
    char pChar;
    bool found;
    int i = 0;
    int j;

    fd = fopen(f->name, "r");

    if(!fd) {
        printf("Errore di apertura file.\n");
        exit(1);
    }

    fscanf(fd, "%d\n", &f->n);

    f->rec = malloc((f->n)*sizeof(struct record));

    if(f->rec == NULL) {
        printf("Errore nell'allocazione della memoria.\n");
        exit(1);
    }

    while(fgets(str, 100, fd)) {

        sscanf(str, "%d %s %c", &pCod, pTime, &pChar);
        pChar = toupper(pChar);
        found = false;

        f->rec[i].cod = 0;                  // these 4 lines are needed just
        strcpy(f->rec[i].tPar, "xxx");      // to check if it writes in the
        strcpy(f->rec[i].tArr, "xxx");      // struct array

        for(j=0; j<i; j++) {
            if((pCod == f->rec[j].cod) && (pChar == 'P')) {
                strcpy(f->rec[j].tPar, pTime);  // doesn't copy
                found = true;                   
            }
            if((pCod == f->rec[j].cod) && (pChar == 'A')) {
                strcpy(f->rec[j].tArr, pTime);  // doesn't copy
                found = true;                   
            }
        }

        if(!found) {
            f->rec[i].cod = pCod;
            if(pChar == 'P')
                strcpy(f->rec[i].tPar, pTime);
            if(pChar == 'A')
                strcpy(f->rec[i].tArr, pTime);

        }

        if(pChar == 'P')
            printf("%d %s %c\n", f->rec[i].cod, f->rec[i].tPar, pChar);
        if(pChar == 'A')
            printf("%d %s %c\n", f->rec[i].cod, f->rec[i].tArr, pChar);

        i++;

    }

    fclose(fd);

    return 0;

}


int main(int argc, char *argv[]) {

    struct file f;

    strcpy(f.name, argv[1]);

    read(&f);

    return 0;
}

Expected ouput:

3 tPar P
2 tPar P
3 tArr A
1 tPar P
1 tArr A
2 tArr A

Actual output:

3 tPar P
2 tPar P
0 xxx A
1 tPar P
0 xxx A
0 xxx A
18
  • 2
    Do not typedef bool. Instead #include <stdbool.h>! Commented Jun 15, 2015 at 23:06
  • 4
    Why do you do i++? Should you only be doing that if (!found), it seems you may run into a segmentation fault in the for(f=0 ... for-loop. It looks like i is used to track the number of records, not the number of lines you've read. Commented Jun 15, 2015 at 23:16
  • 2
    @chux, yes, now I got what you were saying. I added that commet just to be clear for you, it isn't present in the original .txt. Commented Jun 15, 2015 at 23:24
  • 1
    Still using i++; outside of if(!found) { or did you put that it in there like @JustinDanielson suggests? Code will fail until this is corrected. Commented Jun 15, 2015 at 23:34
  • 2
    OK EVERYONE! IT WORKS! Sorry, @MattMcNabb, I really thought that the malloc was the problem. Thank you, guys! I appreciate your help! Commented Jun 15, 2015 at 23:47

1 Answer 1

-3

I suspect your enumerated values for bool are not compiled as 0 and 1, so that your test

if(!found) {

does not work as it appears. (I can't really test my theory right now, though).

Sign up to request clarification or add additional context in comments.

3 Comments

The problem isn't in that particular if, I checked and my bool works fine.
enums are defined that the first one is 0 and subsequent ones are 1 greater than the previous (unless specific value assigned)
@Matt, Doh! Yes, you are quite right. I went and looked it up when I couldn't recall if it started at 1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.