`
lobin
  • 浏览: 425777 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

C 第2100章: 标准输入输出

 
阅读更多

标准输入输出通常指的是控制台输入输出,也就是屏幕显示输入输出。

 

标准输入输出

标准输入输出最简单的方式就是通过scanf,printf进行输入输出。调用scanf后,程序将提示用户进行输入。调用printf后,将在控制台上打印输出的内容。

 

标准输入输出实际上有3中。一个就是标准输入,一个就是标准输出,还有一个就是标准错误输出,当然这个也属于标准输出。标准输入就是我们所说的stdin,标准输出就是stdout,标准错误输出就是stderr。后面将详细讲stdin,stdout,stderr这几个标准输入输出。

 

除了scanf,printf这两个标准函数外,标准库中还提供了大量的标准输入输出相关的标准函数。标准库中提供的文件相关的函数也可以实现标准输入输出一样的功能。

 

 

输出

int printf(const char *format, ...);

int snprintf(char *s, size_t n, const char *format, ...);

int sprintf(char *str, const char *format, ...);

int vprintf(const char *format, va_list arg);

int vsnprintf(char *s, size_t n, const char *format, va_list arg);

int vsprintf(char *s, const char *format, va_list arg);

 

输出格式

%[flags][width][.precision][length]specifier

 

format specifier

 

sub-specifiers

 

.precision

 

在使用%s打印字符串的时候,如果字符串没有加上结束符,打印的时候可能会一直打印输出,直到后面可能出现的结束符,这时候可能已经溢出,可能会打印出乱码。因为字符串是以结束符为标志的,打印也是这样。针对这种字符串没有加上结束符,打印时可以指定输出的字符个数。

 

.number

例子:

snprintf(label, 11, "%.11s", offset(p, 43));

 

.*

这种情况没有在specifier中指定precision,可以在需要打印的字符串参数之前指定输出的字符个数。

例子:

fprintf(stdout, "file: %.*s, args: a=%d, ha=%d, cd: %s\n", len, file, a, ha, current_directory);

这里在输出file时只输出len个字符。

 

标准输出

 

回车换行

我们平常在键入“Enter”的时候,会换到下一行,其实包括回车和换行两个操作,回车和换行对应CRLF中的CR和LF,是两个特殊字符。这两个操作其实是不一样的,回车会将光标定位到行的最开始位置。换行会将光标定位到下一行的和当前光标所处列的同一列的位置。

 

回车和换行(CR和LF)在C语言中对应字符'\r'和‘\n’。字符对应的数字为13(0x0d, 8进制为015)和10(0x0a, 8进制为012)。

 

换行

在C语言中,如果要在输出后换到下一行,可以这样:

printf("this is key2: %s\n", "key2");

其中\n表示换行。

 

上面是我们的正常写法。

 

再看下面的写法:

printf("this is key6: %s\r\n", "key6");

其中\r表示回车。

 

这两种写法运行效果是一样的。但从字符串的定义上,这两种写法其实是不一样的,前者是字符串后面跟个换行,后者是字符串后面跟着回车在加上换行。

 

对于前者,系统在输出时,对于这种情况,会加上一个回车操作。

 

下面是linux下gcc编译的结果:

.LC1:

.string"this is key2: %s\n"

.LC7:

.string"this is key6: %s\r\n"

 

下面是windows  cygwin下gcc编译的结果:

LC2:

.ascii "this is key2: %s\12\0"

LC8:

.ascii "this is key6: %s\15\12\0"

不同环境下编译的结果不一样。linux下编译的结果很好理解,对于windows  cygwin下gcc编译的结果,\15\12其中\15表示回车,\12表示换行。这个是as下.ascii定义字符串的一种写法,使用.string方式也支持这种写法。

 

 

 

中文处理

 

输出中文

前面将输出的时候都是输出英文字母。这里将讲中文文字的输出。

之前输出的时候,一个最简单的printf的例子

printf("hello");

那么通过printf可以输出中文文字吗?

printf("你好");

这样是可以的。不过得注意一些问题。

如果程序中包含中文或者其他文字的话,程序文件首先会出现乱码。所以需要注意文件编码问题。

在输出中文的时候,也会因为编码问题导致无法输出中文。

 

在windows下创建一个C程序文件,代码如下

#include <stdio.h>

int main() 
{
  printf("%s\n", "中文");
  return 0;
}

在windows下的CYGWIN环境通过gcc编译后运行结果如下

>.\test

▒▒▒▒

无法输出中文文字。

我们到linux下去编译运行,也是无法输出中文文字。

# ./test 

 

אτ

通过VC编译的话,运行是没有问题的

>cl test.c

>.\test

中文

这是因为在windows下,创建C程序文件时,其文件编码为ISO-8859编码。可以通过file命令查看下test.c程序文件文件编码格式。

>file test.c

test.c: C source, ISO-8859 text, with CRLF line terminators

可以看到其文件编码为ISO-8859编码。

 

可以将文件编码为UTF-8编码,windows下具体操作就是另存为,在保存的时候选择文件编码为UTF-8编码。

我们可以再通过file命令查看下test.c程序文件文件编码格式。

>file test.c

 

test.c: C source, UTF-8 Unicode text, with CRLF line terminators

可以看到现在的文件编码为UTF-8编码。

再次编译后运行结果如下

>.\test

中文

 

这只是个简单的例子,只有一个源程序文件。实际编程的时候大量的程序文件不可能这么一个个全部将其文件编码格式转换为UTF-8编码。

还是以上面的例子。

>file test.c

 

test.c: C source, ISO-8859 text, with CRLF line terminators

现在是ISO-8859编码。这个时候编译后运行是无法显示中文文字的。

>.\test

▒▒▒▒

这个时候可以在编译的时候指定-finput-charset选项为GBK

>gcc -finput-charset=GBK test.c -o test

>.\test

中文

这样运行的时候就可以显示中文文字了。

 

 

 

输入

上面提到,标准输入最简单的方式就是通过scanf来实现。

scanf

函数原型

int scanf ( const char * format, ... );

调用scanf函数后程序将等待标准IO输入,当然这里也不一定,如果输入缓存中还有缓存的数据,将会从输入缓存中继续接收,如果输入缓存中有足够的数据接收,调用scanf函数后程序将不会等待标准IO输入,而是直接从缓存中接收后继续执行,如果从输入缓存中接收完后还有接收项需要继续接收,将等待标准IO输入等待接受。当接收到回车键后结束输入。输入中通过空格来分割的每个输入项匹配format中的每个接收项。

 

如果输入中通过空格来分割的输入项多于format中的接收项,按format中的接收项进行匹配接收的输入项,多余的输入项不接收,仍保留在输入缓冲区中。在后面从标准输入接收时将还可以接收到,比如在后面通过scanf接收输入时将还可以接收到。

 

标准函数scanf有一个很重要的format参数。这个参数将对应的输入项按照指定的格式格式化写入到对应参数指定的内存中。

 

输入格式

 

%[*][width][length]specifier 

 

比如

int i;

scanf("%d", &i);

如果输入123,将会将123以int整型类型写入到对应的i变量指定的内存中。这样i的值就是123,相当于给i赋值123,输出i的值就是123。

 

如果输入123 456 789,同样也会将123以int整型类型写入到对应的i变量指定的内存中。这样i的值就是123,相当于给i赋值123,输出i的值就是123。由于这里只接收一个输入项,后面的456 789将不会被接收,仍留在输入缓存中。

 

字符串

输入字符串

由于内存中通过一段连续的内存来表示存储字符串,并且针对输出的时候,根据终结符0(在字符串中通过\0表示)来表示字符串的结束。

#include <stdio.h>

int main()
{
  char input[10];
  scanf("%s", input);

  printf("input: \n%s\n", input);
  return 0;
}

在上面的例子中,通过scanf输入字符串来接收字符串,在输入的时候由于可以输入任意多个字符的字符串,再按下回车键结束输入,当输入的字符串长度大于接收的分配的用于存储字符串的大小,可能会导致程序错误:

>.\scanf_test2

aaaaaaaaaaaaaaaaaaaaaa

input:

aaaaaaaaaaaaaaaaaaaaaa

      3 [main] scanf_test2 6032 open_stackdumpfile: Dumping stack trac

 

e to scanf_test2.exe.stackdump

就算是没有报上面的错误,在上面的例子中,是在栈中分配用于存储字符串的连续内存,由于输入的字符串长度大于接收的分配的用于存储字符串的大小,将导致内存溢出。内存溢出可能导致程序崩溃,这里还可能会导致覆盖后面内存的内容,导致程序的错误结果。

 

正确的做法:

#include <stdio.h>
#include <string.h>

int main()
{
  char input[10];
  memset(input, 0, sizeof(input));
  scanf("%9s", input);

  printf("input: \n%s\n", input);
  return 0;
}

对于需要接收比如像控制台输入的命令,或者接收任意长的字符串,可以通过fgets。

 

如:

# netstat -nptl | grep 22

输入字符串中包括空格

 

如:

# echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > out

输入字符串很长

 

 

int getchar ( void );

char * gets ( char * str );

 

 

fgets

函数原型

char * fgets ( char * str, int num, FILE * stream );

#include <stdio.h>

int main()
{
  char input[50];
  fgets(input, sizeof(input), stdin);

  printf("input: \n%s\n", input);
  return 0;
}

 

 

 

标准输入输出定义

/* Standard streams.  */
extern struct _IO_FILE *stdin;          /* Standard input stream.  */
extern struct _IO_FILE *stdout;         /* Standard output stream.  */
extern struct _IO_FILE *stderr;         /* Standard error output stream.  */
#ifdef __STDC__
/* C89/C99 say they're macros.  Make them happy.  */
#define stdin stdin
#define stdout stdout
#define stderr stderr
#endif

 

宽字符输入输出

 

宽字符输出

#include <locale.h>
#include <wchar.h>

int main() 
{
  wchar_t wstr[] = L"中文:1到9的数字,a到z的字母";
  setlocale(LC_ALL, "zh_CN.utf8");

  wprintf(L"%ld\n", sizeof(wstr) / sizeof(wchar_t));
  wprintf(L"%ls\n", wstr);
  return 0;
}

遍历

#include <locale.h>
#include <wchar.h>

int main() 
{
  wchar_t wstr[] = L"中文:1到9的数字,a到z的字母";
  wchar_t *ptr;
  setlocale(LC_ALL, "zh_CN.utf8");

  for (ptr = wstr; *ptr; ptr++)
  {
    wprintf(L"%lc\n", *ptr);
  }
  return 0;
}

 

 

宽字符输入

 

 

 

 

0
0
分享到:
评论

相关推荐

    C语言标准输入输出函数大全

    本文将深入解析C语言标准输入输出函数,特别是格式化输入输出函数printf()和scanf(),以及它们在TurboC2.0环境下的应用。 ### 1.1 标准输入输出函数 #### 1.1.1 格式化输入输出函数 **printf()函数**是格式化输出...

    C语言程序设计:数据的输入输出.ppt

    C语言程序设计:数据的输入输出.ppt

    计算机组成原理(第2版):第5章 输入输出系统.ppt

    计算机组成原理(第2版):第5章 输入输出系统.ppt

    c语言-输出格式输出提取出来的数字字符串,每个连续数字字符串占一行

    #c语言#的问题:输出格式输出提取出来的数字字符串,每个连续数字字符串占一行(相关搜索:字符串长度|输入字符串 #c语言#的问题:输出格式输出提取出来的数字字符串,每个连续数字字符串占一行(相关搜索:字符串...

    C语言标准输入输出scanf

    标题:C语言标准输入输出scanf 描述:C语言标准输入输出,较为详尽的介绍相关的操作 知识点: 一、标准输入输出函数 在C语言中,标准输入输出是程序员经常使用的功能之一,它允许程序从标准输入设备(通常是键盘...

    C语言课件:第三章 数据输入与输出 .ppt

    《C语言中的数据输入与输出》 在C语言编程中,数据的输入与输出是程序与用户交互的基础。本章将深入探讨C语言中的数据输出和输入方法。 首先,我们来看数据的输出。C语言中并没有专门的I/O语句,而是通过函数来...

    C语言程序设计:第六部分 输入输出与格式控制.ppt

    C语言程序设计:第六部分 输入输出与格式控制.ppt

    2022年计算机二级考试Java入门教程:Java输入输出操作.docx

    Java 输入输出操作 Java 输入输出流是 Java 语言中...Java 语言提供了多种方式来实现文件输入输出操作,包括标准输入输出和文件输入输出。这些方式可以用来实现各种文件操作,例如读取文件、写入文件、测试文件等。

    第11章 标准输入输出.pdf

    根据提供的文件信息,本章主要围绕“标准输入输出”这一主题展开讨论,涉及了标准输入输出的基本操作、非格式化输入输出以及格式化输入输出等内容。以下是对这些知识点的详细阐述: ### 11.1 标准输入输出的基本...

    Java程序设计基础:控制台输入输出.pptx

    Java的标准输入输出流 System.out 表示Java标准输出流,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。 System.out.println(" Welcome to Java!"); System.in 表示Java标准输入流,此流对应于键盘...

    C语言程序设计:第3章 基本运算与输入输出

    在C语言程序设计中,第三章主要探讨了基本运算与输入输出的相关概念。这一章分为多个部分,包括运算符与表达式概述、数据对象的存取、基本数值运算、其他常用运算以及输入与输出。 首先,我们来看运算符与表达式。...

    c语言第一讲:c基础

    本篇文章将围绕“C语言第一讲:C基础”这一主题进行展开,详细介绍C语言的基础概念、数据类型、运算符以及输入输出函数等关键知识点。 #### C语言简介 C语言是一种结构化编程语言,它最早由丹尼斯·里奇(Dennis ...

    C语言输入输出格式

    C语言本身并不直接提供输入输出语句,而是通过C标准函数库中的函数来实现这些功能。其中,最常用的两个函数是`printf()`用于输出,`scanf()`用于输入。 #### 三、格式化输出函数printf() `printf()`函数允许开发者...

    Java 语言程序设计:第6章输入输出流和文件.ppt

    Java 语言程序设计:第6章输入输出流和文件.ppt

    C++第3章简单的输入输出ppt课件.ppt

    C++ 第3章 简单的输入输出 C++ 中的输入输出是通过流(Stream)来实现的。流是 C++ 中执行输入和输出的设施。C++ 预定义了四个流所连接的具体设备:cin、cout、cerr 和 clog。 1. cin:与标准输入设备相关联,用于...

    linux系统编程《Linux System Programming》

    第3章:缓冲输入输出 第4章:高级文件I/O 第5章:进程管理 第6章:高级进程管理 第7章:文件与目录管理 第8章:内存管理 第9章:信号 第10章:时间 附录 A GCC对C语言的扩展 附录 B 参考书目 **********************...

    谭浩强C语言课件 第10章 对文件的输入输出

    谭浩强C语言课件 第10章 对文件的输入输出

    掌握C语言的基石:标准I/O库使用指南

    ### 掌握C语言的基石:标准I/O库使用指南 C语言作为一种高效且灵活的编程语言,在软件开发领域有着举足轻重的地位。它的强大之处不仅在于其基础语法的简洁性和高效性,还在于其丰富的标准库支持,尤其是标准输入...

    C语言课件:第四章 数据的输入和输出.ppt

    C语言课件:第四章 数据的输入和输出.ppt

    c语言中文件的输入输出

    ### C语言中文件的输入输出知识点详解 #### 一、文件基本概念与分类 - **文件定义**: 在C语言中,文件通常指的是存储在外部介质(例如磁盘、磁带等)上的数据集合。 - **操作系统管理**: 操作系统以文件为单位对...

Global site tag (gtag.js) - Google Analytics