0

Having problems with formatting CSV created from C# code. In the notepad file the output scrolls vertically down one row (the values seen in the structs below are output in one row. There is a row of numbers as well that appears directly below the struct values but the numbers should be in a new row beside the structs). When I open in excel it's a similar story only the output from the structs is where it should be however the row of numbers appears directly below the struct values but one row to the right if that makes sense, and the numbers should appear directly beside their corresponding struct values. The code I'm using is below.

Here are the structs for the dictionaries im working with.

public enum Genders
{
    Male,
    Female,
    Other,
    UnknownorDeclined,
}

public enum Ages
{
    Upto15Years,
    Between16to17Years,
    Between18to24Years,
    Between25to34Years,
    Between35to44Years,
    Between45to54Years,
    Between55to64Years,
    Between65to74Years,
    Between75to84Years,
    EightyFiveandOver,
    UnavailableorDeclined,
}

the csv file that does the outputting using a streamwriter and stringbuilder.

public void CSVProfileCreate<T>(Dictionary<T, string> columns, Dictionary<T, int> data)
{
        StreamWriter write = new StreamWriter("c:/temp/testoutputprofile.csv");
        StringBuilder output = new StringBuilder();
        foreach (var pair in columns)
        {
            //output.Append(pair.Key);
            //output.Append(",");
            output.Append(pair.Value);
            output.Append(",");
            output.Append(Environment.NewLine);
        }

        foreach (var d in data)
        {
            //output.Append(pair.Key);
            output.Append(",");
            output.Append(d.Value);
            output.Append(Environment.NewLine);
        }

        write.Write(output);
        write.Dispose();
}

And finally the method to feed the dictionaries into the csv creator.

    public void RunReport()
    {
        CSVProfileCreate(genderKeys, genderValues);
        CSVProfileCreate(ageKeys, ageValues);
    }

Any ideas?

UPDATE

I fixed it by doing this:

    public void CSVProfileCreate<T>(Dictionary<T, string> columns, Dictionary<T, int> data)
    {
        StreamWriter write = new StreamWriter("c:/temp/testoutputprofile.csv");
        StringBuilder output = new StringBuilder();

        IEnumerable<string> col = columns.Values.AsEnumerable();
        IEnumerable<int> dat = data.Values.AsEnumerable();

        for (int i = 0; i < col.Count(); i++)
        {
            output.Append(col.ElementAt(i));
            output.Append(",");
            output.Append(dat.ElementAt(i));
            output.Append(",");
            output.Append(Environment.NewLine);
        }

        write.Write(output);
        write.Dispose();
    }

}
4

1 に答える 1

2

出力するすべての値の後に Environment.NewLine を記述します。

ループを 2 つ持つのではなく、出力するループを 1 つだけ持つ必要があります。

  • ペア"
  • 価値
  • Environment.改行

反復ごとに。

columns同じキーを持っていると仮定するとdata、次のようになります

foreach (T key in columns.Keys)
{
    pair = columns[key];
    d = data[key];
    output.Append(pair.Value);
    output.Append(",");
    output.Append(d.Value);
    output.Append(Environment.NewLine);
}

2 つの複雑さに注意してください。

  • pair.Valueまたはカンマが含まれている場合d.Valueは、そのセルの出力を二重引用符で囲む必要があります。
  • If pair.Valueord.Valueにコンマが含まれていて、二重引用符も含まれている場合は、二重引用符を二重にしてエスケープする必要があります。

例:

スミス・ジュニア

出力する必要があります

「スミス・ジュニア」

"スミティ" スミス Jr.

出力する必要があります

"""Smitty"" スミス、ジュニア"

アップデート

キーに関するあなたのコメントに基づいて...

列挙のために、ディクショナリ内の各項目は、値とそのキーを表す KeyValuePair 構造体として扱われます。アイテムが返される順序は定義されていません。

http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

キーを使用して正しいペアを正しいデータに関連付けることができない場合、どのように関連付けを行うのでしょうか?

ディクショナリを繰り返し処理していて、それらが期待どおりの順序になっている場合、それはまったく未定義の動作であり、次の .NET サービス パックで変更される可能性があります。

ペアを正しいデータと関連付けるには、信頼できるものが必要です。

var キーワードについて

varは型ではなく、型全体を書き出すことから解放されるショートカットです。必要に応じてvarを使用できますが、実際の型はKeyValuePair<T, string>and KeyValuePair<T, int>each です。Visual Studio でvarと書き、そのキーワードにマウスを合わせると、それがわかります。

リソースの破棄について

あなたのライン

write.Dispose();

危険です。その行に到達する前にコードのいずれかが例外をスローした場合、そのコードは実行されず、書き込みは破棄されません。次のようにusingキーワードを使用することを強くお勧めします。

using (StreamWriter write = new StreamWriter("c:/temp/testoutputprofile.csv"))
{
    // Your code here
}

usingのスコープが終了すると (関連する } の後)、例外がスローされたかどうかにかかわらず、write.Dispose() が自動的に呼び出されます。これは、と同じですが、より短いです。

try
{
    StreamWriter write = new StreamWriter("c:/temp/testoutputprofile.csv");
    // Your code here
}
finally
{
    write.Dispose();
}
于 2013-01-11T00:16:00.933 に答える