文章目录
第三章 字符串和格式化输入/ 输出
字符/字符串简要理解
前言
C 语言中的字符和字符串是常用的数据类型。字符是一个单个的字母、数字、标点符号或者其他可打印的符号,使用单引号 ’ ’ 表示,例如:‘A’、‘0’、‘+’ 等。C 语言使用 ASCII 码表示字符,每个字符都有一个整数值和一个字符表示。
字符串是字符数组或指针,表示一个或多个字符的序列。字符串使用双引号 " " 表示,例如:“hello”、“world” 等。字符串的最后一个字符是 ‘\0’,表示字符串的结尾。
字符介绍和使用
在计算机编程语言中,字符表示单个字符,如字母、数字或标点符号等,用于表示文本信息和各种类型的数据。在C语言中,字符使用单引号(’ ')表示。例如,单引号中的字符‘a’、‘A’、‘0’都是字符。
字符变量和字符常量是计算机程序中常用的C字符处理机制。变量通常存储一个或多个字符的系列。常量是字符的固定值,不能被修改。字符常量可以存在程序中或通过用户输入设置,然后被分配给字符变量。
#include "stdio.h"
/*
char c ---------可以理解为 用户自己定义的字符变量
'A' ---------可以理解为 字符常量
*/
int main() {
char c = 'A'; // 定义一个字符变量
printf("The character is %c\n", c); // 输出字符
char ch = getchar(); // 获取从键盘输入的字符
printf("The character entered is %c\n", ch);
return 0;
}
数组的简单介绍
数组可以把数组看作是一行连续的多个存储单元。用更正式的说法是,数组是同类型数据元素的有序序列
所有的数组元素都是在一块连续的地址上的存储的,第一个元素占最低的地址,最后一个元素占最高的地址
数组的创建格式
数组是由数组类型+数组名+数组大小组成的,其中最重要的是数组大小是一个常量表达式
/*
此初始化方式第一次看只需知道,等后面正式学到的时候再进一步深入
*/
1、int arry[10] = { 0 };//完全初始化
2、int arry1[6] = { 1,2,3 };//不完全初始化
3、int arry2[5] = { 1,2,3,4,5 };//完全初始化
4、char arry3[] = { 'a','b','c' };//完全初始化
5、char arry4[] = { 'a','b',66,'c' };//完全初始化
6、char arry5[] = "abcdef";//完全初始化
7、char arry6[10] = "abc";//不完全初始化
字符串介绍和使用
字符串 --------- 是一个或者多个字符的序列
C语言没有专门用于存储字符串的变量类型,字符串都被存储在char类型的数组中,数组是由连续的存储单元构成的,字符串中的字符被存储在相邻的存储单元中,每个单元存储一个字符
字符串是字符序列,是C语言中非常重要的一种数据类型。字符串中的字符使用空字符(‘\0’)作为结尾。与字符不同,字符串是必须使用双引号(" ")来表示。在C语言中,我们通常用字符指针【后面学到的】或字符数组来表示字符串。
注意
:
- 双引号不是字符串的一部分。双引号仅告知编译器它括起来的是字符串,正如单引号用于标识单个字符一样。
- 一般来说,空字符计算机会帮我们自动添加,所以实际使用时只用表明这个是字符串 “ ” 就行了。
因为字符串需要用\0结尾,所以在定义字符串的时候,字符数组的长度要预留多一个字节用来存放\0,空字符不是数字 0,它是非打印字符,其 ASCII 码值是(或等价于)0,C中的字符串一定是以空字符结束(’/0‘),这意味着数组的容量必须要比所存储的字符串多1
char name[21]; // 定义一个最多存放20个英文字符或十个中文的数组
/*
*简单理解:
英文字符一般只占用1个位置
而中文字符一般只占用2个位置
*/
## printf
printf函数
- printf()函数能让用户可以与程序交流它们是输出函数或简称为 I/0函数
- 可以说他是最常用的输出函数,可以将你写的代码展示到你的显示屏上面,方便调试
printf函数是格式输出函数,其关键字最末一个字母f即为“格式(format)”之意。其功能是按照用户指定的格式,把指定的数据显示到显示器屏幕上。
printf函数一般格式
printf(格式控制字符串,输出值参数表);
如:
printf("f=%f,c=%f\n",f,c);
其中,f=%f,c=%f\n 是格式控制字符串,f,c 是输出值参数表。
(1)格式控制字符串是用双引号括起来的字符串,包括三类信息:
-
格式字符。格式字符由“%”引导,如%d、%f等。它的作用是控制输出字符的格式。
-
转义字符。格式控制字符串里的转义字符按照转义后的含义输出,如上面printf函数双引号内的换行符“\n”,即输出回车。
-
普通字符。普通字符即需要在输出时原样输出的字符,如上面printf函数中双引号内的“f=”和“c= ”部分。
(2)注意事项
输出值参数表是需要输出的数据项的列表,输出数据项可以是常量、变量或表达式,输出值参数之间用逗号分隔,其类型应与格式字符相匹配。每个格式字符和输出值参数表中的输出值参数一一对应,没有输出参数时,格式控制字符串中不再需要格式字符。
注意,如果没有输出参数时,但是还有格式控制字符串,则会发生未知错误。
#include <stdio.h>
#include <string.h>
int main(void)
{
int c = 0;
printf("%d\n%d\n",c);
}
这里,第2个号d没有对应任何项。系统不同,导致的结果也不同。不过,出现这种问题最好的状况是得到无意义的值。
printf()的转换说明修饰符
printf函数部分格式字符
较为常用已用红框标出的:
常用格式字符详解
%d
int a = 888,b = -666;
printf("%d\n%d",a,b);
输出结果:
还可以在%和格式字符*中间插入格式修饰符*,用于指定输出数据的域宽(所占的列数),如用“%5d”,指定输出数据占5列,输出的数据在域内向右靠齐。如:
%md
例如:
int a = 888, b = -666;
printf("%5d\n%5d", a, b);
从结果可以看出,在%和d中间加数字5,888占3个域宽,****指定域宽>输出数据长度**。****输出数据靠右,前面补空格
%f
输出一个实数(包括单精度、双精度、长双精度),以小数形式输出,有以下几种用法:
不指定输出数据的长度,由系统根据数据的实际情况决定数据所占的列数。系统处理的方法一般是:实数中的整数部分全部输出,小数部分输出6位。
#include <stdio.h>
#include <string.h>
int main()
{
float c = 1.11111;
printf("%f\n",c);
}
那怎么控制输出小数点后面的位数呢?
%.mf
#include <stdio.h>
#include <string.h>
int main()
{
float c = 1.11111;
printf("%.3f\n",c);
}
当然浮点型也可以控制域宽**
%n.mf
#include <stdio.h>
#include <string.h>
int main()
{
float c = 11111.11111;
printf("%30.3f\n",c);
}
可以看出 %3.f 实际是 %3.0f,小数点前面控制域宽,小数点后面控制小数点保留的个数。**
%c
#include <stdio.h>
#include <string.h>
int main()
{
char c ='1';
printf("%c\n",c);
}
%s
#include <stdio.h>
#include <string.h>
int main()
{
printf("%s\n","123312");
}
注意:
请求 printf()函数打印数据的指令要与待打印数据的类型相匹配,否则可能会出现错误
第一个printf函数中的输出参数b是double型值58.8,但对应的格式控制符为%d,当类型不一致时并不会进行类型转换,而会将实际转入的double型值当作需要的整形类型来理解,因此出现非预期结果;
第二个printf函数中,格式控制字符串给出了两个%引导的格式字符,但是输出参数表中只有一个参数a,参数缺少。因此输出c的值默认为内存中a变量后面存储单元的数据值,c的值无法确定
printf的返回值
返回值是是输出的字符数量,包括数字,字母,标点符号,空格等。
#include <stdio.h>
#include <string.h>
int main()
{
int A=43;
printf("%d\n",printf("%d",printf("%d",A)));
}
最后输出结果是这个
代码逻辑:首先,从最内层开始A=43被直接输出。然后,最内层printf的返回值以%d的格式被中间层的printf输出为2。最后,最外层的printf以%d的格式输出中间层的返回值为1。
其实观察第二个printf的输出值和第三个printf的输出值,第一个printf的输出值和第二个printf的输出值不难发现:
printf的返回值就是输出的字符数量
第三个printf输出"43"字符数量为2,于是返回值为2,第二个printf就输出"2”
第二个printf输出"2"字符数量为1,于是返回值为1,第一个printf就输出"1"
#include <stdio.h>
#include <string.h>
int main()
{
printf("%d\n", printf("0,1,2,3\n"));
}
通过运行结果不难看出,数字0123分别占一个字符,标点符号" , “也是分别占一个字符位,换行符” \n "也是占一个。
#include <stdio.h>
#include <string.h>
int main()
{
int num=printf("%d\n", printf("0,1,2,3\n"));
printf("%d\r\n", num);
}
num值为2说明num接受printf的返回值是2**
也说明了printf输出字符数量是2,其中一个是数字8,另外一个就是printf格式控制中的 " \n "可见,格式控制中的字符也算进返回值哦!
scanf
规则说明
scanf()函数使用指向变量的指针,目前只用记住两条规则:
- 如果使用scanf()读取基本变量类型的值,在变量前面加个&
- 如果使用scanf()把字符串存储到字符属数组中,不使用&
#include <stdio.h>
int main(void)
{
int age; // variable
float assets; // variable
char pet[30]; // string
printf("Enter your age, assets, and favorite pet.\n");
scanf("%d %f", &age, &assets); // use the & here
scanf("%s", pet); // no & for char array
printf("%d $%.2f %s\n", age, assets, pet);
return 0;
}
#include <stdio.h>
#define PRAISE "You are an extraordinary being."
int main(void)
{
char name[40];
printf("What's your name? ");
scanf("%s", name);
printf("Hello, %s. %s\n", name, PRAISE);
return 0;
}
注意,scanf它会遇到的第一个空白(空格、制表符或换行符)时就不在输入
所以scanf只会读取字符串中的第一个单词,一般用于输入函数(字符串)的话用fgets()
-
scanf()函数每次读取一个字符,跳过所有的空白字符,直到遇到第一个非空白字符才开始读取。
-
如果使用字段宽度,scanf()在字段末尾或者第一个空白字符的时候停止读取,无法利用字段宽度让只有一个%s的scanf()读取多个单词,最后要注意一点:当scanf()把字符串放进指定的数组的时候,它会在字符序列的末尾添加上’\0’,让数组中的内容成为一个C字符串。
例如:
/*
scanf(Angle Planins)时 遇到Anglea的时候就已经停止输入
*/
转化说明
转换说明 | 输出 |
---|---|
%c | 字符 |
%s | 字符串 |
%d | 有符号十进制整数 |
%u | 无符号十进制整数 |
%o | 无符号八进制整数 |
%x | 无符号十六进制整数(小写) |
%X | 无符号十六进制整数(大写) |
%f | 小数形式的浮点数(float) |
%lf | 小数形式的浮点数(double) |
%e | 指数形式的浮点数(小写) |
%E | 指数形式的浮点数(大写) |
%g | 以小数形式和指数形式中宽度较短的形式输出浮点数,并且不输出无意义的0(小写) |
%G | 以小数形式和指数形式中宽度较短的形式输出浮点数,并且不输出无意义的0(大写) |
%p | 地址 |
%% | 一个百分号 |
换说明中的修饰符
转换说明 | 转换说明 |
---|---|
* | 抑制赋值,示例:“%*d" |
数字 | 最大字段宽度,输入达到最大字段宽度处,或者第一次遇到空白字符为止,示例:“%10s” |
hh | 把整数作为signed char 或者 unsigned char 类型读取 |
ll | 把整数作为long long或者unsigned long long类型读取(C99),示例:“%lld”、“%llu” |
h、l或者L | “%hd"和”%hi”表明把对应的值存储为short int类型;“%ho”、“%hx"和”%hu"表明把对应的值存储为unsigned short int类型;“%ld"和”%li"表明把对应的值存储为long类型;“%lo”、“lx”和“%lu”表明把对应的值存储为unsigned long类型;“%le"、”%lf“和"%lg"表明把对应的值存储为double类型;在e、f和g前面使用L而不是l,表明把对应的值被存储为long double类型,如果没有修饰符,d、i、o和x表明对应的值被存储为int类型,f和g表明把对应的值存储为float类型 |
j | 在整形转换说明后面时,表明使用intmax_t或者uintmax_t类型(C99)示例:“%jd”、“%ju” |
z | 在整形转换说明后面时,表明使用sizeof的返回类型,示例:“%zd”、”%zo" |
t | 在整形转换说明后面时,表明使用表示两个指针差值的类型 ,示例:“%td”、“%tx” |
从scanf角度看输入
假设,scanf()根据一个%d转化说明读取到一个整数
- scanf 函数每次只读取一个字符,先跳过所有非空白字符,知道遇到第一个非空白字符后才开始读取,因为要读取整数,所以如果下一个字符并不是数字或者符号
+或-
(遇到非数字字符),scanf则会认为已经读到了末尾,然后将这个非数字字符放回输入。这意味着下一次开始读的时候,第一个读到的就是这个数字字符 - 如果第一个字符不是数字字符的话。scanf则一直无法越过读取下一个字符,因为
C规定在第一天字符出错时则停止输入
- 注意,所有空白的概念是指包含没有空格的特殊情况
scanf的返回值
- 成功情况:
- 返回成功读取的项数
- 读不到任何项(如需要读取一个数字但是前面是个非数字类型的字符)
- 返回0
- 读到文件结尾
- 返回
EOF
,这是stdio.h中定义的特殊值,通常用#define定义成-1
- 返回
scanf("%d %d",&a,&b);
函数返回值为int型。如果a和b都被成功读入(输入都是数字),那么scanf的返回值就是2;
如果只有a被成功读入(其中一个是数字),返回值为1;
如果a和b都未被成功读入(例如输入q,2.5等字符),返回值为0;
如果遇到错误或遇到end of file,返回值为EOF。end of file相当于Ctrl+z 或者Ctrl+d。
putchar
输出
putchar() → 字符数据输出
输出字符数据是可以使用 putchar() 函数的,其作用是向显示设备进行输出①个无符号字符。
注意:是①个字符,当然也可以说是单个字符咯。
标准格式:
int putchar(int character);
▪️ 目的:
putchar 将一个字符输出到标准输出(通常是控制台)。
▪️ 参数:
character:要输出的字符。它以 int 类型传递,但只使用最低有效的 8 位,因此实际上被视为 char 类型处理。
▪️ 返回值:
将写入的字符作为 unsigned char 类型返回,如果发生错误,则返回 EOF。
▪️用法:
可以使用 putchar 在控制台(屏幕)上显示字符。
#include <stdio.h>
int main() {
char ch = 'A';
printf("显示一个字符:");
putchar(ch); //putchar接收到一个参数(ASCII码值),将字符输出到标准输出
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main(void)
{
int a = 'A';
putchar(a);
return 0;
}
运行结果:A
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main(void)
{
int a = 65;
putchar(a);
return 0;
}
运行结果:A
注意:用putchar()输出整形变量会转换成对应ASCll码的值。(十进制转换成字符)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define num 65
#define c 'A'
int main(void)
{
putchar(num);
putchar(c);
return 0;
}
运行结果
标签:字符,第三章,输出,int,总集,printf,格式化,sizeof,include From: https://blog.csdn.net/qq_62548908/article/details/141113919