簡體   English   中英

C:在二進制文件中讀寫字符串

[英]C: Writing and Reading a string to and from a binary file

我想將字符串以及許多其他數據存儲在二進制文件中,即時消息使用下面的代碼(當我將其真正用於字符串時,將被malloc分配)我可以寫入文件。 Ive在十六進制編輯器中查看了它。 我不確定我是否正確地寫了空終止符(或者如果我需要)。 當我讀回時,我得到與存儲的相同的字符串長度,但不是字符串。 我究竟做錯了什么?

FILE *fp = fopen("mybinfile.ttt", "wb");

char drumCString[6] = "Hello\0";
printf("%s\n", drumCString);    
//the string length + 1 for the null terminator
unsigned short sizeOfString = strlen(drumCString) + 1;
fwrite(&sizeOfString, sizeof(unsigned short), 1, fp);

//write the string
fwrite(drumCString, sizeof(char), sizeOfString, fp);

fclose(fp);

fp = fopen("mybinfile.ttt", "rb");  

unsigned short stringLength = 0;
fread(&stringLength, sizeof(unsigned short), 1, fp);

char *drumReadString = malloc(sizeof(char) * stringLength);
int count = fread(&drumReadString, sizeof(char), stringLength, fp);

//CRASH POINT
printf("%s\n", drumReadString);

fclose(fp); 

您在閱讀時做錯了。 您將&放在了指針變量中,這就是為什么它會導致分段錯誤的原因。

我刪除了它的工作原理,並正確返回Hello。

int count = fread(drumReadString, sizeof(char), stringLength, fp);

我看到了幾個問題,一些問題,一些風格。

  • 您應該真正測試mallocfreadfwrite的返回值,因為分配可能會失敗,並且不會讀取或寫入任何數據。
  • sizeof(char) 始終為 1,無需乘以它。
  • 字符數組"Hello\\0"實際上是7個字節長。 您不需要添加多余的空終止符。
  • 我更喜歡成語char x[] = "xxx"; 而不是指定一定的長度(除非您當然希望數組長於字符串)。
  • 當您fread(&drumReadString ... ,實際上是在覆蓋指針 ,而不是它指向的內存。這是導致崩潰的原因。應該是fread(drumReadString ...

一些提示:

1個

在任何雙引號字符串中都隱含一個終止符\\0 ,通過在末尾添加一個附加字符,您最終得到兩個。 以下兩個初始化是相同的:

char str1[6] = "Hello\0";
char str2[6] = { 'H', 'e', 'l', 'l', 'o', '\0', '\0'};

所以

char drumReadString[] = "Hello";

這樣就足夠了,並且像這樣初始化數組時,指定數組的大小是可選的,編譯器將找出所需的大小(6個字節)。

2

編寫字符串時,您可能還一口氣寫了所有字符(而不是一字符一倍地寫sizeOfString次):

fwrite(drumCString, sizeOfString, 1, fp);

3

即使在普通的台式機PC場景中不太常見,malloc仍可以返回NULL,並且您將受益於開發一個始終檢查結果的習慣,因為在嵌入式環境中,獲得NULL的可能性不大。

char *drumReadString = malloc(sizeof(char) * stringLength);
if (drumReadString == NULL) {
        fprintf(stderr, "drumReadString allocation failed\n");
        return;
}

您不必編寫終止的NUL,也不必編寫,但隨后必須在閱讀時考慮添加它。 即malloc stringLength + 1個字符,讀取stringLength字符,並在已讀取內容的末尾添加\\0

現在是通常的警告:如果您按照此處的方式編寫二進制文件,則會有許多未聲明的假設,這些假設使您的格式難以移植,有時甚至移植到同一編譯器的另一個版本中-我已經在其中看到了默認對齊方式編譯器版本之間的結構更改。

在paxdiablo和AProgrammer中添加了更多內容-如果將來要使用malloc,請從頭開始。 這是更好的形式,這意味着切換時無需調試。

另外,我沒有完全看到unsigned short的用法,如果您打算編寫二進制文件,請考慮到unsigned char類型的大小通常為byte,因此非常方便。

您只需在fread函數中刪除&drumReadString。您只需在ganesh中使用該函數中的drumReadString。因為,drumReadString是一個數組。Array與直接指向內存位置的指針相似。

暫無
暫無

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

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