这是一个基本问题,但我学习了用C ++编程,而且只是转换到C#,所以我对C#方法的无知正在阻碍我。
客户端给了我一些固定长度的文件,他们想要每个奇数记录的第484个字符,跳过从空格变为0的第一个(3,5,7等等)。我的想法,我应该可以做如下的事情:
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所显示的内容,但我每次都做错了。那篇文章中的内容应该有效吗?我应该做点什么吗?
答案 0 :(得分:1)
您无法直接修改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);
})
);
答案 1 :(得分:1)
由于字符串是不可变的,因此您不能通过将其视为char[]
来修改单个字符,然后修改特定索引处的字符。但是,您可以&#34;修改&#34;通过将其分配给新字符串。
我们可以使用Substring()
方法返回原始字符串的任何部分。将此与一些串联相结合,我们可以获取字符串的第一部分(直到您要替换的字符),添加新字符,然后添加原始字符串的其余部分。
此外,由于我们无法直接修改在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();
}
}
答案 2 :(得分:-1)
foreach之后的第一个项(在本例中为字符串行)是一个局部变量,它在循环外没有作用域 - 这就是为什么你不能为它赋值。请尝试使用常规for循环。
答案 3 :(得分:-1)
每个的目的是迭代容器。它只是在自然界中阅读。你应该使用常规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
}