1

我正在用 C 语言编写一个程序,在该程序中我需要创建一个结构数组,将该结构数组保存到一个文件中,然后打开该文件,读取该文件,并将该文件的内容复制到一个结构数组中(这名为“friend”的特定结构包含三个字符串)。但是,如果数组包含三个这样的朋友:

John Doe 234-1230 (string, string, string) <br>
Kool Kat 343-3413<br>
Suzie Q 234-1234<br>

一旦我将此数组保存到一个文件并使用下面的打开函数打开它,我就会得到类似的东西:

Joán Doe 234-2132<br>
Kool Kat 343-3413<br>
Suzie Q 234-1234<br>

或者

John Doe 234-2132<br>
Kool Kat 343-3413<br>
Suz Q 234-1234<br>

其中一个字符串(几乎总是结构中的第一个字符串)与一个或多个随机字符几乎完全相同。谁能告诉我是什么导致了这个错误?

void open(friend* book, int* size){
   FILE *pRead;
   char address[100];
   char answer = 'a';
   printf("\nWARNING: Any unsaved data in the current phonebook will be lost!");
   printf("\nType the file-name you would like to open(press '1' for the default location):");
   scanf("%s", &address);

   if(strcmp(address, "1") == 0){
      strcpy(address, "default.dat");
   }

   pRead = fopen(address, "r");
   if(pRead == NULL){
      printf("\nFile not opened\n");
   }else{
      int counter = 0;
      while(!feof(pRead)){
         fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
         counter++;
         realloc(book, sizeof(friend) * counter);
      }
      *size = counter;
      fclose(pRead);
      printf("\n%s has been loaded into the program!", address);
   }
}

其他信息:当我在同一个文件上继续调用这个函数时,它最终会产生正确的字符串,这让我相信我的保存函数是正确的。这与内存分配有关吗?

这是我的结构代码:

typedef struct Contact{ //creates a struct that holds three strings (first name, last name, phone number) (can be referred to as either Contact or friend
   char pFName[20]; //first name of friend
   char pLName[20]; //last name of contact
   char pNumber[12]; //phone number of contact
}friend;
4

2 回答 2

2

我在这里看到一个明确的问题:

  while(!feof(pRead)){
     fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
     counter++;
     realloc(book, sizeof(friend) * counter);
  }

你总是读入你不拥有的内存,然后再请求realloc。此外,您忽略来自realloc. 即使您假设它永远不会为 NULL,它仍然可以重新定位您的数据。这样做会更安全:

  while(!feof(pRead)){
     book = realloc(book, sizeof(friend) * (counter+1));
     fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
     counter++;
  }

现在,接受book可以更改的情况,您需要将其作为双指针传递,或者让您的函数返回它。

这里还有其他一些事情你应该避免,例如feof测试、你没有检查 的返回值fscanf以及你没有防止缓冲区溢出的事实。但是,看到您的输入和输出,我认为现在这些都不会直接影响您。

于 2013-10-31T21:36:24.820 回答
0

读取文件名时scanf函数出错。

scanf("%s", &address);

你应该删除 &。

但是,这可能不是您的问题的原因,因为它适用于大多数系统。基本上这里的问题是scanf("%s", &string)衰减到一个指向字符的指针[256],而 scanf 期待一个char *类型。它之所以有效,是因为指针&string&string[0]以相同的方式表示。但是,您的代码取决于标准 C 不能保证的东西,它可能在不同的系统中具有不同的行为。

于 2013-10-31T21:27:22.573 回答