Blodorn
Blodorn

Reputation: 73

Why my variable changes its value when I am not changing it? C

I have to read some configuration on a file to do a project from college. In my read function I use a struct to store the configuration but, I don't know why, one of the variables changes it's value when reading the next parameter.

struct client_config {
    char name[20]; // en teoria son 6 + '\0'
    char MAC[12];
    char server[20];
    int UDPport;
};

void read_software_config_file(struct client_config *config) {
    FILE * conf;
    conf = fopen(software_config_file, "r");
    if (conf == NULL) {
        fprintf(stderr, "Error obrir arxiu");
        exit(-1);
    }
    char word[1024];
    int i = 0;

    fscanf(conf, "%s", word);
    // No es la millor manera de fer-ho...
    // pero ja que suposem que el fitxer es correcte
    fscanf(conf, "%s", word);
    // Ens saltem les comprovacions
    strcpy(config->name, word);

    fscanf(conf, "%s", word);
    fscanf(conf, "%s", word);
    strcpy(config->MAC, word);
    printf("%s this is config->mac after first read \n", config->MAC);

    fscanf(conf, "%s", word);
    fscanf(conf, "%s", word);
    strcpy(config->server, word);
    printf("%s this is config->mac after next read \n", config->MAC);

    fscanf(conf, "%s", word);
    fscanf(conf, "%s", word);
    config->UDPport = atoi(word);
    fclose(conf);
}

OUTPUT:

89F107457A36 this is config->mac after first read (this is correct)

89F107457A36localhost this is config->mac after next read (this is not correct)

The file i'm reading is this:

Nom SW-01
MAC 89F107457A36
Server localhost
Server-port 2019

Upvotes: 1

Views: 676

Answers (4)

Horacio Goetendia
Horacio Goetendia

Reputation: 203

  • Check the struct client_config members size, do not forget to consider the string null terminator "\0".

  • Do not forget to initialize the struct client_config with zeros before.

Upvotes: 0

klutt
klutt

Reputation: 31306

The problem is that the MAC field does not have room for the trailing \0 character. All strings in C needs to be one character longer than the actual data.

To make the reading more secure, I'd recommend using a max length for fscanf. Like this:

fscanf(conf, "%12s", word); 

Or even better, use fgets. It makes it easy to use a variable or constant for max length.

fgets(word, MAXLENGTH, conf);

Upvotes: 2

Bodo
Bodo

Reputation: 9855

You don't have space for the terminating '\0' in the MAC field.

When you first copy to the MAC field, the printf finds the terminating '\0' in the server field. After copying to server, the characters in server follow immediately after the characters in MAC without a terminating '\0' in between.

You need at least

struct client_config{
    char name[20]; //en teoria son 6 + '\0'
    char MAC[13]; // 12 characters + '\0'
    char server[20];
    int UDPport;
};

You should also check that strcpy does not copy more than the available memory for the structure fields. Maybe use strncpy instead of strcpy, but make sure the result is terminated with '\0'. (Read the documentation of strncpy.)

Upvotes: 2

bbu
bbu

Reputation: 782

It appears like your MAC field has exactly 12 chars and no place for the trailing 0 char so that the following server is directly appended during print.

Upvotes: 1

Related Questions