2014-06-23 99 views
-1

我必須將程序從UNIX遷移到Windows。該程序是關於從串口獲取數據的。在正在接收它原來的UNIX機器,它的內容:fgets()讀取什麼?

char my_buffer_a[200]; 

memset(my_buffer_a, '\0', sizeof(my_buffer_a)); 

if (fgets(my_buffer_a, sizeof(my_buffer_a), file_p)) 
{ 
    n = sscanf("%d\t%d\t...%d\n0x0A", 
       my_record.field1, my_record.field2, ...) 
    .... 
} 

我知道,與fgets()將讀取直到EOF或換行符。這意味着在my_buffer_a中,我期待最後的'\ n'。但令我驚奇的是,還有0x0A! (這是否意味着兩個換行符?)這是怎麼回事?

我擔心的另一件事是Unix和Windows中換行符的定義。它們在Unix和Windows中都不一樣。我的意思是我轉換後,當我做sscanf,我將不得不做sscanf("%d\t%d\t...%d\r\n(或sscanf(%d\t%d\t...%d\r0x0D\n0x0A,同時保持這種奇怪的邏輯)?

+2

你真的不知道'0x0a'是''\ n''的ASCII編碼('0x0d'是'\ r''的編碼)嗎?而Windows使用'\ r \ n'作爲文本文件行結尾,而Unix只使用'\ n''?你真的可以不知道文字基礎? – DevSolar

+0

是的我已經檢查過0x0A和0x0D是什麼意思。正如我在代碼中所述(由其他人寫的),'sscanf'以'\ n0X0A'結尾。這意味着在原來的UNIX程序中有兩個***換行符。這是否意味着fgets()需要兩個換行符? – user3454439

+1

以十六進制打印輸入字符串,並檢查您的假設。經驗法則:標準功能不會中斷。標準功能的文檔沒有被破壞。 – DevSolar

回答

3

scanf格式字符串中的換行符不會專門在輸入中查找換行符 - 它只是跳過空格(任何空格)。標籤字符相同。另外,大部分 scanf格式說明符(除%c%[之外的所有內容)都跳過空格。所以一般:

  • 你應該永遠使用\t\r\n在格式字符串(除%[內.. ]),因爲它只會混淆人。使用一個空格,而不是相同的東西

  • 你應該避免在格式化字符串中使用多餘的空格,因爲他們什麼都不會,只會混淆人。

因此,與上述,您sscanf呼叫將變爲:

sscanf("%d%d ...%d 0x0A", 

這就很清楚,這讀取兩個數字,隨後三個時期,接着又數,最後是字符串0x0A(4字符)。這6件事中的任何一件之間可能有空白(或沒有),它會被忽略。

就Windows和Unix而言,在Windows下,在行尾會有額外的回車符(\r)。但這些只是空格,所以會像其他空格一樣跳過scanf。所以你可以忽略它們。

+0

最後有人可以指出我有困惑。感謝您「意識到」這個問題。 – user3454439

0

沒有什麼是「正在進行」。請read the manual page,其中明確指出:

如果讀取換行符,它將存儲到緩衝區中。

行號編碼的區別應該不重要,它們都是空白,因此在很多情況下都會跳過sscanf()

+0

但是有兩個換行符! 'sscanf()'以'\ n0x0A'結尾。我希望只有一個換行符! – user3454439

+1

@ user3454439到底你怎麼知道有兩個換行符?你的'sscanf()'推理線有兩個錯誤:1)'0x0A'不代表'scanf'格式字符串中的換行符,它表示一個由4個ASCII字符組成的序列'0x0A'。要指定換行符,您可以使用'\ x0A',或者簡單地使用'\ n'。 2)'sscanf()'處理儘可能多的格式字符串,並返回處理的項目數量。如果字符串不是真的以'0x0A'結尾,'sscanf'不會在意,它會返回成功轉換項目的數量。 – user4815162342

+0

@ user4815162342:謝謝。您的評論是有幫助的。 – user3454439

0

保存在窗口中的文件將在每個文件的結尾處\ r \ n。 在linux中,文件的結尾只有\ n。

+0

'sizeof(my_buffer_a)'實際上是200個字節。 – user4815162342

+0

對不起,這是一個錯字 – Vishwamithra