从文件中读取文本并对其应用一些操作

时间:2008-12-11 21:11:00

标签: c#

我遇到了如何从文件中读取文本并对其执行操作的问题,例如

我有这个包含

的文本文件

// name - // sex --------- // birth // m1 // m2 // m3

fofo, male,    1986, 67, 68,  69
momo, male,    1986, 99, 98,  100
Habs, female,  1988, 99, 100, 87
toto, male,    1989, 67, 68,  69
lolo, female,  1990, 89, 80,  87
soso, female,  1988, 99, 100, 83

现在我知道如何逐行阅读,直到我达到null。

但是这次我想要稍后执行和平均函数来得到第一个数字的平均值m1

然后得到女性的平均值仅为女性,仅为男性

以及其他一些我无能为力的操作


我需要帮助,我不知道如何得到它 我的想法是读取文本文件中的每一行并将其放入一个字符串然后拆分字符串(str.Split(',');)但如何获取每个字符串上的m1记录 如果我使用正则表达式得到整数,我真的很困惑?我应该使用数组2d吗?我完全迷失了,有什么想法吗?

如果您可以通过代码示例改进任何想法,那将是非常好的,并且可以从您那里获得善意。

在我完成之后,我会发布给你们检查。

{作为一个女孩我认为我做错了决定加入IT社区:-(}

7 个答案:

答案 0 :(得分:5)

尝试这样的事情。

  var qry = from line in File.ReadAllLines(@"C:\Temp\Text.txt")
            let vals = line.Split(new char[] { ',' })
            select new
            {
              Name = vals[0].Trim(),
              Sex = vals[1].Trim(),
              Birth = vals[2].Trim(),
              m1 = Int32.Parse(vals[3]),
              m2 = Int32.Parse(vals[4]),
              m3 = Int32.Parse(vals[5])
            };

  double avg = qry.Average(a => a.m1);
  double GirlsAvg = qry.Where(a => a.Sex == "female").Average(a => a.m1);
  double BoysAvg = qry.Where(a => a.Sex == "male").Average(a => a.m1);

答案 1 :(得分:1)

我写了一篇博客文章,详细介绍了阅读CSV文件并解析其列的行为:

http://www.madprops.org/blog/back-to-basics-reading-a-csv-file/

我采用了你提到的方法(拆分字符串),然后使用DateTime.TryParseExact()和相关方法将各个值转换为我需要的类型。

希望帖子有所帮助!

答案 2 :(得分:1)

(注意:这似乎是一个过于复杂的解决方案,但我假设源数据很大(很多行),因此将其加载到List<T>可能不可行)

使用迭代器块可以很好地完成文件读取...如果数据很大,你只想一次处理一行,而不是2D数组。

这实际上看起来非常适合MiscUtil的PushLINQ方法,它可以在数据流上同时执行多个聚合,而无需缓冲...

以下是一个例子......

为什么这有用?

因为它允许您使用标准LINQ语法在数据源上编写多个查询,但只能读取一次。

示例

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using MiscUtil.Linq;
using MiscUtil.Linq.Extensions;
static class Program
{

    static void Main()
    {
        // prepare a query that is capable of parsing
        // the input file into the expected format
        string path = "foo.txt";
        var qry = from line in ReadLines(path)
                  let arr = line.Split(',')
                  select new
                  {
                      Name = arr[0].Trim(),
                      Male = arr[1].Trim() == "male",
                      Birth = int.Parse(arr[2].Trim()),
                      M1 = int.Parse(arr[3].Trim())
                      // etc
                  };

        // get a "data producer" to start the query process
        var producer = CreateProducer(qry);

        // prepare the overall average
        var avg = producer.Average(row => row.M1);

        // prepare the gender averages
        var avgMale = producer.Where(row => row.Male)
                    .Average(row => row.M1);    
        var avgFemale = producer.Where(row => !row.Male)
                    .Average(row => row.M1);

        // run the query; until now *nothing has happened* - we haven't
        // even opened the file    
        producer.ProduceAndEnd(qry);

        // show the results
        Console.WriteLine(avg.Value);
        Console.WriteLine(avgMale.Value);
        Console.WriteLine(avgFemale.Value);
    }
    // helper method to get a DataProducer<T> from an IEnumerable<T>, for
    // use with the anonymous type
    static DataProducer<T> CreateProducer<T>(IEnumerable<T> data)
    {
        return new DataProducer<T>();
    }
    // this is just a lazy line-by-line file reader (iterator block)    
    static IEnumerable<string> ReadLines(string path)
    {
        using (var reader = File.OpenText(path))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                yield return line;
            }
        }
    }

}

答案 3 :(得分:1)

是否有理由不创建存储文件字段,字符串,布尔值(对于m / f),整数和3个整数的数据结构,您可以将其存储到存储值的List中然后循环它以计算各种总和,平均值,以及您想要的其他任何聚合函数。

答案 4 :(得分:0)

我建议使用FileHelpers库。查看示例:Quick start

您可以计算foreach循环中的平均值,如页面上的平均值。

答案 5 :(得分:0)

苏珊娜,我提前道歉,但我不是故意冒犯你。你已经说过“作为一个女孩,你做错了决定加入IT ......”,我之前从姐妹们那里说过,我一直试着帮助他们选择职业。但是如果您在遵循上述答案时遇到概念上的困难而不仅仅复制并粘贴代码,我认为您只是验证了部分陈述。

话虽如此,IT部门还不仅仅是编写代码。换句话说,编码可能不仅仅适合您,但IT部门还有其他领域可能会出类拔萃,包括有朝一日成为经理。我有很多经理无法用任何语言完成上述任务,但他们在管理人员,项目和资源方面做得很好。

相信我,从这里开始变得越来越难了。这是编程中非常基本的任务。但是如果你很快意识到这一点,你可以和你的经理谈谈,要求公司提出非编码方面的挑战。质量保证也可能是另一种选择。再一次,我只是想帮忙,如果你被冒犯我很抱歉。祝好运。

答案 6 :(得分:0)

重新开始跟进“假设”;你只需循环:

// rows is the jagged array of string1, string2 etc
int totalCounter = 0, totalSum = 0; // etc
foreach(string[] row in rows)
{
    int m1 = int.Parse(row[3]);
    totalCounter++;
    totalSum += m1;
    switch(row[2]) {
        case "male":
            maleCount++;
            maleSum += m1;
            break;
        case "female":
            femaleCount++;
            femaleSum += m1;
            break;
    }
}

等。然而,虽然这是有效的,但你可以在C#3.0中使用LINQ更方便/更有表现地做同样的事情 lot ,这是许多现有的回复试图显示的...事实是,Tim J的帖子已经完成了所有这些:

  • ReadAllLines:获取每行的行数
  • 拆分:获取每行的数据数组
  • “select new {...}”:将数据解析为方便的
  • 3“avg”行显示如何对过滤后的数据取平均值

我唯一的改变就是我会在某处添加一个ToArray(),所以我们只读取一次文件......