字符串索引和子字符串 C#

String IndexOf and Substring C#

我正在努力读取包含这行字符串的文本文件。并将其值提取到我的整数变量中。我想尽量避免使用 Class 或 Arrays.

string cont = "[]val1:1val2:0val3:1";

int split = cont.IndexOf("val3:");
int val3 = Int32.Parse(cont.Substring(split + 5)); // this line successfully convert string to int
cont.Remove(split);
Console.WriteLine("Value3: " + val3 + " Content: " + cont);

split = cont.IndexOf("val2:");
int val2 = Int32.Parse(cont.Substring(split + 5)); // LINE 21
cont.Remove(split);
Console.WriteLine("Value2: " + val2 + " Content: " + cont);

split = cont.IndexOf("val1:");
int SilverCoins = Int32.Parse(cont.Substring(split + 5));
cont.Remove(split);
Console.WriteLine("Value1: " + val1 + " Content: " + cont);

当我 运行 这段代码时,我得到一个未处理的异常,它指出 Input string was not in a correct format, at System.Int32.Parse(String s), line 21。 :(

所以,我想要的输出应该是

Value3: 1 Content: []val1:1val2:0
Value2: 0 Content: []val1:1
Value1: 1 Content: []

您的问题出在这段代码中cont.Remove(split);
字符串是不可变的,因此您需要重新分配新值。
为了修复它,你需要写

cont = cont.Remove(split);

0val3:1 不是有效数字,因此 int.Parse 失败。如果需要从这个字符串的开头提取0,可以参考Parse an integer from a string with trailing garbage.

此外,cont.Remove(split); 的结果从未在您的代码片段中使用,因此只会浪费 CPU 个周期。考虑到您在 Console.WriteLine 中注意到了这种行为,并且只是抱怨异常,我只能假设这是故意的?


请注意,您似乎正在尝试从字符串中提取键值对。类似于 val([^:]+):([0-9]+) 的正则表达式在这里可能是更好的工具。

或者,您可以拆分 val 并取冒号的 left/right。类似于:

var vals = cont.Split(new[] {"val"}, StringSplitOptions.None)
               .Skip(1) //ignore any garbage at the beginning
               .Select(x => x.Split(':'))
               .ToDictionary(x => x[0], x => int.Parse(x[1]));

调用 Remove 方法后恢复 cont 值丢失。

修改后的代码:

string cont = "[]val1:1val2:0val3:1";

int split = cont.IndexOf("val3:");
int val3 = Int32.Parse(cont.Substring(split + 5)); // this line successfully convert string to int
cont = cont.Remove(split);
Console.WriteLine("Value3: " + val3 + " Content: " + cont);

split = cont.IndexOf("val2:");
int val2 = Int32.Parse(cont.Substring(split + 5)); // but this line fails to convert from string to int..
cont = cont.Remove(split);
Console.WriteLine("Value2: " + val2 + " Content: " + cont);

split = cont.IndexOf("val1:");
int val1 = Int32.Parse(cont.Substring(split + 5));
cont = cont.Remove(split);
Console.WriteLine("Value1: " + val1 + " Content: " + cont);

解决问题的两种方法。

C# 字符串是不可变的,因此您必须将代码修改为

cont = cont.Remove(split);

另一种方法(可能最适合您的情况),当使用 SubString 指定长度时,您将获得指定的字符数。

split = cont.IndexOf("val2:");
int val2 = Int32.Parse(cont.Substring(split + 5, 1)); 

您没有将删除结果放回字符串中,请尝试这样做:

cont = cont.Remove(split);

当我们对字符串执行某些操作时,它不会在同一个字符串实例中进行更改。相反,它 returns 一个新的字符串实例。这个概念被称为不变性

当你这样做时

cont.Remove(split);

它不会更新 cont。相反,它 returns 更新了您需要像这样捕获的字符串

cont = cont.Remove(split);