2014-06-23 69 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