String.Format:输入字符串的格式不正确[关闭]

Posted

技术标签:

【中文标题】String.Format:输入字符串的格式不正确[关闭]【英文标题】:String.Format: Input string was not in a correct format [closed] 【发布时间】:2013-01-29 00:19:11 【问题描述】:

以下代码一直给我错误提示输入字符串的格式不正确,但我很确定它是正确的,不是吗?

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?

【问题讨论】:

您需要转义花括号。对 json 数据 '' 使用两个。 你的格式是什么..?查看如何使用 string.Format 就我个人而言,我根本不会使用string.Format——它只是无缘无故地增加了复杂性。您无法快速判断哪个参数适用于哪个占位符。字符串连接具有相同的语义,没有要记住的转义规则,甚至更快 - 然后您实际上可以看到您正在插入的变量的上下文,我认为这在实际程序中具有一定的意义。 @EamonNerbonne:我同意复杂性,但不同意速度。字符串在 C# 中是不可变的,因此在这种情况下进行多个字符串连接可能会更慢。但是,对于大多数用例而言,性能差异可能并不重要,因此我更倾向于使用更清晰、更易于维护的代码而不是 String.Format。 这是非常糟糕的代码。您是否至少考虑过使用真正的 json 序列化程序? 【参考方案1】:

转义格式字符串中的“”、“”(通过复制它们):

" 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 个元素。

【讨论】:

hmm,改成双大括号后,原来的错误消失了,但是Index必须大于等于0并且小于给定的参数列表的大小。 newData + extra id.toString() 里面有 21 个,应该是 22... 完全放弃这种方法并简单地使用带有一些快速组合匿名对象的 JSON 编码器似乎是一个很好的理由。明显不易出错。 第一次知道花括号需要在c#@formatted字符串中转义。【参考方案2】:

newData 中有 21 个元素,但使用了 22 个占位符(编号为 0 到 21)。

此外,您必须在输入数据中转义文字“”

左大括号和右大括号被解释为格式项的开始和结束。因此,您必须使用转义序列来显示文字左大括号或右大括号。在固定文本中指定两个左大括号(“”)以显示一个左大括号(“”),或两个右大括号(“”)以显示一个右大括号(“”)。格式项中的大括号按照遇到的顺序依次解释。不支持解释嵌套大括号。

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

【讨论】:

我在第一次发布时错过了 id,但在我的代码中我确实有它但仍然收到错误。【参考方案3】:

我在 cmets 上已经说了这么多,但我认为现在值得回答:

不要使用string.Format(在这种情况下)。它速度较慢,可读性较差。如果您需要复杂的连接,只需使用简单的字符串连接和有意义的变量名 - 这些将更快且更易于维护。更快,因为对于固定数量的段,由于编译器优化,纯 + 是 the fastest option,并且更易于维护,因为读者可以看到放置变量的字符串中的上下文。

正如 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.NET 确实支持DateTime 序列化,但JS 中的日期没有标准化格式,因此这些日期被序列化为iso 8601 格式的字符串。这可能不是您需要的,因此本示例中的日期字符串 - 不过,我会先尝试 iso 格式,因为这是最简单的解决方案。

【讨论】:

【参考方案4】:

除了转义花括号外,还可以尝试将 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);

【讨论】:

@jamesdeath123 - 或者,正如我刚刚输入的那样,您只有两个参数来填充格式字符串中的 22 个位置。根据 Cédric Bignon 的规定,字面大括号需要转义。【参考方案5】:

什么

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

确实是:尝试格式化字符串数据,仅使用 2 个字符串..不是 22!! 哪些?...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);

【讨论】:

以上是关于String.Format:输入字符串的格式不正确[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 Lua 中 string.format 参数不正确抛出异常问题

如何将String / char格式化为十六进制值正确

String.format

格式字符串 XXX 不是有效的格式字符串,因此不应将其传递给 String.format

聊聊String.format()方法

JAVA字符串格式化String.format()的使用