6

我用 C 编写了自己的 CSV 读取器/写入器,以将记录存储在 ODBC 数据库的字符列中。不幸的是,我发现了许多影响我的实现的边缘案例,我得出的结论是我的问题是我没有严格定义 CSV 的规则。我已经阅读了 RFC4180,但它似乎不完整并且不能解决歧义。

例如,应该将 "" 视为空标记还是双引号?引号是由外向内匹配还是从左到右匹配?如何处理具有不匹配单引号的输入字符串?当我嵌套了标记时,真正的混乱开始了,这使转义的引号字符加倍。

我真正需要的是可以在代码中实现的明确的 CSV 标准。每次我觉得我已经钉牢了每个角落的情况时,我都会找到另一个。我相信这个问题已经被我的优秀头脑多次考虑和解决了,有没有人写过我可以在代码中实现的 CSV 的严格定义?我意识到 C 在这里不是理想的语言,但在这个阶段我没有选择编译器;我也不能使用第三方库(除非它用 C-90 编译)。Boost 不是一个选项,因为我的编译器不支持 C++。我曾考虑为 XML 放弃 CSV,但在 256 个字符的数据库记录中存储一些标记似乎有点过头了。有人制定了明确的 CSV 规范吗?

4

3 回答 3

1

没有标准(参见维基百科的文章,特别是http://en.wikipedia.org/wiki/Comma-separated_values#Lack_of_a_standard),所以为了使用 CSV,您需要遵循保守的一般原则在你接受的东西上产生和自由。尤其是:

  • 不要在空白字段中使用引号。只需写一个空字段(两个相邻的定界符,或行的第一个/最后一个位置的定界符)。
  • 引用包含引号、逗号或换行符的任何字段。
于 2013-06-06T04:04:52.417 回答
0

找到您信任的最权威的 CSV 库并阅读源代码。CSV 并不复杂,以至于您无法通过全面阅读源代码实现来理解其规则。我对 Java 的opencsv很满意。Perl 在这里,等等。

于 2013-06-06T03:58:51.410 回答
0

根据RFC 4180,应该从左到右解析字段以正确解释双引号。在某些情况下""是转义的双引号(当在带引号的字段内时),否则它是空字符串或两个双引号(当在其他非空字段值内时)。

例如,考虑一个有 4 条记录(1 列)的文件:

"field""value" CRLF
"" CRLF
field""value CRLF
"field value" extra CRLF
  1. "field""value"- 应该读作field"value
  2. ""- 应该读为一个空字符串
  3. field""value- 应该读作field""value
  4. "field value" extra- 可以读作,field value extra或者你可以拒绝它

记录 4 确实是一个无效字段,因此您可以接受或拒绝它。

当您开始读取一个字段时,您需要检查读取的第一个字符是否是双引号。如果第一个字符是双引号,则引用字段值,您需要阅读直到找到未转义的右双引号。在这种情况下,您可以忽略换行符和逗号字符,因为该字段被引用 - 它仅在您遇到结束双引号时结束。

如果第一个字符不是双引号,则字段值中的所有双引号都应视为文字双引号。在这种情况下,当您遇到逗号或换行符时,您会到达字段的末尾。

基于此,我建议在写出记录时始终引用所有字段,并在读取数据时编写适当的解析器来解析记录。通过这种方式,您可以将任何数据存储在 CSV 文件中(甚至是带有嵌入引号的多行文本),并且您的格式将一目了然。读取 CSV 文件时,所有无法正确解析的文件都会失败 - 如果这是一个数据库,您可以期望用户不要手动弄乱记录,除非他们知道自己在做什么。

于 2013-06-06T04:08:34.237 回答