无法读取用C写入文件的行

时间:2017-12-05 14:23:38

标签: c file writing

我一直在开发这个项目,其中分叉后的每个进程都将他的信息写在一个文件上供父级阅读。 我还为父母写了一个小片段来读取这个文件,但每次运行这段代码都不行。 相反,当我以下列格式手动写入文件时:

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

我可以读得很好,但是当我运行这段代码时:

  #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;
}

然后使用此代码读取文件,它不起作用:

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]);
}

根据我的理解,我使用流程代码编写的行的长度非常长,而且读取文件的代码并不支持它。我是C的新手,所以我无法确切地知道我错在哪里,我希望有人可以提供帮助。

2 个答案:

答案 0 :(得分:2)

您的第一个程序不是以第二个程序期望的格式写入数据。

第一个问题在这里:

strcpy( individuo.nome, &randomletter);

strcpy函数需要一个指向空终止字符串的指针,用于它的第二个参数。您反而将指针传递给单个字符。因此,该函数将尝试读取超过该单个变量位置的内存。在内存边界之外读取会调用undefined behavior

另一个问题是:

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

你的第二个程序需要第二个和第三个元素的单个字符,但是你要为这两个元素编写字符串。此外,\r不是换行符,而是换行符。换行符为\n

修复:

首先更改您的结构以使用单个字符而不是字符串,因为您只会写字符:

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

然后更改您分配给这些字段的方式:

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

然后编写单个字符并修复换行符:

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

答案 1 :(得分:2)

错误修正作者:

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);

错误修正读者:

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]);
    }
}