标准流

c语言

Unix类Unix系统中,如同某些程式语言介面一样,标准串流是当一个电脑程式执行时,在它和它的环境间(典型为终端),事先连接的输入和输出频道。这三个I/O连结称作“标准输入”、“标准输出”和“标准错误输出”。

背景 编辑

在Unix之前的作业系统,程式必须明确指出连结到合适的输入和输出资料。对这当中的许多系统而言,这牵涉一些错综复杂而又与特定作业系统相关的事,是一件吓人的程式设计挑战。如控制环境设定、存取一个档案表格、决定区域资料集、和决定读卡机、磁带、磁碟、列印机、打卡机或互动式终端机。

Unix 提供许多开创产的进步,其中之一是提供 抽象设备 :它免除了程式须要知道或在意它正与哪个设备沟通。 Unix 借由资料串流的概念来消除这种复杂:一种资料位元组的有序序列,直到读到档案结尾。程式员亦可依需求写入而无须宣告写入多少或如何组织。

另一个 Unix 突破为预设自动连结输入和输出-程式(和程式设计师)不用为了典型输入-处理-输出程式建立输入和输出。相对地,之前作业系统通常要求一些-有时复杂-工作控制语言Job Control Language英语Job Control Language)以建立连结,或者,相者近似于协调的责任。

既然 Unix 提供标准串流,Unix C 的执行环境被要求要支援它。结果不管什么作业系统, C 的执行环境(及 C 的衍生)都提供类似功能。

标准输入 (stdin) 编辑

标准输入是指输入至程式的资料(通常是文件)。程式要求以(read)操作来传输资料。并非所有程式都要求输入。如dirls程式(显示一个目录中的档名)运行时不用任何输入。

除非重导向,输入是预期由 键盘取得的。

标准输入的档案描述子为 0。在POSIX <unistd.h> 的定义是 STDIN_FILENO;相对应的 <stdio.h> 变数为 FILE* stdin ;类似地, <iostream> 变数为 std::cin

标准输出 (stdout) 编辑

标准输出是指程式写输出资料的串流。程式要求资料传输使用的运算。并非所有程式都要求输出。如mvren程式在成功完成时是沉默的。

除非重导向,输出为 终端

标准输出的档案描述子为 1 。POSIX <unistd.h> 定义是 STDOUT_FILENO;相对应的 <stdio.h> 变数为 FILE* stdout ;类似地, <iostream> 变数为 std::cout

标准错误输出 (stderr) 编辑

标准错误输出是另一输出串流,用于输出错误讯息或诊断。它独立于标准输出,且可以分别被重导。常见的目的则为启始这个程式的终端,即使其标准输出被重导亦如此。例如:一个管线中的程式的输出被重导到下一个程式,但错误讯息仍然直接流向文字终端机。

标准输出标准错误输出导到相同的目的地,如文字终端,是可以(且正常)的。讯息会以如同程式写入的顺序来出现,除非使用了缓冲。(例如,一个常见状况是,当标准错误串流未使用缓冲,但标准输出串流使用了缓冲;在这种情况下,如果标准输出的缓冲区还没满的话,较迟写到标准错误的文字可能会较早出现在终端。

标准错误输出的档案描述子为 2 ;POSIX <unistd.h> 定义为 STDERR_FILENO;相对的 <stdio.h> 变数 FILE* stderr。C++ <iostream> 标准表头档提供两个相关的变数: std::cerrstd::clog,前者用于无缓冲的而后者使用和其它 C++ 串流相同的缓冲机制。

大部分程式允许使用

 >& filename

标准输出标准错误输出重导向到相同的档案。

Bourne-类壳程式允许使用

   2>&1

标准错误输出重导向到标准输出的目的。

年表 编辑

1950 年代: Fortran 编辑

Fortran 提供类于 Unix 档案描述子:UNIT=5 用于 stdin 、 UNIT=6 用于 stdout 和 UNIT=0 用于 stderr 。

! FORTRAN 77 example
      PROGRAM MAIN
      READ(UNIT=5,*)NUMBER
      WRITE(UNIT=6,'(F5.3)')' NUMBER IS: ',NUMBER
      END

1960: ALGOL 60 编辑

ALGOL 60因没有标准档案存取而受批评。

1968: ALGOL 68 编辑

ALGOL 68 的输入和输出机制合起来称为 transput 。 Cornelis H. A. Koster英语Cornelis H. A. Koster coordinated the definition of the transput standard. 这标准包含:stand instand outstand errorstand back

范例:

# ALGOL 68 example #
main:(
REAL number;
getf(stand in,($g$,number));
printf(($"Number is: "g(6,4)"OR "$,number)); # OR #
putf(stand out,($" Number is: "g(6,4)"!"$,number));
newline(stand out)
)
输入: 输出:
3.14159
Number is: +3.142 OR Number is: +3.142!

1970 年代: C 和 Unix 编辑

C语言 中,标准输入、标准输出和标准错误输出分别连接到已存的 Unix 档案描述子 0 、1 和 2。

1995: Java 编辑

Java中,标准串流被称为 System.in(标准输入)、System.out(标准输出)和 System.err(标准错误)。

public static void main(String args[]) {
    try {
        BufferedReader br = 
          new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        double number = Double.parseDouble(s);
        System.out.println("Number is:" + number);
    } catch (Exception e) {
        System.err.println("Error:" + e.getMessage());
    }
}

2000s: .NET 编辑

C# 和其它 .NET 语言中,标准串流为 System.Console.In (标准输入)、System.Console.Out (标准输出)和System.Console.Error (标准错误)。stdin 和 stdout 的基本读写能力可以直接透过 System.Console 来存取(如 System.Console.WriteLine() 可以取代 System.Console.Out.WriteLine() )。

注意, System.Console.InSystem.Console.OutSystem.Console.ErrorSystem.IO.TextReader (stdin) 和 System.IO.TextWriter (stdout、stderr) 的对象,只允许存取底层基于文件的标准串流。存取二位元标准串流要分别经由 System.Console.OpenStandardInput()System.Console.OpenStandardOutput()System.Console.OpenStandardError() 所传回的System.IO.Stream

// C# example
public static int Main(string[] args)
{
    try {
        string s = System.Console.In.ReadLine();
        double number = double.Parse(s);
        System.Console.Out.WriteLine("Number is: {0:F3}", number);
        return 0;

    // If Parse() threw an exception
    } catch (System.ArgumentNullException) { 
        System.Console.Error.WriteLine("No number was entered!");
    } catch (System.FormatException) {
        System.Console.Error.WriteLine("The specified value is not a valid number!");
    } catch (System.OverflowException) {
        System.Console.Error.WriteLine("The specified number is too big!");
    }

    return -1;
}
' Visual Basic .NET example

Public Function Main() As Integer
    Dim number As Double
    Dim s As String

    Try
        s = System.Console.In.ReadLine()
        number = CDbl(s)
        System.Console.Out.WriteLine("Number is: {0:F3}", number)
        Return 0
    Catch e As System.InvalidCastException
        ' if CDbl() threw an exception
        System.Console.Error.WriteLine("No number was entered!")
        Return 1
    End Try
End Function

当使用 System.Diagnostics.Process 时,可以使用 StandardInputStandardOutputStandardError 属性来存取程序的标准串流。

Console 并非指 Dos 的命令列视窗。

图形使用者介面 编辑

图形使用者介面很少使用标准串流。 重导图形使用者介面或建立管线是不实用的。 最近似的大概是从一个程式剪下(或复制)再贴到另一个。 既然需要人工使用者的运作,移动大量的贴上就不会特别有效率。 一个值得一提的例外为dwm铺砖式视窗管理器tiling window manager英语tiling window manager),其会将导入标准输入的资料显示到状态列。

一些原本在 Unix 上的图形使用者介面程式仍会写错误讯息到标准错误输出。 其它可能会从标准输入取得档案,如许多 Unix 媒体播放程式。

GTK-Server英语GTK-Server 可以使用标准输入为沟通介面,以便互动式程式能理解图形使用者介面程式。

另见 编辑

参考 编辑

外部链接 编辑