C#-文本文件中每两行

C#-文本文件中每两行,c#,xamarin,foreach,console-application,C#,Xamarin,Foreach,Console Application,我正在C#中开发。 我有一个文本文件,包含以下内容: Sam NYC Mii Peru LEO Argentina 我想逐行遍历这个文件,然后将每对夫妇的第一行、第二行(姓名和国家)打印到控制台,这样输出将是: Sam, NYC Mii, Peru 以下是我尝试过的: int linenum = 0; foreach (string line in File.ReadLines("c:\\file.txt")) { string wor

我正在
C#
中开发。 我有一个
文本文件
,包含以下内容:

Sam
NYC
Mii
Peru
LEO
Argentina
我想逐行遍历这个文件,然后将每对夫妇的
第一行、第二行
(姓名和国家)打印到控制台,这样输出将是:

Sam, NYC
Mii, Peru
以下是我尝试过的:

int linenum = 0;
        foreach (string line in File.ReadLines("c:\\file.txt"))
        {
            string word = line;
            string s = "";
            string j = "";
            linenum = linenum + 1;
            if(linenum % 2 != 0) //impaire
            {
                s = line;
            }
            else
            {
                j = line;
            }
          Console.WriteLine((string.Concat(s, j));
     }
但这不起作用,我想做:

 int linenum = 0;
 foreach( two lines in File.ReadLines("c:\\file.txt"))
 {
 linenum = linenum + 1;
 //get the first line (linenum = 1) and store it in a string s
 // then get the second line (linenum = 2) and store it in a string j
 // then print the two strings together to the console like that 
  Console.WriteLine((string.Concat("S: " + s,"J: " j));
 }

如何执行此操作?

使用
File.ReadAllLines
返回字符串数组:

var lines = File.ReadAllLines(filePath);
for (int i = 0; i < lines.Length; i+=2)
{
    var s = lines[i];
    var j = lines[i+1];
    Console.WriteLine($"S: {s} J: {s}");
}
var lines=File.ReadAllLines(filePath);
对于(int i=0;i
实际上,您可以使用LINQ通过Take一次获得两行

var twoLines = File.ReadLines(@"YourPath").Take(2));
正如您可以使用“跳过”跳过所选的两行,然后选择下两行,如下所示:

var twoLines = File.ReadLines(@"YourPath").Skip(2).Take(2));
编辑:感谢@derpirscher出现性能问题,因此将代码更改为以下内容:

首先读取整个文件并将其存储在字符串数组中 然后使用LINQ循环遍历它,一次从数组中获取两个元素

string[] myStringArray = File.ReadAllLines(@"YourFile.txt");
for (int i = 0; i < myStringArray.Length ; i+=2)
   {
      var twoLines = myStringArray.Skip(i).Take(2).ToArray();
   }
string[]myStringArray=File.ReadAllLines(@“YourFile.txt”);
对于(int i=0;i
您可以使用
控制台进行输出。在每一行中写入行,但也应该只在第二行中执行。此外,变量
s
j
位于循环的作用域内,因此每次迭代都会重新创建它们,并释放它们的先前值

int i = 0; string prev = "";
foreach (string line in File.ReadLines("c:\\file.txt")) {
    if (i++ % 2 == 0) prev = line;
    else Console.WriteLine($"{prev}, {line}");
}
另一种方法是使用
for
循环而不是
foreach
迭代从
File.ReadAllLines
获得的数组,并将索引增加2

var lines = File.ReadAllLines("c:\\file.txt");
//make sure, you have an even number of lines!
if (lines.Length% 2 == 0) for (int i = 0; i < lines.Length; i+=2) {
   Console.WriteLine($"{lines[i]}, {lines[i+1]}");  
}
var lines=File.ReadAllLines(“c:\\File.txt”);
//确保你有偶数行!
if(lines.Length%2==0)for(int i=0;i
为作业使用正确的工具
foreach()
不是这里的正确工具

在不放弃ReadLines()相对于ReadAll()的内存效率的情况下:


您可以自己编写一个小助手方法来返回成批的行

此实现通过为文件末尾缺少的行返回
,来处理不是批处理大小倍数(在您的情况下为2)的文件

public static IEnumerable<string[]> BatchedLinesFromFile(string filename, int batchSize)
{
    string[] result = Enumerable.Repeat("", batchSize).ToArray();
    int count = 0;

    foreach (var line in File.ReadLines(filename))
    {
        result[count++] = line;

        if (count != batchSize)
            continue;

        yield return result;
        count  = 0;
        result = Enumerable.Repeat("", batchSize).ToArray();
    }

    if (count > 0)
        yield return result;
}
另一个,使用和一个整数选择器将a
[NumberOfLines/2]
增加了几倍。
对于上瘾的
LINQ
来说可能很有趣(无论如何,
for/foreach
解决方案可能更好)。

输出为:

Sam NYC
Mii Peru
LEO Argentina

不要将相关信息存储在foreach循环的不同行中,您必须跟踪奇偶状态。请记住奇数值,并以偶数打印。如果您的文件不是很大,那么您可能会有更好的经验,使用file.ReadAllLines编写此代码,并在内存中使用一系列行,而无需解释如何在循环中使用此代码,您就不会给出问题的解决方案,而且这将大大减少对于非常大的文件非常有效。您总是打印数组的前两个元素!嗯,这肯定是解决这个问题最糟糕的方法。首先,在执行
Count()
时,您放弃了
ReadLines
优于
ReadAllLines
的优点,因为您必须等待整个文件被读取并放入集合中。第二,在每次循环迭代中重新读取整个文件…嗯,我没有考虑性能,因为我以前没有尝试过这种方法,但我不确定是否要重新读取整个文件,以2和跳过2为例,它真的读取了整个文件吗?如果是这样的话,我会重新考虑这一点,并且认为我不确定,
ReadLines
是否只在迭代时读取。你可能就在那里。但是,当您接近文件末尾时,要跳过10000行,您必须先阅读它们,这是没有办法的。然后你想跳过10002行,你必须再次阅读前10000行,以此类推。因此,您必须打开文件
lineCount/2
次,并平均读取
lineCount/2
行(开始时越少,结束时越多)。所有这些,假设,
ReadLine
只在您迭代时读取。@derpirscher您说得对,谢谢。我考虑了性能问题,并用另一种方法编写了代码。只需从文件中读取一次。我认为这种方法更好如果你使用一个数组和一个
来进行
循环,就不需要
跳过
获取
只要通过它们的索引访问值就可以了。ie
myStringArray[i]
myStringArray[i+1]
foreach (var batch in BatchedLinesFromFile(filename, 2))
{
    Console.WriteLine(string.Join(", ", batch));
}
string[] input = File.ReadAllLines([SourcePath]);
int Selector = -1;

string[] output = Enumerable.Repeat(0, input.Length / 2).Select(_ => {
                    Selector += 2;
                    return $"{input[Selector - 1]}  {input[Selector]}";
                }).ToArray();
Sam NYC
Mii Peru
LEO Argentina