1. 标准输入 标准输出 标准错误输出的认识。
标准输入:表示键盘输入,其实在我看来标准输入就是从键盘上输入字符存储到一个文件中,可称为标准输入文件;
标准输出:表示显示屏,其实就是在程序的控制下将内存中的数据复制一份到标准输出文件;
标准错误输出:输出的设备还是显示屏,从内存中将输出的错误信息复制到标准错误输出文件(仅代表个人理解)。
2. 标准I/O库(stdio.h)中常见输入输出函数的使用。scanf printf scanf_s printf_s gets puts fgets fputs
//操作系统:win10
//开发环境:visual studio 2019 win10 SDK
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int i_var = 0;
float f_var = 0.0;
char c_var = 'a';
char str_var[20] = "hello world";
//格式化输出的本质是将要输出的内容转为字符串写到标准输出文件中,再从标准输出文件推送到显示屏。
printf_s("----> printf output: %d %f %c %s\n", i_var, f_var, c_var, str_var); //格式化输出
printf_s("----> printf_s output: %d %f %c %s\n", i_var, f_var, c_var, str_var); //安全的格式化输出
//格式化输入的本质是从标准输入文件中读取字符序列,遇到'\n'则停止,
//按照格式代码转为相应类型的值,再存储到内存中。
//注意: 除"%c"外,其他的格式控制码满足以下情况:
//1. 输入值前的空白符号(制表符,空格,换行)被跳过
//2. 输入值后的空白符号被看作输入值的结束标记
//以获取整数为例:
//scanf函数从标准输入文件中获取整数形式的字符序列转换为整数 例如:1234'\n' -> 1234
//scanf()返回成功转换的整数数量
printf_s("----> read int by scanf_s ret: %d\n", scanf_s("%d", &i_var));
printf_s("----> read float by scanf_s ret: %d\n", scanf_s("%f", &f_var));
printf_s("----> read char by scanf_s ret: %d\n", scanf_s("%c", &c_var, 1));
printf_s("----> read string by scanf_s ret: %d\n", scanf_s("%s", &str_var, 20));
//遇到'\n'时读取结束,标准输入文件中剩余一个字符'\n'。
printf_s("----> allvalue by scanf_s output: %d,%f,%c,%s len: %d\n", i_var, f_var, c_var, str_var, strlen(str_var));
printf_s("----> ----> ----> ----> ----> ----> ----> ----> ----> ---->\n");
//puts函数自动输出换行符
puts("----> puts output: hello world");
//fputs函数指定标准输出文件对象
fputs("----> fputs output: hello world\n", stdout);
//从标准输入文件中读取一行,保存在内存中,返回内存空间地址。
//1. 一行输入由一串字符组成,以一个'\n'结尾
//2. 遇到EOF时读取结束返回NULL,使用feof()函数检查
//3. 遇到错误时读取结束返回NULL,使用ferror()函数检查
//注意:gets()函数读取没有限制,可以一直读取,如果读取到的内容超过内存空间的限制,则会覆盖内存空间尾部的其他内存,
//所以gets()函数不安全,fgets()函数可以指定内存空间的大小,是安全的函数。
//读取一行,将'\n'转换为'\0'
printf_s("----> gets ret: %p str_var value: %p\n", (const char *)gets(str_var), str_var);
printf_s("----> value by gets output: %s len: %d\n", str_var, strlen(str_var));
//读取一行,在'\n'后加'\0'
printf_s("----> fgets ret: %p str_var value: %p\n", fgets(str_var, 20, stdin), str_var);
printf_s("----> value by fgets output: %s len: %d\n", str_var, strlen(str_var));
while (1);
return EXIT_SUCCESS;
}
//总结:
// scanf_s 遇到'\n'读取结束,不读取'\n';
// gets读取一行,'\n'转'\0';
// fgets()读取一行,在'\n'后加'\0'。
运行截图:
控制台输入:1 1.2 aabcdefg
标准输入文件中的字符序列应该是:1 1.2 aabcdefg'\n'
注意:1到1.2 1.2到aabcdefg之间是由空格的, '\n'是输入完成后按下的回车键对应的字符。
通过scanf_s读取整数 浮点数 字符 字符串后都转换成功了,读取字符串后剩余的'\n'通过gets()函数读取了,‘\n’直接转'\0', 所以gets()函数得到的字符串长度为0。
第二次输入的hello world在标准输入文件中应该是:hello world'\n'
12个字符,fgets()函数读取一行,在'\n'后加'\0',所以最后长度是12。
3. getchar putchar函数的使用。
getchar从标准输入中读取一个字符,遇到文件结束时返回EOF(-1),循环读取字符操作可用于清空标准输入文件。
putchar输出一个字符到标准输出文件。
int main()
{
int c = 0;
//从标准输入中读取一个字符
c = getchar();
//将读取的字符输出到标准输出
putchar(c);
//从标准文件中读取剩余的字符
//所有字符读取完毕后阻塞在getchar()
//应该是返回EOF,但此时标准输入文件没有关闭所以阻塞在getchar()
while ((c = getchar()) != EOF) {
printf("%c", c);
}
while (1)
;
}
4. 字符串处理函数的使用。
int main()
{
char str1[20] = {0};
char str2[20] = "world";
char* str3 = "xinglei";
printf_s("----> str1 size: %d\n", sizeof(str1));
printf_s("----> str2 size: %d\n", sizeof(str2));
printf_s("----> str3 size: %d\n", sizeof(str3));
//strcpy(str1, str3);
strcpy_s(str1, 20, str3);
printf_s("----> strcpy str1: %s\n", str1);
//strncpy(str1, str3, strlen(str3));
strncpy_s(str1, 20, str3, strlen(str3));
printf_s("----> strcpy str1: %s\n", str1);
//strcat(str1, "hello");
strcat_s(str1, 20, "hello");
printf_s("----> strcat_s str1: %s\n", str1);
printf_s("----> strchr h in str1: %p\n", strchr(str1, 'h'));
printf_s("----> strstr h in str1: %p\n", strstr(str1, "xing"));
printf_s("----> strcmp ret: %d\n", strcmp(str1, str2));
printf_s("----> strcmp ret: %d\n", strncmp(str1, str2, 5));
while (1)
;
}