实践出真知 || 为什么C#代码中写了Console.Read();控制台窗口仍然闪退?

本篇博客的诞生,还要从一次用C#递推斐波那契数列相关问题开始,引发思考的错误代码如下:

using System;
namespace Work2_1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("需要计算的前多少个斐波那契? ");
            int n = Console.Read();
            Fib(n);
            Console.Read();
        }
        
        private static void Fib(int n)
        {
            int a = 1, b = 1, c = 0, i;
            Console.Write("{0}\t{1}\t", a, b); //每8个字符输出一个数
            for (i = 3; i <= n; i++)
            {
                c = a + b;
                Console.Write("{0}\t", c);
                if (i % 5 == 0) //要求每行输出5个斐波那契数
                {
                    Console.WriteLine();
                }
                a = b; b = c;
            }
        }
    }
}

初学C#时照猫画虎,为了挽留控制台窗口驻足一会,自然而然地遵循课本的经验,像往常一样在Main()方法最后写上Console.Read(),遗憾的是它还是闪退了。

于是,在最后一句代码处加个断点,强行扣留一下,观察发现它还溢出了。
在这里插入图片描述
寻思了一下,又瞅瞅代码,发现了和之前敲的例题代码不一样的地方:

int n = Console.Read();

啊,难怪不让我多看两眼控制台,传的数据类型对不上呀,C#与C进行文本输入是不同的:

C#:使用Cosole.ReadLine()接收的是键入的字符串,需要配合Parse()方法,转换成需要使用的数据类型。比如:

string s = Console.ReadLine();
int a = int.Parse(s);   //之后才可以使用希望得到的a中的数据。

C:使用库函数scanf(),自动将键入的数据转化成与变量对应的数据类型。比如:

int a; 
scanf("%d", &a);   //后续直接使用a中的数据即可。

补充:同样是面向对象编程的Java代码也和C#差不多复杂,需要使用其他方法转换类型,比如:

Scanner sc = new Scanner(System.in); 
int a = sc.nextInt(); 

经过一番思考,稍稍一改就可以产出正确代码,得到正确的输出:

static void Main(string[] args)
{
	Console.Write("需要计算的前多少个斐波那契? ");
    string sline = Console.ReadLine();
    int n = int.Parse(sline);
    Fib(n);
    Console.Read();
}

在这里插入图片描述

PS: 为什么 int n = Console.Read(); 编译不报错呢?

先来看方法的声明 public static int Read ();
返回值类型与变量 n 的类型一致,自然不会编译出错。
该方法的作用是从标准输入流读取下一个字符,如果当前没有更多的字符可供读取,则为-1。
当 Read 你键入输入字符时,方法会阻止其返回; 当按下键时,该方法将终止 Enter 。
按 Enter 会将与平台相关的行终止序列附加到输入 (例如,Windows 会将回车换行符序列附加) 。
【C#官方文档】https://docs.microsoft.com/zh-cn/dotnet/api/system.console.read?view=netcore-3.1.
看过一波官方文档后,发现ReadKey()方法才是为暂停看控制台窗口量身定制的,Read()只是恰好效果相同。
ReadKey()方法的最常见用途之一 ,是在用户按下某个键(就像C语言程序运行完成后提示的“请按任意键继续…”)时暂停程序执行,然后应用终止或显示其他信息窗口。

[题外话]:
char可以被int兼容,就隐式转换了,至于转换成什么,目前不太清楚,搜索一番后发现有人说这样读写是错乱了很多东西,输出的是不可预知的乱码,里面包含有各种控制符,难怪最后的ReadLine()不生效。
推荐参考如下博客思考一下char和int类型转换问题:
https://bbs.csdn.net/topics/391886193.
https://blog.csdn.net/alex4chan/article/details/5771620?utm_medium=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase.

continue…


版权声明:本文为qq_44641482原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。