C#从文本文件中舍入小数

时间:2017-08-21 09:39:19

标签: c#

我有输入文件(.txt),包括很多数字。我有一个代码来阅读和修改它,但我没有成功删除不必要的小数。

请帮助我将这些数字舍入为2位小数。

我的代码:

const string FILE_SOURCE = @"Text.txt";

const string FILE_RESULT = @"Text2.txt";

List<TextModification> Rules = new List<TextModification>
{
new SimpleSplitLongLine(),
new SimpleModifyTextLine("string", ""),
new RegexModifyLine("LOAD [0-9]{3,}", "PERFORM ANALYSIS", "LOAD ([0-9]{3,})", "LOAD COMB $1"),
};

const bool DUMP_MODS = true;

const string STD_ENCODING = "iso-8859-1";

void Main()
{


var stdEncoding = Encoding.GetEncoding(STD_ENCODING);
int lines = File.ReadLines(FILE_SOURCE).Count();
int currentLine = 0;

var progress = new Util.ProgressBar();
progress.Caption = "Käsitellään tiedostoa";
progress.Dump();

using (TextReader r = new StreamReader(FILE_SOURCE, stdEncoding))
{
    using (TextWriter w = new StreamWriter(FILE_RESULT, false, stdEncoding))
    {           
        string line;
        while ((line = r.ReadLine()) != null)
        {
            if (++currentLine % 1000 == 0)
                progress.Percent = Math.Min(100, (currentLine* 100) / lines);

            bool handled = false;

            foreach (var rule in Rules)
            {
                if (rule.CanHandle(line, currentLine))
                {
                    rule.Handle(line, currentLine, w);
                    handled = true;                     
                }
            }

            if (!handled)
                w.WriteLine(line);
        }           
    }
}

progress.Percent = 100;
progress.Caption = "Valmis";
}

public abstract class TextModification
{
public string Name { get; set; } = String.Empty;

public abstract bool CanHandle(string line, int lineNumber);
public virtual void Handle(string line, int lineNumber, TextWriter w) {}
}

public class SimpleModifyLine : TextModification
{
public string Text { get; }
public string Replace { get; }

public SimpleModifyLine(string text, string replace)
{
    Text = text;
    Replace = replace;
}

public override bool CanHandle(string line, int lineNumber) => line.Contains(Text);

public override void Handle(string line, int lineNumber, TextWriter w)
{
    $"{lineNumber} {Name}: Modified '{line} --> {line.Replace(Text,Replace)}'".Dump();
    w.WriteLine(line.Replace(Text, Replace));       
}
}


public class SimpleSplitLongLine : TextModification
{
public int MaxLength { get; set; } = 79;
public string LineContinueSymbols { get; set;} = "-";

public override bool CanHandle(string line, int lineNumber)
{
    if (line.Length > MaxLength)
    {
        $"Katkaistaan rivi {lineNumber} (pituus: {line.Length})".Dump();
        return true;
    }       

    return false;
}


public override void Handle(string line, int lineNumber, TextWriter w)
{
    string [] data = line.Split(' ');

    string newLine = string.Empty;
    int lineLength = MaxLength - LineContinueSymbols.Length;

    for (int i = 0; i < data.Length; i++)
    {

        if (newLine.Length + data[i].Length + 1 > lineLength)
        {
            w.Write(newLine);
            w.WriteLine(LineContinueSymbols);

            newLine = data[i] + " ";
        }

        else
        {
            newLine += data[i] + " ";
        }       
    }

    if (newLine.Length > 0)
        w.WriteLine(newLine);
}
}


public class SimpleModifyTextLine : TextModification
{
public string Text { get; }
public string Replace { get; }

private List<string> buffer = new List<string>();
private const string LINE_CHANGE = "-";

public SimpleModifyTextLine(string text, string replace)
{
    Text = text;
    Replace = replace;
}

public override bool CanHandle(string line, int lineNumber)
{
    if (buffer.Count > 0)
        return true;

    return line.Contains(Text);
}

public override void Handle(string line, int lineNumber, TextWriter w)
{
    //w.WriteLine(line);

    if (line.EndsWith(LINE_CHANGE))
    {
        buffer.Add(line.Replace(Text, Replace));
    }
    else
    {           
        buffer.ForEach(w.WriteLine);            
        w.WriteLine(line.Replace(Text, Replace));
        buffer.Clear();
    }
}
}

public class RegexModifyLine : TextModification
{
public Regex StartRegex { get; }
public Regex EndRegex { get; }
public Regex ReplaceRegex { get; }
public string ReplaceString { get; }
public bool Modify { get; private set; }

public RegexModifyLine(string startRegex, string endRegex, string replaceRegex, string replaceString)
{
    StartRegex = new Regex(startRegex);
    EndRegex = new Regex(endRegex);
    ReplaceRegex = new Regex(replaceRegex);
    ReplaceString = replaceString;
}

public override bool CanHandle(string line, int lineNumber)
{
    if (!Modify && StartRegex.IsMatch(line))
    {
        Modify = true;
        return ReplaceRegex.IsMatch(line);
    }

    else if (Modify && EndRegex.IsMatch(line))
    {
        Modify = false;
        return ReplaceRegex.IsMatch(line);
    }

    if (Modify) return ReplaceRegex.IsMatch(line);

    else return false;      
}

public override void Handle(string line, int lineNumber, TextWriter w)
{
    string newLine = ReplaceRegex.Replace(line, ReplaceString);

    $"{lineNumber} {Name}: Modified '{line} --> {newLine}'".Dump();

    if (newLine != string.Empty)        
        w.WriteLine(newLine);
}
}

我的文字档案:

  

172.800000 45.000000 0.800000 35.000000 2.000000 69309.733333 14293.416000 -
  194.005333 36.000000 140.000000
  WI800-16-20X350
  261.600000 80.000000 1.600000 35.000000 2.000000 271470.133333 14317.608000 -
  293.162667 128.000000 140.000000
  132.800000 45.000000 0.800000 25.000000 2.000000 50819.733333 5210.082667 -
  140.672000 36.000000 100.000000
  18 1.000 33 -1.000 1 1.000 26 1.000 6 -1.000 14 1.000 20 1.000 19 1.000 25 1.000 13 1.000
  15 0.667 8 0.333 18 0.667 1 0.667 26 0.667 14 0.667 20 0.667 19 0.667 25 0.667 13 0.667
  15 0.667 8 0.333 18 0.667 1 0.667 14 0.667 25 0.667 13 0.667
  18 0.667 9 0.333 23 0.667 1 0.667 26 0.667 14 0.667 20 0.667 19 0.667 25 0.667 13 0.667
  18 0.667 9 0.333 23 0.667 1 0.667 14 0.667 25 0.667 13 0.667
  18 0.667 22 0.667 1 0.667 26 0.667 14 0.667 20 0.667 19 0.667 25 0.667 13 0.667 2 0.333
  18 0.667 22 0.667 1 0.667 14 0.667 25 0.667 13 0.667 2 0.333
  33 0.667 9 0.667 18 0.667 26 0.667 1 0.667 14 0.667 20 0.667 19 0.667 25 0.667 13 0.667

3 个答案:

答案 0 :(得分:0)

Math.Round会为你做这件事。

var rounded= Math.Round(0.123456789, 2);

会给你

  

0.12

请阅读MSDN Math.Round Method以获取更多信息。

答案 1 :(得分:0)

虽然您的代码看起来很复杂,但您似乎将数字作为字符串处理。因此,我认为没有实际的数字舍入。所以这里是一个解决方案,你如何在字符串逗号之后取2位小数:

string s = "18.123456";

string rounded = s.Substring(0, s.IndexOf(".")+3);

我希望你能将它添加到你的代码中。一个机会似乎在Handle方法中:

newLine += data[i].Substring(0, data[i].IndexOf(".")+3) + " ";

所有其他不符合if (rule.CanHandle(line, currentLine))标准的行,您必须手动拆分并从每个数字中取出子串。

答案 2 :(得分:0)

使用Math.Round可以做你想做的事。 但也有一个非常重要的因素,MidPointRounding

 Math.Round( 3.45, 1, MidpointRounding.ToEven) // = 3.4

 Math.Round( 3.45, 1, MidpointRounding.AwayFromZero) // = 3.5

请查看此解释MSDN