我在C中编写了自己的CSV读取器/写入器,用于将记录存储在ODBC数据库的字符列中。不幸的是,我发现很多边缘情况都超过了我的实现,我得出结论我的问题是我没有严格定义CSV的规则。我读过RFC4180,但似乎不完整,并没有解决歧义。
例如,应该将“”视为空令牌还是双引号?报价是从外到内还是从左到右匹配?如何使用具有无法匹配的单引号的输入字符串?当我有嵌套的标记时,真正的混乱就开始了,它使转义的引用字符加倍。
我真正需要的是一个明确的CSV标准,我可以在代码中实现。每当我觉得我已经钉好每一个角落的情况下,我找到了另一个。我确信这个问题已经被我的优秀思想多次仔细考虑并解决了,有没有人写过我可以在代码中实现的严格的CSV定义?我意识到C不是这里理想的语言,但我现阶段没有关于编译器的选择;我也不能使用第三方库(除非它与C-90编译)。 Boost不是一个选项,因为我的编译器不支持C ++。我已经考虑过丢弃用于XML的CSV,但是在256字符数据库记录中存储一些令牌似乎有些过分。有人制定了明确的CSV规范吗?
答案 0 :(得分:1)
没有标准(参见维基百科的文章,特别是http://en.wikipedia.org/wiki/Comma-separated_values#Lack_of_a_standard),所以为了使用CSV,你需要遵循一般原则,即保守你所接受的内容和自由。特别是:
答案 1 :(得分:0)
答案 2 :(得分:0)
根据RFC 4180,应该从左到右解析字段以正确解释双引号。在某些情况下,""
是一个转义双引号(在引用字段内),否则它是一个空字符串或两个双引号(当在非空字段值内时)。
例如,考虑一个包含4条记录(1列)的文件:
"field""value" CRLF
"" CRLF
field""value CRLF
"field value" extra CRLF
"field""value"
- 应该被理解为field"value
""
- 应该被理解为空字符串field""value
- 应该被理解为field""value
"field value" extra
- 可以被视为field value extra
,或者您可以拒绝记录4实际上是一个无效字段,因此您可以接受或拒绝它。
当您开始阅读字段时,您需要检查读取的第一个字符是否为双引号。如果第一个字符是双引号,则引用字段值,您需要阅读,直到找到未转义的结束双引号。在这种情况下,您可以忽略新行和逗号字符,因为该字段是引用的 - 它只在您输入结束双引号时结束。
如果第一个字符不是双引号,则字段值中的所有双引号应视为文字双引号。在这种情况下,当遇到逗号或换行符时,您将到达字段的末尾。
基于此,我建议在写出记录时始终引用所有字段,并在读取数据时编写适当的解析器来解析记录。通过这种方式,您可以将任何数据存储在CSV文件中(即使是带有嵌入式引号的多行文本),您的格式也会很清晰。当读取CSV文件时,我将无法正确解析所有文件 - 如果这是一个数据库,您可以期望用户不要手动弄乱记录,除非他们知道他们正在做什么。