簡體   English   中英

當我嘗試在C中讀取文件時,為什么fscanf隨機更改字符串中的字符?

[英]Why does fscanf randomly change characters in my strings when I am trying to read a file in C?

我正在用C語言編寫一個程序,其中需要創建一個結構數組,將該結構數組保存到文件中,然后打開該文件,讀取該文件並將該文件的內容復制到一個結構數組中(這是稱為“朋友”的特定結構包含三個字符串)。 但是,如果數組包含三個這樣的朋友:

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

其他信息:當我繼續在同一個文件上調用此函數時,它將最終產生正確的字符串,這使我相信我的save函數是正確的。 這與內存分配有關嗎?

這是我的結構代碼:

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的返回值以及沒有防止緩沖區溢出的事實。 但是,看到您的輸入和輸出,我認為這些都不會對您造成直接影響。

讀取文件名時,scanf函數上有錯誤。

scanf("%s", &address);

您應該刪除&。

但是,這可能不是造成問題的原因,因為它在大多數系統中都有效。 基本上,這里的問題是scanf("%s", &string)衰減到指向char [256]的指針,而scanf則期望使用char *類型。 之所以有效,是因為指針&string&string[0]以相同的方式表示。 但是,您的代碼取決於標准C不能保證的事情,它在不同的系統中可能具有不同的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM