目录
前言
为了让程序和用户进行交互,这一节我们来学习一些有关字符与字符串以及其他数据类型重要的输入输出函数,比如下面一些函数。
printf: 这是一个标准的C库函数,用于打印格式化的输出到 stdout(屏幕)。
scanf: 这也是一个标准的C库函数,用于从 stdin(键盘)读取格式化的输入。
putchar: 这个函数用于输出一个字符到 stdout。
getchar: 这个函数用于从 stdin 读取一个字符。
_getch: 这个函数在非 Windows 系统上不可用,无回显的从键盘获取一个字符。
puts: 这个函数用于输出一个字符串到 stdout。
fgets: 这是一个更安全且更通用的替代 gets 的函数。它从指定的流中读取一行,直到遇到换行符或读取到指定数量的字符后停止。
一、printf函数
printf函数可以输出打印一个字符串到屏幕上,比如如下程序
#include <stdio.h>
int main()
{
printf("我在树上摘了5个苹果!");
return 0;
}
那么上面代码编译运行后会在屏幕上打印:我在树上摘了5个苹果!
如果继续下面的代码
#include <stdio.h>
int main()
{
int n = 10;
printf("我在树上摘了n个苹果!");
return 0;
}
上面代码编译运行后会在屏幕上打印:我在树上摘了n个苹果!
如果我想将n的变量值打印出来,就要用到下面讲到的格式化输出了。先看如下代码
#include <stdio.h>
int main()
{
int n = 10;
printf("我在树上摘了%d个苹果!", n);
return 0;
}
上面代码编译运行后会在屏幕上打印:我在树上摘了10个苹果!首先printf的函数原型是
_Check_return_opt_
_CRT_STDIO_INLINE int __CRTDECL printf(
_In_z_ _Printf_format_string_ char const* const _Format,
...)
简化用法即是: printf("格式化字符串",参数列表)
上面代码格式化字符串中的%d是格式控制符,n是参数列表中的一个,后面的参数列表可以传递各种各样的数据,称为参数。参数和字符串中的格式控制符是一一匹配的。参数列表中的参数,可以有任意多个,可以是常量,也可以是变量,但是需要和格式字符串中的控制符匹配上,把匹配到的参数替换到相应的格式控制符的位置打印出来。
比如:printf("今天星期%d,我想去吃%s", 4, "肯德基");
打印出来就是今天星期四,我想去吃肯德基
二、格式字符
格式控制符都是以%号开头的,输出时对不同类型的数据要使用不同的格式字符,对应关系如下所示:
另外附加的格式有
以下是代码示例
#include <stdio.h>
int main()
{
int a = 100;
printf("a = %d\n", a);//格式化输出一个字符串
printf("%p\n", &a);//输出变量a在内存中的地址编号
printf("%%d\n");
long a2 = 100;
printf("%ld, %lx, %lo\n", a2, a2, a2);
long long a3 = 1000;
printf("%lld, %llx, %llo\n", a3, a3, a3);
int abc = 10;
printf("abc = '%6d'\n", abc);
printf("abc = '%-6d'\n", abc);
printf("abc = '%06d'\n", abc);
printf("abc = '%-06d'\n", abc);
double d = 12.3;
printf("d = \' %-10.3lf \'\n", d);
return 0;
}
三、转义字符
C语言中还有一些字符并不是能够用字符表示的,比如说回车,响铃等,我们需要使用反斜杠+符号的方式来表示他们。以下是常见的转义字符,假如你无法记住的话,那么就先记住一个换行符,其他的慢慢掌握就行。
以下为代码示例:
#include <stdio.h>
int main()
{
printf("abc");
printf("\refg\n"); //\r切换到句首, \n为换行键
printf("abc");
printf("\befg\n");//\b为退格键, \n为换行键
printf("%d\n", '\123');// '\123'为8进制转义字符,0123对应10进制数为83
printf("%d\n", '\x23');// '\x23'为16进制转义字符,0x23对应10进制数为35
return 0;
}
四、scanf 函数与 scanf_s 函数
程序与用户的交互是一个基本功能,不能只是输出信息,也得需要用户输入信息,那么如何才能够让程序的使用者从键盘给程序传递信息呢?就可以使用 scanf或者scanf_s函数。
4.1 基本用法
用法如下所示:
scanf("格式化字符串", 参数列表)
和 printf 的用法差不多,它的功能是将键盘上输入的内容,按照格式化字符串中的格式,传递到参数列表的参数中。注意:在vs 上默认只能使用 sacanf_s 函数,scanf 是禁用不安全的,不过他们俩用法类似。
以下是代码使用示例
#include <stdio.h>
int main(){
int nNum = 0;
scanf("%d", &nNum);
printf("%d\n", nNum*2);
return 0;
}
当程序运行到 scanf 的时候,会停住,等待用户从键盘上输入数字,输入完毕,点击回车后,程序才会继续执行,此时从键盘上输入的数字就被存储到 nNum中了。需要注意到,nNum 的前面有一个&符号,这个符号叫做取地址符。这个符号非常的重要,这里需要先理解一下地址的概念。
我们的程序是运行在内存中的,内存中存储了程序运行所需要的代码和数据。内存中的存储以字节为单位,每一个字节都有一个编号,这个编号就是地址。每一个变量在定义的时候,其实就是要求操作系统分配一块空间给程序,比如:int a;看似是定义一个变量,实际上是要求系统分配了4个字节的内存。并且用a这个名字代表这块内存。
scanf 函数的参数列表要传递的是变量所代表的内存空间的地址,而取地址符&就能够得到变量的地址,所以就会出现上述代码的形式。
4.2 两者的区别
scanf 函数是C标准的库函数,而这个 scanf_s 函数怎么来的,他是微软推出的安全版输入函数。微软还推出了其他很多安全版函数,这个在后续的学习中,我们会逐渐接触到。安全版的 scanf_s 函数与 scanf 函数,只有涉及到字符和字符串的时候才会稍有不同其他都是一致的,接下来举的这个例子大致能够说明他们的不同。
#include <stdio.h>
int main()
{
//具体看一下scanf 函数的不安全之处
//通过数组的方式演示(数组的概念后面详解)
char szCh[8] = "hello";
scanf("%s", szCh); //scanf 中参数前需要加上取地址符(&),但数组不用,数组名就是地址
return 0;
}
注意:以上代码编译后发现出现错误:error C4996:'scanf'.....
此错误提示说 scanf 是一个不安全的函数,建议参考它的说明。
为了测试使用 scanf函数,我们可以通过右键工程属性->配置管理->c/c++ ->常规找到SDL检查把是改成否即可。
编译通过后输入 qwertabdjdjjieiekkllwlls 总之比 szCh 总长度要大就可以。然后在内存中查看是否超出了 szCh 的范围?
为了避免超出范围,我们尝试以下代码
#include <stdio.h>
int main()
{
//而使用 scanfs函数就没有超出范围的情况
char szCh[8] = "hello";
scanf_s("%s",szCh,8);
//限定输入字符的最大长度,输入的字符数只能比这个8小,超过了则只能保存一个’\0’
//scanf_s在输入字符的时候,也需要加一个长度,如下所示
int a,b;
scanf_s("%d%c%d", &a, &szCh[1], 1, &b); //输入字符的时候,后面跟个1
return 0;
}
五、getchar、putchar与_getch函数
1) getchar()获取第一个字符,这个函数没有参数
函数功能:从键盘输入一个字符。
返回值:返回输入字符的ASCII码,可以使用字符变量或者整型变量接收
说明:
在屏幕上输入一串字符串,直到遇到回车才结束输入,但函数只接受第一个字符。因为其返回值为int 型,所以定义一个int 型变量接受字第一个符对应的ASCII码当然也可以定义 char 型变量,保存第一个字符(字符就是数字)。代码示例如下。
#include <stdio.h>
int main()
{
int n = getchar();
char ch = getchar();
return 0;
}
getchar()一次只能接收一个字符。
例如scanf(“%c%c”,&c1,&c2);
语句如果用getchar()函数实现只能写成:
c1=getchar();c2=getchar();
getchar()可以接收回车字符。而scanf()将回车作为数据的间隔符或结束符。
getchar()接收的字符可以不赋给任何变量。
2) 字符输入函数 putchar()
函数原型:
int putchar(int c);
函数功能:
从终端输出一个字符,且转换成ASCII码返回。
函数参数:
其中c 要输出的字符,可以是字符型常量、字符型变量、整型常量、整型变量表达式、转义序列等。
#include <stdio.h>
int main()
{
int c = 'A';
putchar(c);//参数为字符变量
putchar('A');//参数为字符变量
putchar(65); //参数为数值常量 结果为 输出 65 对应的字符
putchar('5'); //参数为字符变量 这里代表字符的含义
putchar('\n'); //参数为字符常量 换行
putchar('5' + 1);//参数为表达式 这里的加法是’5’对应的ASCII码与1相加
return 0;
}
3) _getch函数无回显字符输入函数
函数原型:
int _getch(void);
函数功能:从终端输出一个字符,且转换成ASCIL码返回。
函数参数:无
注:不需要每次输入完后输入回车表示结束。只要有键按下就会直接返回,并且不会在屏幕上有显示。需要包含头文件#include <conio.h>。
#include <conio.h>
int main()
{
char ch = _getch();
return 0;
}
在C语言中,可以使用getch或_getch函数来获取用户输入的字符,但它们属于不同的库。
getch函数是C语言标准库中没有的,它通常在Windows平台的conio.h库中定义。这个函数会等待用户输入一个字符,然后立即返回该字符,而不需要等待用户按下回车键。
_getch函数则是在C语言标准库的stdio.h中定义的。这个函数也会立即返回用户输入的字符,但与getch不同的是,它需要用户按下回车键才能完成输入。
因此,如果你正在编写一个跨平台的程序,最好使用_getch函数,因为它在所有支持C语言的平台上都可以使用。如果你正在编写一个只在Windows平台上运行的程序,那么使用getch函数可能会更方便。
六、gets 和 puts 函数
C语言提供了字符串的输入输出函数gets()和puts(),用于整串字符串的输入输出。它们在头文件“stdio.h”中定义的。
1)字符串输出函数puts()
用法:puts(字符数组名); 或 puts(字符串) ;
例如:char str[]=”I like C”; puts(str);
或:puts(“I like C”);
函数puts()一次只能输出一个字符串。
函数puts()可以输出转义字符
函数puts()输出字符串后自动换行。
#include <stdio.h>
void main()
{
char str1[]="student",str2[]="teacher";
puts(str1);
puts(str2);
printf("%s",str1);
printf("%s",str2);
printf("\n%s\n%s", str1, str2);
}
可以看出printf()函数与puts()相比,一是可以同时输出多个字符串,二是可以灵活控制是否换行。
2)字符串输入函数gets()
gets()作用是将一个字符串输入到字符数组中
用法:gets(字符数组名);
例如:char str[20]; gets(str);
gets()函数同scanf()函数一样,在读入一个字符串后,系统自动在字符串后加上一个字符串结束标志’\0’。
函数gets()只能一次输入一个字符串。
函数gets()可以读入包含空格和TAB的全部字符,直到遇到回车为止。
#include <stdio.h>
void main()
{
char str1[20],str2[20];
gets(str1);
scanf("%s", str2);
printf("str1: %s\n", str1);
printf("str2: %s\n", str2);
}