C - accessing a structure array

Viewed 87

I'm trying to code my own Turing machine. My program takes two files as arguments: my initial tape the machine will have to work with, and a rule file. This rule file consists in one rule per line, and each rule is five integers: current state, symbol found, new symbol, direction for the head to go, and new state. For that, I have a function that reads my file and puts each set of five ints found in a rule structure. An array of these structures is then generated.

What I'm trying to do is to return this array in order to be able to use it later on. Here is what I have :

struct rule {
    int cur_state;
    int symbol;
    int new_symbol;
    int direction;
    int new_state;
};
typedef struct rule rule;
struct vect {
    int nb_elem;
    rule *p;
};

vect rule_generator (char * file_rule){
    int line_number = 0;
    int ligne;
    char tmp;
    rule rule_list[line_number];
    vect output_rules;
    FILE * file;
    file = fopen(file_rule, "r");

    for(tmp = getc(file); tmp != EOF; tmp = getc(file)){
        if ( tmp == '\n')
            line_number++;
    }
    output_rules.p = malloc(line_number*sizeof(rule));
    assert(output_rules.p);
    output_rules.nb_elem = line_number;
    for (ligne = 0; ligne < line_number; ligne++ ){
        fscanf(file, "%d %d %d %d %d", &rule_list[ligne].cur_state, 
&rule_list[ligne].symbol, &rule_list[ligne].new_symbol, 
&rule_list[ligne].direction, &rule_list[ligne].new_state);
    }

    fclose(file);
    return output_rules;
}
int main (int argc, char *argv[]){
    vect rule_list = rule_generator(argv[2]);
    printf("symbole : %ls \n", &rule_list.p[0].symbol);
    return 0;
}

As some of you may already have guessed, this doesn't print anything... I've been scratching my head for a while, trying to access my array. I could really use a hand here!

2 Answers

Few problems here.

  1. You are declaring array with size 0.

    int line_number = 0; rule rule_list[line_number];

    You don't need rule_list just remove it.

  2. output_rules is no where being initilized other than memory allocating.

Solution:

I would suggest you to use output_rules for fscanf.

for (ligne = 0; ligne < line_number; ligne++ ){
        fscanf(file, "%d %d %d %d %d", &output_rules.p[ligne].cur_state, 
          &output_rules.p[ligne].symbol, &output_rules.p[ligne].new_symbol, 
          &output_rules.p[ligne].direction, &output_rules.p[ligne].new_state);
    }

Also did you mean to print the value of symbol?

As you are using %ls which is used to wchar_t *.

printf("symbole : %ls \n", &rule_list.p[0].symbol);

should be

printf("symbole : %d \n", rule_list.p[0].symbol);

There's lots going on here.

The main problem seems to be that this loop:

for(tmp = getc(file); tmp != EOF; tmp = getc(file)){
    if ( tmp == '\n')
        line_number++;
}

is going right the way through the file to the end, which means there's nothing left for fscanf() to read. If you want to read the whole file through once to find out the number of lines, and then read it again to read the content, you're going to have to either a) close and reopen it, or b) use the rewind() or fseek() function to go back to the start of the file.

(To be honest, an even better solution would be to design your code so that you don't need to read the file twice over. If you end up trying this and get stuck, ask again with a new question on this site.)

In addition, you should add these lines at the beginning of your code:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

to read in the header files which define the functions you're using, and put this line after your struct vect definition to define the type:

typedef struct vect vect;

Also, please run your compiler with warnings enabled. This would have helped you find some of these problems yourself!

Related