编写一个.csv文件 - 与文化无关

7

在德语中,小数分隔符是“,”,数值分隔符是“;”。而在英语/其他语言中,小数分隔符为“.”,数值分隔符为“,”。

我希望创建一个与当前文化无关的 .csv 文件。也就是说,该 .csv 文件应始终将“.”作为小数分隔符,将“,”作为数值分隔符。

以下是代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Globalization;

namespace CSV_FILE_FORMAT
{
    class Program
    {
        static void Main(string[] args)
        {
            string aFileName = "result.csv";
            FileStream aFileStream = new FileStream(aFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
            StreamWriter m_StreamWriter = new StreamWriter(aFileStream);
            double[] values = new double[] { 10.5, 20.3, 30.2 };
            for(int i = 0; i < values.Length;i++)
            {
                m_StreamWriter.Write(values[i].ToString(CultureInfo.InvariantCulture));
                m_StreamWriter.Write(",");
            }
        }
    }
}

这段代码存在的问题是如果操作系统语言为德语,小数分隔符会显示为“,”而不是“.”。请让我知道代码是否缺少某些内容。

2
这段代码的问题在于如果操作系统是德语的话,小数分隔符会显示为“,”而不是“.”。使用CultureInfo.InvariantCulture可以解决这个问题。所以还有其他地方我可能忽略了。 - Tim Schmelter
m_StreamWriter.Write(values[i].ToString(CultureInfo.InvariantCulture)); 我正在使用InvariantCulture,但仍然无法获得正确的值。 - Raghav55
1
提供的代码在德国操作系统(Windows 7)上运行良好(除了关闭资源;-)),并且双精度浮点数按照注释所期望的点"."格式化,即使区域设置被设置为“,”。 - Stefan Keller
似乎你已经解决了核心问题,但是测试方法不正确。 - H H
这就是为什么我更喜欢制表符分隔值而不是逗号分隔的原因之一。我的第二个原因是,你可以将TSV纯文本复制粘贴到MS Excel中。 - Soonts
3个回答

6
您可以从当前文化中获取小数分隔符和列表分隔符。
CultureInfo culture = new CultureInfo(currentCultureName);
string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator;
string listSeparator = culture.TextInfo.ListSeparator;

如果要写入的值包含任何分隔符,则将该值用双引号括起来。

string val = values[i].ToString(CultureInfo.InvariantCulture);
if(val.Contains(decimalSeparator) || val.Contains(listSeparator))
{
    val = string.Format("\"{0}\"", val);
}
m_StreamWriter.Write(val);
m_StreamWriter.Write(listSeparator);

当前的文化名称可以像这样:美国英语为“en-US”。

希望这能帮到你!


2

在我看来,这将是一个更好的解决方案,与CSV解析器相一致。 - Indy9000
3
德语版的 Excel 使用分号 ; 作为分隔符。 - Joey
这非常取决于读者部分:德语或不变的。 - H H
@Јοеу 我相信无论文化背景如何,Microsoft Excel始终将“;”作为“逗号分隔值文件”的分隔符。 - ANeves

1
这个问题没有简单的解决方案:CSV并不是文件格式定义(尽管RFC 4180如此规定)。
Excel以本地化列表分隔符和设置的本地化数据格式读取和保存CSV。这样,在CSV中,“逗号”并不意味着逗号,而是通用的列表分隔符(对于许多欧盟国家来说,这是分号,正如Tim Schmelter所说)。
如果值被引号括起来,则通常视为字符串。Excel仍会尝试解析CSV行的带引号元素,因此在非常特殊的情况下可能有效。
问题在于CSV文件的编写者和读者应该使用相同的文化,否则几乎所有不是字符串的东西都会出现问题(数字和日期/时间是另一个问题的来源)。
我对日期使用经验性衍生解决方案,由格式字符串“yyyy/MM/dd HH:mm:ss”组成。我观察到它允许Excel和我的程序之间交换工作日期,无论是英语还是意大利语都可以互换使用。
至今为止,我仍未找到一种通用的十进制数解决方案。我怀疑科学计数法可能有用,但还没有时间测试。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接