web-dev-qa-db-ja.com

String.Format:入力文字列が正しい形式ではありませんでした

次のコードは、入力文字列が正しい形式ではないというエラーを出し続けますが、正しいと思いますよね?

int id = 112;

String[] newData = { "1", "2", "21", "reidb", "reidb", "reidb", "reidb", "aa", 
                      "Some description", "11", "2012-02-28", "2012-01-29", "true", "1", "1", 
                      "true", "note note note", "true", "1", "2011-12-03", "45"};

String data = "{ cmd: \"save magellan deal\", data: { id: {0} , AId: {1}, " +
            "CId: {2}, CCId:{3}, LA: \"{4}\", BA: \"{5}\" , " +
            "LSA: \"{6}\" , BSA: \"{7}\" , \"path: \"{8}\"," +
            "dscp: \"{9}\", SI: \"{10}\", CD: \"{11}\", " +
            "period: \"{12}\", IsStatic: {13}, LSD: {14}, LC: {15}, RB: {16},} " +
            "Notes: \"{17}\", IsEE: {18}, RBy: {19}, DPDD: \"{20}\", LId: {21} } }";


String cmd = String.Format(data, id.toString(), newData);

誰でもアイデアはありますか?

===編集===

中括弧を修正した後、「インデックス(ゼロベース)はゼロ以上で引数リストのサイズ未満でなければなりません」という新しいエラーが発生します。与えられます。 newDataには21があり、さらにid.toString()があり、正確に22である必要がありますか?

33
jamesdeath123

書式文字列で「{」、「}」を(それらを複製して)エスケープします。

"{{ cmd: \"save magellan deal\", data: {{ id: {0} , AId: {1}, " +
"CId: {2}, CCId:{3}, LA: \"{4}\", BA: \"{5}\" , " +
"LSA: \"{6}\" , BSA: \"{7}\" , \"path: \"{8}\"," +
"dscp: \"{9}\", SI: \"{10}\", CD: \"{11}\", " +
"period: \"{12}\", IsStatic: {13}, LSD: {14}, LC: {15}, RB: {16},}} " +
"Notes: \"{17}\", IsEE: {18}, RBy: {19}, DPDD: \"{20}\", LId: {21} }} }}"

そして、フォーマット文字列には22個の要素があり、配列には21個の要素があります。

71
Cédric Bignon

newDataには21個の要素がありますが、22個のプレースホルダー(0〜21の番号)を使用しています。

また、入力データのリテラル「{」をエスケープする必要があります

中括弧の開閉は、書式項目の開始および終了として解釈されます。したがって、エスケープシーケンスを使用して、リテラルの開き中かっこまたは閉じ中かっこを表示する必要があります。固定テキストで2つの開始中括弧( "{{")を指定して1つの開始中括弧( "{")を表示するか、2つの終了中括弧( "}}")を指定して1つの終了中括弧( "}")を表示します書式項目内の中括弧は、出現順に順番に解釈されます。ネストされた中括弧の解釈はサポートされていません。

http://msdn.Microsoft.com/en-us/library/txafckwd.aspx

8
Eric J.

私はコメントで同じように言ったが、今では答える価値があると思う:

string.Formatを使用しないでください(この場合)。遅く、読みにくいです。複雑な連結が必要な場合は、意味のある変数名で単純な文字列連結を使用するだけです。これらはより高速で保守しやすくなります。固定数のセグメントではプレーン+はコンパイラの最適化により 最速のオプション であり、変数が置かれている文字列内のコンテキストを読者が見ることができるため、より保守しやすいため高速です。

Hans Passantが指摘したように、javascriptリテラルを作成しているようです。その場合は、代わりに Json.NET のようなJsonシリアライザーを検討してください。

JsonConvert.SerializeObject(new {
    cmd = "save magellan deal",
    data = new {
        id = 12345, AId = 1, CId = 2, CCId = 21,
        LA = "reidb", BA = "reidb", LSA = "reidb", BSA = "reidb",
        path = "aa", dscp = "Some description", SI = 11,
        CD = "2012-02-28", period = "2012-01-29",
        IsStatic = true, LSD = 1, LC = 1, RB = true,
    },
    Notes = "note note note",
    IsEE = true, RBy = 1, DPDD = "2011-12-03", LId = 45
})

Json.NETDateTimeシリアル化をサポートしますが、JSの日付には標準化された形式がないため、これらはiso 8601形式の文字列としてシリアル化されます。これはあなたが必要とするものではないかもしれないので、この例の日付文字列-それは最も簡単な解決策なので、最初にiso形式を試します。

3
Eamon Nerbonne

中括弧をエスケープすることに加えて、String[]定義を次のように変更してみてください。

int id = 112;

String[] newData = {id.ToString(), "1", "2", "21", "reidb", "reidb", "reidb", "reidb", "aa", 
          "Some description", "11", "2012-02-28", "2012-01-29", "true", "1", "1", 
          "true", "note note note", "true", "1", "2011-12-03", "45"};

String.Formatを次のように変更します。

String cmd = String.Format(data,newData);
2
Mark Hall

String cmd = String.Format(data, id.toString(), newData);  

は、次のとおりです。22個ではなく2個の文字列を使用して、文字列データをフォーマットしようとします!
どれですか?... 1)id.ToString()および2)newData.ToString()
明らかに間違っています

これが問題であることをどのように確認できますか...?データ文字列に{0}と{1}だけを残して印刷します。正常にコンパイルされ、何が得られるかがわかります。
もちろん、文字列リテラルが必要な場合は{の代わりに{{を使用する必要があります

完全に機能するソリューション:

int id = 112;

String[] newData = { id.ToString(),"1", "2", "21", "reidb", "reidb", "reidb", "reidb", "aa", 
                  "Some description", "11", "2012-02-28", "2012-01-29", "true", "1", "1", 
                  "true", "note note note", "true", "1", "2011-12-03", "45"};

String data = "{{ cmd: \"save magellan deal\", data: {{ id: {0} , AId: {1}, " +
                    "CId: {2}, CCId:{3}, LA: \"{4}\", BA: \"{5}\" , " +
                    "LSA: \"{6}\" , BSA: \"{7}\" , \"path: \"{8}\"," +
                    "dscp: \"{9}\", SI: \"{10}\", CD: \"{11}\", " +
                    "period: \"{12}\", IsStatic: {13}, LSD: {14}, LC: {15}, RB: {16},}} " +
                    "Notes: \"{17}\", IsEE: {18}, RBy: {19}, DPDD: \"{20}\", LId: {21} }} }}";


String cmd = String.Format(data, newData);
1
George