[英]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.