【问题标题】:Replace a character of the nth position替换第 n 个位置的字符
【发布时间】:2015-07-28 04:52:50
【问题描述】:

我正在编写这个程序来替换文本文件中字符串第 n 位的字符。我的文本文件包含以下内容 -

the quick brown fox jumped over the lazy dog
the quick brown fox jumped over the lazy dog
the quick brown fox jumped over the lazy dog
the quick brown fox jumped over the lazy dog

这是代码的输出 -

thehuick brown fox jumped over the lazy dog

上面的结果不是我想要的。只更新了一行,其余的在文件中都找不到了。

这是我用 C# 编写的完整代码

        var txtFiles = Directory.GetFiles(@"E:\PROJ\replaceY\replaceY\", "*.txt");
        foreach (string currentFile in txtFiles)
        {
            string[] lines = File.ReadAllLines(currentFile);
            foreach (string line in lines)
            {

                var theString = line;
                var aStringBuilder = new StringBuilder(theString);
                aStringBuilder.Remove(3, 2);
                aStringBuilder.Insert(3, "h");
                theString = aStringBuilder.ToString();
                using (StreamWriter outfile = new StreamWriter(currentFile))
                {
                    outfile.Write(theString.ToString());
                }

                Console.WriteLine(theString);
                Console.ReadKey();

            }
        }

我哪里出错了?请帮忙!

【问题讨论】:

  • 这实际上可能是最后一行,因为您在每次循环迭代中都覆盖了文件。试试new StreamWriter(currentFile, true)
  • 它只是在最后一行追加新字符串
  • 是的,你写的是我忘记了一个额外的步骤,因为你从你正在写入的同一个文件中读取,检查我的答案

标签: c# asp.net


【解决方案1】:

因为你的逻辑说:

  • 对于每个文件
    • 打开文件
    • 对于文件中的每一行
      • 处理它
      • 重新打开文件进行写入
      • 写一行

这意味着您反复用最新的行覆盖文件。最后,每个文件只包含一行:最后一行。

你会想做这样的事情:

static void Main(string[] args)
{
  foreach ( string fileName in args )
  {
    string tempFileName = Path.GetTempFileName() ;

    using ( Stream       tmpFile = File.Open( tempFileName , FileMode.OpenOrCreate , FileAccess.Write , FileShare.None ) )
    using ( StreamWriter output = new StreamWriter( tgtFile , Encoding.Default ) )
    using ( Stream       srcFile = File.Open( fileName , FileMode.Open , FileAccess.ReadWrite , FileShare.None ) )
    using ( StreamReader input = new StreamReader( srcFile , Encoding.Default , true ) )
    {
      string line ;
      while ( null != (line=input.ReadLine()) )
      {
        output.Write( line.Substring(0,3) ) ;
        output.Write( 'h' ) ;
        output.WriteLine( line.Substring(5) ) ;
      }
    }

    string backupFileName = string.Format( "{0}.{1:yyyy-MM-dd.HHmmss}.bak" , fileName , DateTime.Now ) ;

    File.Move( fileName     , backupFileName ) ;
    File.Move( tempFileName , fileName ) ;
    File.Delete( backupFileName ) ;

  }
  return;
}

您需要添加一些 try/catch/finally 异常处理来处理文件出现问题的情况,以便您可以将该文件回滚到其原始状态。

其他选项是

  • 打开文件进行读取。
  • 使用File.ReadAllLines() 或等效项在整个内容中啜饮
  • 根据需要变换线条
  • 重新打开原始文件进行写入
  • 将转换后的内容吐出到原始文件中。

这会让你想到这样的事情:

static void Main(string[] args)
{
  foreach ( string fileName in args )
  {
    string[] lines = File.ReadAllLines( fileName ) ;

    for ( int i = 0 ; i < lines.Length ; ++i )
    {
      lines[i] = ApplyTransformHere( lines[i] ) ;
    }

    File.WriteAllLines( fileName , lines ) ;

  }

  return;
}

【讨论】:

    【解决方案2】:

    我在每个设置为 false 的新文件的开头创建了一个布尔追加,因此它为第一行创建一个新文件,然后设置 append = true 以便后续每一行都追加

    var txtFiles = Directory.GetFiles(@"E:\PROJ\replaceY\replaceY\", "*.txt");
    foreach (string currentFile in txtFiles)
    {
        var append = false;
        string[] lines = File.ReadAllLines(currentFile);
        foreach (string line in lines)
        {
            var theString = line;
            var aStringBuilder = new StringBuilder(theString);
            aStringBuilder.Remove(3, 2);
            aStringBuilder.Insert(3, "h");
            theString = aStringBuilder.ToString();
            using (StreamWriter outfile = new StreamWriter(currentFile, append))
            {
                outfile.Write(theString.ToString() + Environment.NewLine);
            }
            append = true;
        }
    }
    

    【讨论】:

      【解决方案3】:

      附带说明,但仍然相关。您是否考虑过使用 Regex 替换所有行?

      https://regex101.com/r/aC6cY1/1

      点赞/(?&lt;=^.{4,4})./gm

      string input = "";//your sample text above
      string pattern = "(?<=^.{4,4}).";
      string replacement = "h";
      Regex rgx = new Regex(pattern, RegexOptions.Multiline);
      string result = rgx.Replace(input, replacement);
      

      关于您的问题,我会:

      var txtFiles = Directory.GetFiles(@"E:\PROJ\replaceY\replaceY\", "*.txt");
              foreach (string currentFile in txtFiles)
              {
              using (StreamReader sr = new StreamReader(currentFile))
                  {
                       string input = sr.ReadToEnd();
                       string pattern = "(?<=^.{4,4}).";
                       string replacement = "h";
                       Regex rgx = new Regex(pattern, RegexOptions.Multiline);
                       string result = rgx.Replace(input, replacement);
                       using (StreamWriter outfile = new StreamWriter(currentFile, append))
                        {
                            outfile.Write(result);
                        }
                  }
      }
      

      【讨论】:

      • 我在写入文件时遇到问题
      【解决方案4】:

      写出第二个 foreach 循环,用一个字符串数组替换它。然后将字符串数组写入第一个 foreach 循环下的文件中。那应该可以解决您的逻辑问题。

      【讨论】:

        猜你喜欢
        • 2011-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-27
        • 2017-12-01
        • 2012-07-19
        • 1970-01-01
        相关资源
        最近更新 更多