存储一系列字符串并将结果输出到CSV



以下代码将巧克力列表写入CSV文件:

using (StreamWriter outfile = new StreamWriter(@"C:UsersMartinDesktopchocListWRITE.csv", true)) //true:  append text to a file with StreamWriter. The file is not erased, but just reopened and new text is added to the end. 
{
    Chocolate _choc = new Chocolate();
    string line = _choc.Serialize();
    outfile.WriteLine(line);
    Console.WriteLine(line);
}

在控制台中,它们显示为:

11111,火星

22222,赏金

33333,Snickes

但是在输出CSV文件中,它们显示为:11111,火星22222,赏金33333,Snickers

这很好,但是如果可能的话,如果可能的话,我希望输出文件将结果与控制台相同,并在每个对象之后使用新行。因此,为此,我试图将它们存储为一个数组并输出???

我遇到了错误'文件无法写入"索引"索引在数组的边界之外'''''cock [arrayno] = easce(c._barcode.number);

//dummy data of list of chocolates assigned to 'Chocolates'
//serialize function
 string[] fullList = new string[] { };
        string[] choc = new string[] { };
        int arrayNo = -1;
        foreach (Choclate c in Choclates)
        {
            arrayNo = arrayNo + 1;
            choc[arrayNo] = Escape(c._barcode.number);//returns barcode as string
            choc[arrayNo + 1] = Escape(c._bar.barName);//returns name as string                             
        }
        return choc;
    }
    string Escape(String s)
    {
        StringBuilder sb = new StringBuilder();
        bool needQuotes = false;
        foreach (char c in s.ToArray())
        {
            switch (c)
            {
                case '"': sb.Append("\""); needQuotes = true; break;
                case ' ': sb.Append(" "); needQuotes = true; break;
                case ',': sb.Append(","); needQuotes = true; break;
                case 't': sb.Append("\t"); needQuotes = true; break;
                case 'n': sb.Append("\n"); needQuotes = true; break;
                default: sb.Append(c); break;
            }
        }
        if (needQuotes)
            return """ + sb.ToString() + """;
        else
            return sb.ToString();
    }

怎么办?

return Choclates
  .Select(i => Escape(i._barcode.number) + "," + Escape(i._bar.barName))
  .ToArray();

这是一种从集合中构建字符串数组的简单方法。您可能必须在使用中添加System.Linq

另外,您可以使用一些有用的方法来简化整个工作,例如,您的Encode方法可以使用以下方式:

private static readonly char[] CharsToEncode = new []{'"', 'r', 'n', ',', 't'};
string Escape(string str)
{
  if (str.IndexOfAny(CharsToEncode) != -1)
  {
    return """ + str.Replace(""", """") + """;
  }
  else
  {
    return str;
  }
}

无论如何,当您使用StreamWriter时,构建字符串阵列是完全不需要的。您只需要根据需要浏览每种巧克力和WriteLine。这也将添加端线。如果您的结果是出乎意料的,那么您正在做其他错误。您可能只使用WriteLine方法一次,而不是每巧克力一次?还是您的输出在浏览器中显示?在这种情况下,它倾向于将其解释为HTML,这意味着它看起来没有折断(您必须在HTML中使用<br />进行折断)。

即使您将arrayNo设置为负1,您仍然会在代码其余部分中的一个错误中获得一个错误。MATTC是正确的,初始化数组的大小与Choclates列表的计数相同,但是此外,您需要更改代码行

choc[arrayNo + 1] = Escape(c._bar.barName);//returns name as string 

假设您的数组是1个元素,然后在您的示例中,当您在foreach循环内启动时,arrayNo等于0:

var firstElement = choc[arrayNo] // arrayNo is 0 so an array of 1 item will be able to reference this
var secondElement = choc[arrayNo + 1] // choc is a 1 element array so you will get out of bounds exception

编辑

您是否尝试使用" r n"而不是仅仅用于新线字符的" n"?这在某些系统上有所作为。

最新更新