替换List <string>中特定索引处的字符,但索引器是只读的

时间:2018-01-30 02:49:26

标签: c# list enumeration flat-file

这是一个基本问题,但我学习了用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所显示的内容,但我每次都做错了。那篇文章中的内容应该有效吗?我应该做点什么吗?

4 个答案:

答案 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
    }