简体   繁体   中英

Can't read line written on a file in C

I have been developing this project where every process after being forked writes his information on a file for the parent to read. I have also written a small snippet for the parent to read this file, but every time I run this code it wont work. Instead, when I manually write in the file in the following format:

  • 567 |A | B | 20
  • 568 |N | A | 2
  • 569 |Z | B | 12

I can read allright, but when I run this code:

  #include "header.h"


  struct Individui {
       pid_t pid;
       char tipo[50];
       char nome[50];
       unsigned long genoma;
  };


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

    Individuo individuo;
    srand(getpid());

    int min = 2;
    int max = atoi(argv[2]);
    int diff = max - min;
    int r;
    r = rand() % (diff + 1) + min;

    char randomletter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[rand() % 26];

    individuo.pid = getpid();
    strcpy( individuo.tipo, argv[0]);
    strcpy( individuo.nome, &randomletter);
    individuo.genoma = r;

    FILE *f = fopen("dati.txt", "a");
    if (f == NULL)
    {
        printf("Error opening file!\n");
        exit(1);
    }

    fprintf(f, "%d | %s | %s | %lu\r", individuo.pid, individuo.nome, individuo.tipo, individuo.genoma);

    fclose(f);

    return 0;
}

And then read the file with this code, it doesn't work:

int main(){
    char name[4], type[4];
    int pids[4];
    unsigned long genome[4];
    int i = 0;

    FILE * file = fopen("dati.txt", "r"); // "r" = read
    while(fscanf(file, "%d | %c | %c | %ld\n", &pids[i], &name[i], &type[i], &genome[i]) != EOF){
        i++;
    }

    printf ("%d %c %c %lu\n", pids[0], name[0], type[0], genome[0]);
    printf ("%d %c %c %lu\n", pids[1], name[1], type[1], genome[1]);
    printf ("%d %c %c %lu\n", pids[2], name[2], type[2], genome[2]);
}

From what I was able to understand, the length of the lines I write with the process code is very long, and the code to read the file doesn't support it. I'm new to C so I can't really know where I'm mistaken, and I hope somebody might help.

Your first program isn't writing the data in the format the second program expects.

The first problem is here:

strcpy( individuo.nome, &randomletter);

The strcpy function expects a pointer to a null terminated string for it's second argument. You're instead passing a pointer to a single character. As a result, the function will attempt to read memory past the location of that single variable. Reading outside of memory bounds invokes undefined behavior .

The other issue is here:

fprintf(f, "%d | %s | %s | %lu\r", 
        individuo.pid, individuo.nome, individuo.tipo, individuo.genoma);

Your second program expects a single character for the second and third elements, but you're instead writing strings for both of these. Also, \r is not a newline but a linefeed. A newline is \n .

The fix:

First change your structure to use individual characters instead of strings, since you'll only be writing characters:

  struct Individui {
       pid_t pid;
       char tipo;
       char nome;
       unsigned long genoma;
  };

Then change how you assign to those fields:

individuo.tipo = argv[1][0]; // assumes first command line argument is char to print
individuo.nome = randomletter;

Then write single characters and fix the newline:

fprintf(f, "%d | %c | %c | %lu\n", 
        individuo.pid, individuo.nome, individuo.tipo, individuo.genoma);

Bugfixes writer:

char randomletter[2];
randomletter[0] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[rand() % 26];
randomletter[1] = '\0';

strcpy( individuo.nome, randomletter);

fprintf(f, "%d | %s | %s | %lu\n",
    individuo.pid, individuo.nome, individuo.tipo, individuo.genoma);

Bugfixes reader:

void read() {
    char name[4][50], type[4][50];
    int pids[4];
    unsigned long genome[4];

    FILE * file = fopen("dati.txt", "r"); // "r" = read
    for (int i = 0; i < 4; i++) {
        if (fscanf(file, "%d | %s | %s | %lu", &pids[i], name[i], type[i], &genome[i]) != 4)
            break;

        printf ("%d %s %s %lu\n", pids[i], name[i], type[i], genome[i]);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM