2011-11-17 70 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;