Linux终端输入输出操作示例

Linux或UNIX操作系统中,终端应用程序如cat命令提供了多种数据输入方式。本文将介绍三种主要的输入方法,并展示如何创建一个简单的应用程序makeupper,该程序支持这三种输入方式。

数据输入方式:

  • 通过传递文件名作为参数:
  • cat file.txt
  • 通过进入规范模式:
  • cat

    规范模式是终端输入的一种模式,它按行处理输入。这意味着程序会在输入了新行(CRLF)或文件结束(EOF)字符后读取信息。

  • 通过创建管道连接发送数据到进程(或从中接收):
  • cat file.txt | more

终端输入/输出:

Linux和所有其他UNIX变体(如IBM-AIX)中,从文件读取数据和从终端读取数据之间没有区别,同样地,将数据写入文件和写入屏幕之间也没有区别,特别是当数据仅由字符字符串组成时。

终端提供了三个I/O端口:

  • 标准输入:默认是键盘
  • 标准输出:默认是终端屏幕
  • 标准错误:默认是终端屏幕

有两组函数用于处理这些I/O端口:

  • 低级I/O系统调用:使用文件描述符来访问标准输入、输出和错误。
  • 标准I/O库:使用流,实现为指向FILE*结构的指针(#include )。

示例代码:

以下是一个名为test.c的简单应用程序的源代码,它展示了如何使用低级系统调用和标准I/O库函数将字符串打印到终端屏幕(标准输出)。

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int _argc, char *_argv[]) { char *ptr = "This is an output test!\n"; printf(ptr); fprintf(stdout, ptr); write(1, ptr, strlen(ptr)); return 0; }

要使用C编译器构建test.c

cc -o test test.c

执行./test后,将看到以下输出:

"这是一个输出测试!" 这个字符串通过三种不同的函数打印到屏幕上:

  • printf:标准I/O库的一部分,它默认总是将字符串打印到标准输出。
  • fprintf:标准I/O库的一部分。注意第一个参数stdout流重定向ptr字符串到标准输出(或屏幕)。
  • write:低级系统调用。注意第一个参数1,它是标准输出的文件描述符。

makeupper 示例:

源代码中还有两个示例:makeupper.cmakeupper2.c。它们做同样的事情,但区别在于makeupper.c使用低级系统调用,而makeupper2.c使用标准I/O库。

makeupper示例非常简单。它的目的是将输入数据中的字母大写并打印到标准输出。然而,它也展示了如何从标准输入和文件中读取。第一个示例makeupper.c使用低级系统调用:

/* Makeupper.c */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> int main(int _argc, char *_argv[]) { int fd_main = 0; char ch = 0; fd_main = _argc == 1 ? 0 : open(_argv[1], O_RDONLY); if (fd_main == -1) { perror("input"); exit(-1); } while (read(fd_main, &ch, 1)) { ch = toupper(ch); write(1, &ch, 1); } close(fd_main); return 0; }

注意读取的行:

fd_main = _argc == 1 ? 0 : open(_argv[1], O_RDONLY);

如果没有传递文件路径参数,则fd_main假设标准输入描述符。当作为参数传递时,使用open系统调用打开文件。

makeupper2.c使用标准I/O库函数代替系统调用:

/* Makeupper2.c */ #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int _argc, char *_argv[]) { FILE *f_file = NULL; char ch = 0; f_file = _argc == 1 ? stdin : fopen(_argv[1], "r"); if (f_file == NULL) { perror("input"); exit(-1); } while (!feof(f_file)) if ((ch = fgetc(f_file)) > 0) fputc(toupper(ch), stdout); fclose(f_file); return 0; }

要构建这两个示例:

cc -o makeupper makeupper.c cc -o makeupper2 makeupper2.c

执行./makeupper(或./makeupper2)不带参数时,它将启动规范模式。在按下回车键后,makeupper接收该行。要退出规范模式,应该按CTRL+D或CTRL+\:

也可以传递文件路径:

或者makeupper可以从进程的标准输入中接收输出:

重定向I/O:

可以将标准输出和错误重定向到文件或设备(/dev/...)。为了说明这一点,键入并编译以下代码(可以将其命名为test2.c):

#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int _argc, char *_argv[]) { char *p1 = "printed to standard output via stdlib.\n"; char *p2 = "printed to standard error via stdlib.\n"; char *p3 = "printed to standard output via low-level calls.\n"; char *p4 = "printed to standard error low-level calls.\n"; fprintf(stdout, p1); fprintf(stderr, p2); write(1, p3, strlen(p3)); write(2, p4, strlen(p4)); return 0; }

有四个字符串分别指向四个指针。p1p3被打印到标准输出,p2p4被打印到标准错误。

要构建它:

cc -o test2 test2.c

执行./test2,有:

  • ./test2 - 将看到所有字符串都打印到屏幕上。
  • ./test2 >file.txt - 将标准输出重定向到file.txt。注意只有p1和p3字符串被保存在file.txt中。
  • ./test2 2>file.txt - 将标准错误重定向到file.txt。注意只有p2和p4字符串被保存在file.txt中。
  • ./test2 >file.txt 2>&1 - 将输出和错误都重定向到file.txt。注意技巧2>&1(意味着将标准错误重定向到标准输出)。

如果想要追加到现有文件:

  • ./test2 >>file.txt
  • 或./test2 >>file.txt 2>&1。

希望这对有帮助。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485