2011-11-17 54 views
15

我有一個緩衝區,我通過串口接收。當我收到一個特定的字符時,我知道完整的一行已經到達,我想用printf方法打印它。但是,每一行都有不同的長度值,當我只是去:printf緩衝區中char的長度通過C

printf("%s", buffer); 

我打印的行加上屬於前行額外的字符(如果它比當前的更長)。

我看過here,至少在C++中,給出一個%s可以告訴多少字符,但它沒有例子,我不知道如何在C中做任何幫助。 ?

編輯:完美。所以,我有三種解決方案: - 由字符打印字符用for循環 - 使用終止字符 - 或使用*

問題是:哪一個是更快?因爲我正在使用微芯片PIC,所以我希望它儘可能快地發生。

+2

當您收到的* 「某些字符」 *並將它添加到'buffer',追加空字符('\ 0')爲好。這個「告訴」'sprintf()'何時停止打印字符。 –

回答

22

您擁有的字符串不是空終止的,所以printf(和任何其他C字符串函數)無法確定其長度,因此它將繼續編寫它在那裏找到的字符,直到它碰巧遇到一個空字符。

解決你的問題,你可以:

  • 使用fwritestdout

    fwrite(buffer, buffer_length, 1, stdout); 
    

    這工作,因爲fwrite是沒有想到的印刷只是字符串,但任何類型的數據,所以它不查找終止空字符,但接受要寫入的數據長度作爲參數;

  • 印刷之前手動空終止您的緩衝區:

    buffer[buffer_length]=0; 
    printf("%s", buffer); /* or, slightly more efficient: fputs(buffer, stdout); */ 
    

    這可能是一個更好的主意,如果你有超過buffer做其他任何字符串處理,現在將是空值終止並通過這樣便於管理正常的C字符串處理函數。

+0

我很驚訝,這個SO問題的重複的答案不包括這種方法,但只建議'for'循環... – Alex

1

一旦你確定了線的末端,則必須將其發送給printf前追加'\0'字符到緩衝區的末尾。

+0

誰downvoted想解釋爲什麼,以便我可以改善我的答案? –

+0

除了如何糾正之外,你應該說OP的錯誤。 – Alex

37

您可以您的終止符後添加一個空字符,而您的printf將工作,或者你可以在你的printf語句添加'.*'並提供長度

printf("%.*s",len,buf); 

在C++中,可能會使用的std :: string和性病::法院,而不是像這樣:

std::cout << std::string(buf,len); 

如果你想要的速度是最快的,並沒有格式 - 然後用

fwrite(buf,1,len,stdout); 
+0

不錯,不知道這 – Ben

+0

完美。所以我有三種解決方案:使用for循環打印字符char,使用終止字符或使用。*問題是:哪一個更快?因爲我在微芯片PIC上工作,我希望它快速發生 –

+0

@RomanRdgz:我的猜測:'fwrite'或空終止+'fputs'應該是最快的,接着是空終止+'printf'(可能會更慢因爲它可能不得不解析格式化字符串,除非編譯器非常聰明),然後''printf'用'。*'(當然需要解析格式化字符串)並且最後用char打印char(可能是最慢的,因爲所有的函數調用 - 但是可以內聯)。 –

3

您可以收到的最後一個字符後把一個NUL(爲0x0)在緩衝區中。

buffer[i] = 0;