替换 List<string> 中特定索引处的字符,但索引器是只读的
Replace character at specific index in List<string>, but indexer is read only
这是一个基本问题,但我是用 C++ 学习编程的,现在正过渡到 C#,所以我对 C# 方法的无知妨碍了我。
一位客户给了我一些固定长度的文件,他们想要每条奇数记录的第 484 个字符,跳过第一个(3、5、7 等...)从 space 到 0。在我看来,我应该能够执行如下操作:
static void Main(string[] args)
{
List<string> allLines = System.IO.File.ReadAllLines(@"C:\...").ToList();
foreach(string line in allLines)
{
//odd numbered logic here
line[483] = '0';
}
...
//write to new file
}
但是,属性 或索引器无法分配给它,因为它是只读的。我所有的阅读都说我没有为变量设置 setter,并且我已经尝试了 this SO article 处显示的内容,但我每次都做错了。该文章中显示的内容应该有效吗?我应该做点别的吗?
foreach 之后的第一项(在本例中为字符串行)是一个局部变量,它在循环之外没有作用域 - 这就是为什么不能为其赋值的原因。尝试改用常规的 for 循环。
您不能直接修改 C# 字符串,因为它们是不可变的。您可以将字符串转换为 char[]
,修改它,然后再次制作一个 string
,并将其写入文件:
File.WriteAllLines(
@"c:\newfile.txt"
, File.ReadAllLines(@"C:\...").Select((s, index) => {
if (index % 2 = 0) {
return s; // Even strings do not change
}
var chars = s.ToCharArray();
chars[483] = '0';
return new string(chars);
})
);
for each 的目的是遍历容器。它本质上是只读的。您应该使用常规的 for 循环。它会起作用。
static void Main(string[] args)
{
List<string> allLines = System.IO.File.ReadAllLines(@"C:\...").ToList();
for (int i=0;i<=allLines.Length;++i)
{
if (allLines[i].Length > 483)
{
allLines[i] = allLines[i].Substring(0, 483) + "0";
}
}
...
//write to new file
}
由于字符串是不可变的,您不能通过将其视为 char[]
来修改单个字符,然后修改特定索引处的字符。但是,您 可以 "modify" 通过将其分配给新字符串来实现。
我们可以使用Substring()
方法来return原始字符串的任何部分。将此与一些连接相结合,我们可以获取字符串的第一部分(直到要替换的字符),添加新字符,然后添加原始字符串的其余部分。
此外,由于我们无法直接修改在 foreach
循环中迭代的集合中的项目,我们可以将您的循环切换为 for
循环。现在我们可以通过索引访问每一行,并且可以动态修改它们:
for(int i = 0; i < allLines.Length; i++)
{
if (allLines[i].Length > 483)
{
allLines[i] = allLines[i].Substring(0, 483) + "0" + allLines[i].Substring(484);
}
}
有可能,根据您正在处理的行数以及最终进行的内联串联的数量,使用 StringBuilder
代替串联可能会表现得更好。这是使用 StringBuilder
执行此操作的另一种方法。我会把性能测量留给你...
var sb = new StringBuilder();
for (int i = 0; i < allLines.Length; i++)
{
if (allLines[i].Length > 483)
{
sb.Clear();
sb.Append(allLines[i].Substring(0, 483));
sb.Append("0");
sb.Append(allLines[i].Substring(484));
allLines[i] = sb.ToString();
}
}
这是一个基本问题,但我是用 C++ 学习编程的,现在正过渡到 C#,所以我对 C# 方法的无知妨碍了我。
一位客户给了我一些固定长度的文件,他们想要每条奇数记录的第 484 个字符,跳过第一个(3、5、7 等...)从 space 到 0。在我看来,我应该能够执行如下操作:
static void Main(string[] args)
{
List<string> allLines = System.IO.File.ReadAllLines(@"C:\...").ToList();
foreach(string line in allLines)
{
//odd numbered logic here
line[483] = '0';
}
...
//write to new file
}
但是,属性 或索引器无法分配给它,因为它是只读的。我所有的阅读都说我没有为变量设置 setter,并且我已经尝试了 this SO article 处显示的内容,但我每次都做错了。该文章中显示的内容应该有效吗?我应该做点别的吗?
foreach 之后的第一项(在本例中为字符串行)是一个局部变量,它在循环之外没有作用域 - 这就是为什么不能为其赋值的原因。尝试改用常规的 for 循环。
您不能直接修改 C# 字符串,因为它们是不可变的。您可以将字符串转换为 char[]
,修改它,然后再次制作一个 string
,并将其写入文件:
File.WriteAllLines(
@"c:\newfile.txt"
, File.ReadAllLines(@"C:\...").Select((s, index) => {
if (index % 2 = 0) {
return s; // Even strings do not change
}
var chars = s.ToCharArray();
chars[483] = '0';
return new string(chars);
})
);
for each 的目的是遍历容器。它本质上是只读的。您应该使用常规的 for 循环。它会起作用。
static void Main(string[] args)
{
List<string> allLines = System.IO.File.ReadAllLines(@"C:\...").ToList();
for (int i=0;i<=allLines.Length;++i)
{
if (allLines[i].Length > 483)
{
allLines[i] = allLines[i].Substring(0, 483) + "0";
}
}
...
//write to new file
}
由于字符串是不可变的,您不能通过将其视为 char[]
来修改单个字符,然后修改特定索引处的字符。但是,您 可以 "modify" 通过将其分配给新字符串来实现。
我们可以使用Substring()
方法来return原始字符串的任何部分。将此与一些连接相结合,我们可以获取字符串的第一部分(直到要替换的字符),添加新字符,然后添加原始字符串的其余部分。
此外,由于我们无法直接修改在 foreach
循环中迭代的集合中的项目,我们可以将您的循环切换为 for
循环。现在我们可以通过索引访问每一行,并且可以动态修改它们:
for(int i = 0; i < allLines.Length; i++)
{
if (allLines[i].Length > 483)
{
allLines[i] = allLines[i].Substring(0, 483) + "0" + allLines[i].Substring(484);
}
}
有可能,根据您正在处理的行数以及最终进行的内联串联的数量,使用 StringBuilder
代替串联可能会表现得更好。这是使用 StringBuilder
执行此操作的另一种方法。我会把性能测量留给你...
var sb = new StringBuilder();
for (int i = 0; i < allLines.Length; i++)
{
if (allLines[i].Length > 483)
{
sb.Clear();
sb.Append(allLines[i].Substring(0, 483));
sb.Append("0");
sb.Append(allLines[i].Substring(484));
allLines[i] = sb.ToString();
}
}