存储字符串数组并将结果输出到CSV

时间:2014-01-22 15:06:25

标签: c# asp.net arrays string

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

using (StreamWriter outfile = new StreamWriter(@"C:\Users\Martin\Desktop\chocListWRITE.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,Bounty

     

33333,Snickes

但在输出CSV文件中,它们显示为: 11111,Mars 22222,Bounty 33333,Snickers

这很好但是如果可能我希望输出文件将结果与控制台一样存储,每个对象后面都有一个新行。所以为此,我试图将它们存储为数组并输出????

我收到错误'文件无法写入'索引超出了数组的范围'使用choc [arrayNo] = Escape(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();

    }

2 个答案:

答案 0 :(得分:0)

即使您将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”作为换行符?这对某些系统产生了影响。

答案 1 :(得分:0)

使用它怎么样?

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,这意味着它看起来没有换行符(你必须使用<br />来换行HTML中的换行符。)