c fgets检索整个数组?

时间:2014-02-07 13:17:20

标签: c file fgets strlen

我有一个名为phobebook的文件,我在其中检索我拥有的联系人数量(这里的int是在变量cc上分配的),然后保存了名称,地址等。 问题是当我显示信息时,细节在那里,但它们用新的行分开。我试图把\ 0但它似乎不起作用。

typedef struct myphonebook{
  char name[31];
  char address[101];
  char cellphone[11];
  char email[21];
} Myphonebooktype;

FILE*db;

db = fopen("db.txt", "r");

fscanf(db, "%d" , &cc);

pb = (Myphonebooktype*)malloc(cc*sizeof(Myphonebooktype));
addcounter = cc;

for(i = 0; i<cc ; i++){
  size_t lenn = strlen(pb[i].name);
  if (pb[i].name[lenn - 1] == '\n') {
    pb[i].name[lenn - 1] = '\0';
  }
  fgets(pb[i].name, sizeof(pb[i].name), db);

  size_t lena = strlen(pb[i].address);
  if (pb[i].address[lena - 1] == '\n') {
    pb[i].address[lena - 1] = '\0';
  }
  fgets(pb[i].address, sizeof(pb[i].address), db);

  size_t lenc = strlen(pb[i].cellphone);
  if (pb[i].cellphone[lenc - 1] == '\n') {
    pb[i].cellphone[lenc - 1] = '\0';
  }
  fgets(pb[i].cellphone, sizeof(pb[i].cellphone), db);

  size_t lene = strlen(pb[i].email);
  if (pb[i].email[lene - 1] == '\n') {
    pb[i].email[lene - 1] = '\0';
  }
  fgets(pb[i].email, sizeof(pb[i].email), db);
}

2 个答案:

答案 0 :(得分:3)

在初始化之前,您无法在新分配的Myphonebooktype 数组中引用数据。您调用strlen()都会生成未定义的行为,因为结构成员尚未初始化。

另外,don't cast the return value of malloc() in C

答案 1 :(得分:0)

正如@unwind所说,代码在写入之前引用了未初始化的数据

  size_t lenn = strlen(pb[i].name);  // pb[i].name contents are not defined yet.
  ...
  fgets(pb[i].name, sizeof(pb[i].name), db);

建议创建一个处理行读数的函数。

void ReadLine(FILE *db, char *dest, size_t size) {
  char buffer[size+2];
  dest[0] = '\0';
  if (fgets(buffer, sizeof buffer, db) != NULL) {
    size_t len = strlen(buffer);
    // Get rid of potential \n
    if (len > 0 && buffer[len-1] == '\n') buffer[--len] = '\0';
    strncpy(dest, buffer, size);
  }
} 


for(i = 0; i<cc ; i++) {
  ReadLine(db, pb[i].name, sizeof pb[i].name);
  ReadLine(db, pb[i].address, sizeof pb[i].address);
  ReadLine(db, pb[i].cellphone, sizeof pb[i].cellphone);
  ReadLine(db, pb[i].email, sizeof pb[i].email);
}

可以对ReadLine()进行添加以在NULL读取时返回EOF,由@MadHatter引发过长的行或\r关注。它只是一个功能,因此更容易维护和增强代码。