【问题标题】:C# stream reader read line to stor in dataC# streamreader 读取行以对数据进行排序
【发布时间】:2018-09-27 15:11:59
【问题描述】:

我这里有sample.txt:

ABCDEABCDEABCDEABCDE
1000 ABCDEABCDEABCDEABCDE
1001 BCDEABCDEABCDEABCDEA
1002 CDEABCDEABCDEABCDEAB
1003 DEABCDEABCDEABCDEABC
1004 EABCDEABCDEABCDEABCD
1005 AABBCCDDEEABCDEABCDE
1006 ABBCCDDEEAABCDEABCDE
1007 ACBEDADCEBBCDEAABABA
1008 AAAAAAAAAAAAAAAAAAAA
1009 BBBBBBBBBBBBBBBBBBBB
1010 EEEEEEEEEEEEEEEEEEEE
1011 CCCCCCCCCCCCCCCCCCCC
1012 DDDDDDDDDDDDDDDDDDDD
0000 

第一行是标准答案,下面是学生证(4位)和学生答案(20位)。 并且要求是除非学生 ID = 0000,否则读取到 array.array[0]=student1 id,array[1]=student 1 答案的行。或 studentID[0]=student 1 ID,answer[0]=student 1 答案。 我不熟悉随着 i 增加的 while 条件。

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            int id;
            string line;
            string[] token;


            var lineCount = File.ReadLines("C:\\testresult\\exam.txt").Count();
            Console.WriteLine(lineCount);
            string[] record = new string[lineCount];

            try
            {
                StreamReader sr = new StreamReader("C:\\testresult\\exam.txt");
                line = sr.ReadLine();

                line = sr.ReadLine();
                token = line.Split();
                id = Convert.ToInt32(token[0]);
                while (id != 0)
                {
                    {
                        Console.WriteLine(token[1]);
                        line = sr.ReadLine();
                        token = line.Split();
                        id = Convert.ToInt32(token[0]);
                        for (int i = 0; i < lineCount; i = i + 2)
                        {
                           record[i]=Convert.ToString(id);
                            record[i + 1] = token[1];
                            Console.WriteLine(record[i], record[i + 1]);

                        }
                    }
                }
                sr.Close();
                Console.ReadLine();

            }
            catch { }
        }
    }
}

谁能建议如何逐行读取并将 id 和 token[0] 每次都存储到数组中的每个元素中?

【问题讨论】:

  • 我建议使用 List&lt;string&gt; 而不是数组,这样您就可以在迭代行时添加值,直到到达 0000 行。
  • 我总是尝试使用 File.ReadAllLines 然后逐行处理结果。
  • 您能澄清一下“将 id 和 token[0] 存储到每个元素中”的含义吗? id 和 token[0] 一样吗?您要寻找的最终结果是什么?
  • @TaW 请允许我指出 OP 正在(严重)使用的 File.ReadLines 方法的文档,您可以以类似的方式使用该方法;但不会一次将整个文件加载到内存中。
  • MSDN:当您处理非常大的文件时,ReadLines 可以更高效让我们这样做何时以及如果

标签: c# while-loop streamreader


【解决方案1】:

让我们来看看几个基本的学习点。

  1. 不要做try...catch,除非你真的要做某事 例外。
  2. StreamReader 是 IDisposable,所以应该在 using 块中
  3. 发布的代码将遍历整个文件两次。小文件不是问题;但我想指出这一点。
  4. 尝试养成只将变量声明为接近它们所使用的“范围”的习惯 - 它使您的代码更易于阅读和维护(例如,在移动代码时),并且不会影响性能在循环中声明局部变量。
  5. String.Split 将始终为您提供一项(第零项),但您使用的是第一项 token[1] 而不检查是否有一项,并且当 Id=0 时不会有,这会给您一个 IndexOutOfRangeException .
  6. 您有一对匹配的大括号,没有明显的原因,可以而且应该删除(保持代码简单)。
  7. 对于在while 循环中包含for 循环,您肯定会感到困惑。您的while 循环将针对文件中除第一行之外的每一行执行,因此您只需要计算您已通过循环的次数。
  8. 如果您要让您的代码更具“防御性”,您可以使用 int.TryParse 而不是 Convert.ToInt32;但我假设你并不担心这一点。

所以这会给你...

static void Main(string[] args)
{
    var records = new List<string>();
    foreach (string line in File.ReadLines("C:\\testresult\\exam.txt").Skip(1))
    {
        var tokens = line.Split();
        int id = Convert.ToInt32(tokens[0]);
        if (id == 0)
        {
            break;
        }
        else if (tokens.Length > 1)
        {
            // It looks like you want the Id and values to be put consecutively in the same array, which doesn't seem very useful.
            // I would have thought a Dictionary<int,string> would be more useful... but here you go.
            records.Add(id.ToString());
            records.Add(tokens[1]);
        }
    }

    // If you really want records to be an array you can use "records.ToArray()"

    Console.ReadLine();
}

【讨论】:

  • 当我尝试在循环中 console.writeline(record) 时,它显示 system.collection.generic.list`1[system.string],这是怎么回事??
  • 但是您的建议确实非常有用且清晰。我喜欢它!
  • @DavidShi 没事。 records 是字符串的集合。当您在其上调用 WriteLine 时,它​​会向您显示对象上 ToString 的结果,这只是类型的名称。
  • 我尝试过投票,但我的级别不足以提高它.. 抱歉!
【解决方案2】:

您可以使用哈希表来记录您的数据。 例如:

//Record data to Hash Table   
Hashtable hash = new Hashtable();

    StreamReader sr = new StreamReader(@"C:\Users\Binh\Desktop\C#\test\exam.txt");
    while(sr.EndOfStream == false)
    {
        string line = sr.ReadLine();

        if(!line.StartsWith("0") && !Regex.IsMatch(line, @"^[A-Z]"))
        {
            string[] info = line.Split(' ');//Split string
            string strudent_id = info[0];
            string student_ans = info[1];
            hash.Add(strudent_id, student_ans);
        }
    }
    sr.Close();

    //Watch the result
    foreach (DictionaryEntry item in hash)
    {
        Console.WriteLine(item.Key + "," + item.Value);
        //OUTPUT:
        //1007,ACBEDADCEBBCDEAABABA
        //1009,BBBBBBBBBBBBBBBBBBBB
        //1010,EEEEEEEEEEEEEEEEEEEE
        //1012,DDDDDDDDDDDDDDDDDDDD
        //1001,BCDEABCDEABCDEABCDEA
        //1002,CDEABCDEABCDEABCDEAB
        //1004,EABCDEABCDEABCDEABCD
        //1006,ABBCCDDEEAABCDEABCDE
        //1008,AAAAAAAAAAAAAAAAAAAA
        //1011,CCCCCCCCCCCCCCCCCCCC
        //1000,ABCDEABCDEABCDEABCDE
        //1003,DEABCDEABCDEABCDEABC
        //1005,AABBCCDDEEABCDEABCDE
    }

例如:如果你想得到 ID 为 1009 的学生的答案

string answer = hash["1009"].ToString();
Console.WriteLine(answer);//Return BBBBBBBBBBBBBBBBBBBB

【讨论】:

  • 强类型泛型字典比散列表更好。
  • StreamReader 是一次性的,所以应该在 using 块中。规范说“第一行是标准答案”,但是您已经使用正则表达式实现了这一点,该正则表达式用于每行以可能忽略它(与请求的内容不匹配)。同样,您测试 StartsWith 0 而不是指定的“0000”(因此如果 4 位 id 为 0123,它将被忽略)。错字“强硬”。
  • @Richardissimo 我只是给他一个例子,如果他想记录标准答案,他可以通过添加一些代码行轻松存档 if(Regex.IsMatch(line, @"^[AZ]" )) { string standard_ans = line; } 关于学生的案例 id 是“0000”。之后没有答案,所以我们可以忽略它。下面的这些代码只是忽略了 id 以 0 开头并且也没有答案的情况。(所以如果情况是 0001 并且有答案,它将正确记录而不是忽略)。 if(!line.StartsWith("0") && !Regex.IsMatch(line, @"^[A-Z]")) { //做点什么 }
  • 还有一点,如果有很多学生,那么你有大量的数据,当你想在列表中找到一些学生的答案时,搜索会花费很多时间。但是使用 hashtable(或任何类型的通用字典总是比 "List" 更好的选择),它总是一种快速的方法,因为它不依赖于数据量。
  • 你误解了我的观点,让我再试一次......“第一行是标准答案”,而不仅仅是任何匹配正则表达式的行:如果下一次考试怎么办答案是数字?关于 "0000" :您再次误解了我的观点:我强调您的代码决定任何以 "0" 开头的行都符合该标准,而不仅仅是以 "0000" 开头的行,所以尽管您 say 它会记录 0001,它不会。关于慢速搜索:我完全同意,并在我自己的回答中这么说,但是 OP 非常清楚地指定了他们想要的是一维值序列。希望这会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多