【问题标题】:C# Display loop iteration on single line in consoleC# 在控制台中单行显示循环迭代
【发布时间】:2017-06-30 12:06:42
【问题描述】:

所以我使用 for 循环循环遍历 excel 电子表格中的所有行,我可以通过使用“i”定义非常轻松地显示当前行号,但是它打印在多行上,因为每个迭代都使用控制台显示.WriteLine() 命令。

我希望它只显示一次,并让它在一行上显示更新的迭代。这是我当前的代码:

void DeleteCells(string filePath)
    {

        int currRowNumber = 0;


        // create excel-instance:
        Application excel = new Application();
        // open the concrete file:
        Workbook excelWorkbook = excel.Workbooks.Open(@filePath);
        // select worksheet. NOT zero-based!!:
        _Worksheet excelWorkbookWorksheet = excelWorkbook.ActiveSheet;

        if(isclosing)
        {
            closeProgram(excel, excelWorkbook);
        }

        int numRows = excelWorkbookWorksheet.UsedRange.Rows.Count;
        Console.WriteLine("Number of rows: " + numRows);
        Console.Write("Checking Row #: " + currRowNumber);


        int numRowsDeleted = 0;
        int nullCounter = 0;
        //for (int j = 1; j <=)

        for (int i = 1; i < numRows + 4; i++)
        {
            //We want to skip every row that is null and continue looping until we have more than 3 rows in a row that are null, then break
            if (i > 1)
            {
                i -= 1;
            }

            //Create Worksheet Range
            Microsoft.Office.Interop.Excel.Range range = (Microsoft.Office.Interop.Excel.Range)excelWorkbookWorksheet.Cells[i, 2];
            string cellValue = Convert.ToString(range.Value);

            if (nullCounter == 5)
            {
                Console.WriteLine("Null row detected...breaking");
                Console.WriteLine("Number of rows deleted: " + numRowsDeleted);
                break;
            }

            if (cellValue != null)
            {
                if (cellValue.Contains("MESSAGE NOT CONFIGURED"))
                {
                    //Console.WriteLine("Deleting Row: " + Convert.ToString(cellValue));
                    ((Range)excelWorkbookWorksheet.Rows[i]).Delete(XlDeleteShiftDirection.xlShiftUp);
                    numRowsDeleted++;
                    //Console.WriteLine("Number of rows deleted: " + numRowsDeleted);
                    nullCounter = 0;
                    i--;
                    currRowNumber++;
                }
                else
                {
                    currRowNumber++;
                    nullCounter = 0;
                }
            }
            else
            {
                nullCounter++;
                //Console.WriteLine("NullCounter: " + nullCounter);
            }
            i++;

        }

        Console.WriteLine("Fixes Finished! Please check your excel file for correctness");

        closeProgram(excel, excelWorkbook);
    }

样本输出:

Row Number: 1
Row Number: 2
Row Number: 3
Row Number: 4
Row Number: 5

等等。

我希望它只显示一行并不断更新行号。我该怎么做呢?任何帮助表示赞赏。谢谢。

更新: 所以我有以下循环:

for (int i = 1; i < numRows + 2; i++) //numRows was +4, now +2
        {

            Console.Clear();

            Console.WriteLine("Number of rows: " + numRows);
            Console.Write("Checking Row #: " + currRowNumber);

            //We want to skip every row that is null and continue looping until we have more than 3 rows in a row that are null, then break
            if (i > 1)
            {
                i -= 1;
            }

            //Create Worksheet Range
            Microsoft.Office.Interop.Excel.Range range = (Microsoft.Office.Interop.Excel.Range)excelWorkbookWorksheet.Cells[i, 2];
            string cellValue = Convert.ToString(range.Value);

            if (nullCounter == 3) //was 5
            {
                Console.WriteLine("\nNull row detected...breaking");
                Console.WriteLine("Number of rows deleted: " + numRowsDeleted);
                break;
            }

            if (cellValue != null)
            {
                if (cellValue.Contains(searchText))
                {
                    //Console.WriteLine("Deleting Row: " + Convert.ToString(cellValue));
                    ((Range)excelWorkbookWorksheet.Rows[i]).Delete(XlDeleteShiftDirection.xlShiftUp);
                    numRowsDeleted++;
                    //Console.WriteLine("Number of rows deleted: " + numRowsDeleted);
                    nullCounter = 0;
                    i--;
                    currRowNumber++;
                    rowsPerSecond = i;
                }
                else
                {
                    currRowNumber++;
                    nullCounter = 0;
                }
            }
            else
            {
                nullCounter++;
                //Console.WriteLine("NullCounter: " + nullCounter);
            }
            i++;

        }

我想计算每秒循环通过多少行,然后根据有多少行从该数字计算完成整个循环需要多长时间。

再次感谢任何帮助,谢谢!

【问题讨论】:

  • Console.Write( 而不是 Console.WriteLine(
  • 这是一个如此简单的修复,我不敢相信我没有想到它。谢谢大家!
  • 新问题不同,所以你应该为它创建一个新问题!
  • 检查此链接第一个答案。它为我工作*.com/a/8946847/2629117

标签: c# loops for-loop


【解决方案1】:

在每个循环圈上,在打印输出之前使用Clear() 方法:

Console.Clear();

【讨论】:

    【解决方案2】:

    你可以这样做:

    const int ConsoleWidth = 80;
    for(int i = 0; i < 10; i++)
    {
        // pull cursor to the start of the line, delete it with spaces
        // then pull it back again
        for(int j = 0; j < ConsoleWidth; j++) Console.Write("\b");
        for(int j = 0; j < ConsoleWidth; j++) Console.Write(" ");
        for(int j = 0; j < ConsoleWidth; j++) Console.Write("\b");
    
        Console.Write("Row Number: {0}", i);
    
    }
    

    【讨论】:

    • 解决了问题的第一部分,现在我需要计算完成循环需要多长时间。我更新了问题。
    【解决方案3】:

    如果你这样做

    Console.Write("Row Number: {0}", i);
    

    它会一直附加在前面的文本前面。 如果你这样做了

    Console.Clear();
    

    您打算在此文本之前写的任何消息都会消失。 如果您知道文本的确切位置,您可以尝试在控制台中将该位置的文本修改为:

    // First time write
    Console.WriteLine("Row Number: {0}", i);
    
    // x,y coordinates in the method for later iterations
    Console.SetCursorPosition(11, 0);
    Console.Write(i);
    

    【讨论】:

    • 解决了问题的第一部分,现在我需要计算完成循环需要多长时间。我更新了问题。
    【解决方案4】:

    如果行中的文本量永远不会减少(例如,因为数字只会变大),您可以使用 Console.Write() 并在文本前加上 \r 前缀:

    for (int i = 0; i < 100000; ++i)
        Console.Write($"\rRow Number: {i}");
    
    Console.WriteLine();
    

    如果由于数字变小而导致文本长度减少,您可以使用格式化字符串输出左对齐的数字,并带有额外的空格,这将覆盖额外的数字:

    for (int i = 100000; i >= 0; --i)
        Console.Write($"\rRow Number: {i, -6}");
    
    Console.WriteLine();
    

    这样做的好处是您可以在控制台中保留任何以前的文本并且只更新单行。与每次迭代清除整个显示相比,这也使其更快。

    【讨论】:

    • 解决了问题的第一部分,现在我需要计算完成循环需要多长时间。我更新了问题。
    【解决方案5】:

    尝试在 Console.Write 之前使用 Console.SetCursorPosition

    【讨论】:

      【解决方案6】:

      你可以按照前面的答案建议,这是另一种方法。

       int line = Console.CursorTop;
       int len = new String("Row Number: ").length;
       Console.WriteLine("Row Number: ");
       for(your loop)
       {
        Console.WriteLine(i);
        //Print whatever else you want!
        Console.SetCursorPosition(len,line);
       }
      

      这种方法的优点是位置会被记住,并且您可以在向用户显示任何其他信息后返回到相同的位置,这在更新一个充满文本的屏幕中的单个字符时很有用!

      要回答下一个问题,请使用

      Stopwatch s = new Stopwatch();
      long millis =0,avg;
      for(int i=0;i<loopLength;i++)
      {
       s.Start();
       //Do work
       s.Stop();
       millis += s.ElapsedMilliseconds;
      avg = millis/(i+1);
       Console.WriteLine("Time remaining :" + (TimeSpan.FromMilliseconds(avg*(loopLength - (i+1))).Seconds);
      }
      

      【讨论】:

      • 解决了问题的第一部分,现在我需要计算完成循环需要多长时间。我更新了问题。
      • 编辑了答案@IgnitionK6