c - 当我试图用 C 读取文件时,为什么 fscanf 会随机更改字符串中的字符?

标签 c scanf realloc

我正在用 C 编写一个程序,我需要在其中创建一个结构数组,将该结构数组保存到一个文件中,然后打开该文件,读取该文件,并将该文件的内容复制到一个数组中结构(这个名为“friend”的特殊结构包含三个字符串)。但是,如果数组包含三个这样的 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;

最佳答案

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

  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 的返回值,而且你'不防止缓冲区溢出。但是,看到您的输入和输出,我认为这些现在都没有直接影响到您。

关于c - 当我试图用 C 读取文件时,为什么 fscanf 会随机更改字符串中的字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19716864/

相关文章:

c - 重新分配结构数组

c - 如何让C程序播放声音文件?

c - 链表程序错误?在C中

c++ - 错误: invalid conversion on const return type

c++ - 为什么 fscanf() 从不返回 EOF?

objective-c - 不知道为什么出现 "EXC Bad Access"错误

c - 在这个简单的 C 程序中分配内存时我哪里出错了?

计算程序的系统调用并使用 strace 检查结果的有效性

c - 如何使用 scanf 函数从 ls -l 作为参数的结果中解析两个特定信息?

c - 如何在 C 中创建一个函数,允许我根据分隔符将字符串拆分为数组?