C语言学习笔记(四)—— 字符串和格式化输入输出

 一、简单的字符串使用示例

#include<stdio.h>
#include<string.h> //它包含多个与字符串相关的函数原型,包括strlen()等
#define AGE "25" //把字符串常量定义为25
int main() {
	/**
	 * C语言没有专门用来存储字符串的数据类型,它用数组存储字符串,
	 * 该数组占用内存中40个连续的字节,每个字节存储一个字符值,
	 * 数组末尾是\0,这是空字符,标记字符串的结束,空字符不是0,
	 * 它是非打印字符,ASCII码是0,它只能存储39个字符,剩下一
	 * 个留给空字符,当然如果你存储40个以上的字符也不会马上报错,
	 * 但这已经造成了内在溢出的问题,我们要避免这种情况。
	 */
	char name[40];
	int size, letters;
	printf("What's your name ?\n");
	/**
	 * 用%s转换说明来处理字符串的输入和输出,注意name前没有&
	 */
	scanf("%s", name);//如果我们在这里输入Alex zhang,那么它只会读取Alex进行输出
	printf("My name is %s\n", name);
	printf("My age is %s\n", AGE);
	size = sizeof(name);
	letters = strlen(name);//strlen()用于获取字符串的长度
	printf("Your name have %d bytes\n", size);
	printf("Your name have %d letters\n", letters);
	return 0;
} 

1、字符串和字符

//字符串常量"x"和字符常量'x'的区别
//'x'是基本数据类型,"x"是字符数组,它由'x'和空字符\0组成

2、strlen()与sizeof()的区别

#include<stdio.h>
#include<string.h>
#define STR "This is a test content!"
int main() {
	printf("%s size is %u\n", STR, sizeof(STR));//24,它将字符串末尾的空字符也计算进去了
	printf("%s length is %u\n", STR, strlen(STR));//23,它并未将字符串末尾的空字符计算进去
	return 0;
}

二、常量和C预处理器

常量声明的格式为:#define name value

在程序编译时,程序会将所有的name替换成value,这一过程被称为编译时替换。

#include<stdio.h>
#define PI 3.1415926
void example2();
int main() {
	example2();
	return 0;
}
void example2(){
	printf("%.2f",PI);//3.14
};

1、const限定符

const用于限定变量为只读,可以使用,可以打印,但不能更改,它用起来比#define更灵活

void example3() {
	const int i = 10;//将变量设置为只读
	//i = i++; 当执行运算时,程序报错
	printf("%d", i);
}

2、明示常量

limits.h中一些明示常量

描述
CHAR_BIT 8 定义一个字节的比特数。
SCHAR_MIN -128 定义一个有符号字符的最小值。
SCHAR_MAX 127 定义一个有符号字符的最大值。
UCHAR_MAX 255 定义一个无符号字符的最大值。
CHAR_MIN 0 定义类型 char 的最小值,如果 char 表示负值,则它的值等于 SCHAR_MIN,否则等于 0。
CHAR_MAX 127 定义类型 char 的最大值,如果 char 表示负值,则它的值等于 SCHAR_MAX,否则等于 UCHAR_MAX。
MB_LEN_MAX 1 定义多字节字符中的最大字节数。
SHRT_MIN -32768 定义一个短整型的最小值。
SHRT_MAX +32767 定义一个短整型的最大值。
USHRT_MAX 65535 定义一个无符号短整型的最大值。
INT_MIN -32768 定义一个整型的最小值。
INT_MAX +32767 定义一个整型的最大值。
UINT_MAX 65535 定义一个无符号整型的最大值。
LONG_MIN -2147483648 定义一个长整型的最小值。
LONG_MAX +2147483647 定义一个长整型的最大值。
ULONG_MAX 4294967295 定义一个无符号长整型的最大值。

float.h中的一些明示常量

描述
FLT_ROUNDS 定义浮点加法的舍入模式,它可以是下列任何一个值:
  • -1 - 无法确定

  • 0 - 趋向于零

  • 1 - 去最近的值

  • 2 - 趋向于正无穷

  • 3 - 趋向于负无穷

FLT_RADIX 2 这个宏定义了指数表示的基数。基数 2 表示二进制,基数 10 表示十进制,基数 16 表示十六进制。

FLT_MANT_DIG

DBL_MANT_DIG

LDBL_MANT_DIG

这些宏定义了 FLT_RADIX 基数中的位数。

FLT_DIG 6

DBL_DIG 10

LDBL_DIG 10

这些宏定义了舍入后不会改变表示的十进制数字的最大值(基数 10)。

FLT_MIN_EXP

DBL_MIN_EXP

LDBL_MIN_EXP

这些宏定义了基数为 FLT_RADIX 时的指数的最小负整数值。

FLT_MIN_10_EXP -37

DBL_MIN_10_EXP -37

LDBL_MIN_10_EXP -37

这些宏定义了基数为 10 时的指数的最小负整数值。

FLT_MAX_EXP

DBL_MAX_EXP

LDBL_MAX_EXP

这些宏定义了基数为 FLT_RADIX 时的指数的最大整数值。

FLT_MAX_10_EXP +37

DBL_MAX_10_EXP +37

LDBL_MAX_10_EXP +37

这些宏定义了基数为 10 时的指数的最大整数值。

FLT_MAX 1E+37

DBL_MAX 1E+37

LDBL_MAX 1E+37

这些宏定义最大的有限浮点值。

FLT_EPSILON 1E-5

DBL_EPSILON 1E-9

LDBL_EPSILON 1E-9

这些宏定义了可表示的最小有效数字。

FLT_MIN 1E-37

DBL_MIN 1E-37

LDBL_MIN 1E-37

这些宏定义了最小的浮点值。

三、printf()和scanf()

printf()是输出函数,scanf()是输入函数

1、printf()函数的转换说明

        请求printf()函数打印数据的指令要与待打印数据的类型相匹配,如打印整数时使用%d,打印字符时使用%c,这些符号被称为转换说明,它们指定了如何把数据转换成可显示的形式。

常用的转换说明及其输出结果如下:

转换说明 输出
%a,%A 浮点数、十六进制数和p计数法(C99/C11)
%c 一个字符
%d 有符号十进制数
%e,%E 浮点数,e计数法
%f 浮点数,十进制计数法
%g,%G 根据数值不同自动选择%f或%e,%e格式在指数小于-4或者大于等于精度时使用
%i 有符号十进制整数(与%d相同)
%o 无符号八进制整数
%p 指针
%s 字符串
%u 无符号十进制数
%x,%X 使用十六进制数0f的无符号十六进制整数
%% 打印一个百分号

2、printf()的转换说明修饰符

修饰符 意义
标志 五种标志将在后面的表3中说明,可以使用零个或者多个标志,示例: “%-10d”
数字 字段宽度的最小值。如果字段不能容纳要打印的数或者字符串,系统会使用更宽的字段示例: “%4d”,“%10s”
.数字 精度 对于%e,%E和%f转换,是将要在小数点的右边打印的数字的位数。对于%g和%G转换,是有效数字的最大位数。对于%s转换,是将要打印的字符的最大数目。对于整数转换,是将要打印的数字的最小位数。如果必要,要使用前导0来达到位数。只使用”.”表示其后跟随一个0,所以%.f和%.0f相同。示例: “%5.2f”表示打印一个浮点数,它的字段宽度为5个字符,小数点后有两个数字
h 和整数转换说明符一起使用,表示一个short int或unsigned short int类型数值。示例: “%hu”, “%hx”, “%6.4hd”
hh 和证书转换说明符一起使用,表示一个signed char或unsigned char类型数值
j 和整数转换说明符一起使用,表示一个intmax_t或uintmax_t值示例: “%jd”,”%8jx”
l 和整数转换说明符一起使用,表示一个long int或unsigned long int类型值
ll 和整数转换说明符一起使用,表示一个long long int或unsigned long long int类型值(C99)示例: “%lld”,”%8llu”
L 和浮点数转换说明符一起使用,表示一个long double值示例: “%Lf”, “%10.4Le”
t 和整数转换说明符一起使用,表示一个ptrdiff_t值(与两个指针之间的差相对应的类型)(C99)。示例: “%td”, “%1ti”
z 和整数转换说明符一起使用,表示一个size_t值(sizeof返回的类型)(C99)。示例: “%zd”,”%12zx”

3、printf()中的标记

标志 意义
- 项目左对齐,即,会把项目打印在字段的左侧开始处。示例: “%-20s”
+ 有符号的值若为正,则显示带加号的符号;若为负,则显示带减号的符号。示例: “%+6.2f”
(空格) 有符号的值若为正,则显示时带前导空格(但是不显示符号);若为负,则带减号符号。+标志会覆盖空格标志。示例: “% 6.2f”
# 使用转换说明的可选形式。若为%o格式,则以0开始;若为%x和%Xgeshi ,则以0x或0X开始。对于所有的浮点形式,#保证了即使不跟任何数字,也打印一个小数点字符。对于%g和%G格式,它防止尾随0被删除。示例: “%#o”, “%#8.0f”, “%+#10.3E”
0 对于所有的数字格式,用前导零而不是空格填充字段宽度。如果出现-标志或者指定了精度(对于整数)则忽略该标志。示例: “%010d”, “%08.3f”,”%02X”

4、printf()的使用示例

意义
- 项目左对齐,即,会把项目打印在字段的左侧开始处。示例: “%-20s”
+ 有符号的值若为正,则显示带加号的符号;若为负,则显示带减号的符号。示例: “%+6.2f”
(空格) 有符号的值若为正,则显示时带前导空格(但是不显示符号);若为负,则带减号符号。+标志会覆盖空格标志。示例: “% 6.2f”
# 使用转换说明的可选形式。若为%o格式,则以0开始;若为%x和%Xgeshi ,则以0x或0X开始。对于所有的浮点形式,#保证了即使不跟任何数字,也打印一个小数点字符。对于%g和%G格式,它防止尾随0被删除。示例: “%#o”, “%#8.0f”, “%+#10.3E”
0 对于所有的数字格式,用前导零而不是空格填充字段宽度。如果出现-标志或者指定了精度(对于整数)则忽略该标志。示例: “%010d”, “%08.3f”,”%02X”
void example4(){//下面的*号是作一个标记,方便看输出结果
	int num = 888;
	printf("*%d*\n",num);//结果:*888*,这是默认的情况
	printf("*%2d*\n",num);//结果:*888*,输出结果应该是2字段宽,打印的整数有3位,所以字段宽度自动扩大
	printf("*%5d*\n",num);//结果:*  888*,输出结果有5个空格宽度,数字位于右侧
	printf("*%-5d*\n",num);//结果:*888  *,输出结果有5个空格宽度,数字位于左侧

	double price = 3852.99;
	printf("*%f*\n",price);//结果:*3852.990000*,默认至少能表示6位有效数位
	printf("*%e*\n",price);//结果:*3.85299e+003*,使用指数计数法
	printf("*%3.1f*\n",price);//结果:*3852.0*,3代表小数点前是3空格宽度,但实际有4个,自动扩大,1代表保留小数点后1位
	printf("*%10.3f*\n",price);//结果:*  3852.990*,输出结果10个空格宽度,前面2个空格,后面8个字符
	printf("*%-10.3f*\n",price);//结果:*3852.990  *,浮点数位于左侧
	printf("*%12.2E*\n",price);//结果:*  3.853E+003*,E可以替代e,小数四舍五入保留2位
	printf("*%+4.2f*\n",price);//结果:*+3852.99*,在浮点数前面添加代数符号+
	printf("*%010.2f*\n",price);//结果:*0003852.99*,打印结果前面用0来填充
};

5、转换说明意义

5.1 转换不匹配

        转换说明把以二进制格式存储在计算机中的值转换成一系列字符以便于显示,转换说明应该与待打印值的类型相匹配。

5.2 printf()的返回值

返回打印的字符个数,如果出错返回负值

void example5(){
	int length = printf("zhangsan\n");
	printf("%d",length);//结果:8
};

6、使用scanf()

scanf()把输入的字符串转换成整数、浮点数、字符或字符串。

6.1 scanf()与printf()的区别

        两者的区别主要是在参数列表中,printf()使用变量、常量或表达式,scanf()使用指向变量的指针。

6.2 scanf()使用注意

① 使用scanf()读取基本变量类型的值,要是变量名前加一个&

② 使用scanf()把字符串读取到字符数组中,不能使用&

void example6() {
	int num;
	char name[50];//字符数组,用于存储字符串
	scanf("%d\n", &num);//读取基本类型的值
	scanf("%s\n", name);
	printf("%s have %d apples",name,num);
}

6.3 scanf()的转换说明

转换说明符 意义
%c 把输入解释成一个字符
%d 把输入解释成一个有符号十进制整数
%e,%f,%g,%a 把输入解释成 一个浮点数(%a是C99标准)
%E,%F,%G,%A 把输入解释成一个浮点数(%A是C99标准)
%i 把输入解释成一个有符号十进制整数
%o 把输入解释成一个有符号八进制数
%p 把输入解释成一个指针(地址)
%s 把输入解释成一个字符串;输入的内容以一个非空白字符作为开始,并且包含直到下一个空白字符的全部字符
%u 把输入解释成一个无符号十进制整数
%x,%X 把输入解释成一个有符号十六进制整数

6.4 scanf()转换说明中的修饰符

修饰符 意义
* 滞后赋值。示例:“%*d“
digit(s) 最大字段宽度;在达到最大字段宽度或者遇到第一个空白字符时(不管哪一个先发生都一样)停止对输入项的读取。示例:“%10s“
hh 把整数读作signed char 或者 unsigned char 。示例:“%hhd“ ”%hhu“
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类型存储。将L(而非l)与e、f和g一起使用指示该值以long double类型存储。
如果没有这些修饰符,d、i、o、和x知识int类型,而e、f和g指示float类型

6.5 scanf()的返回值

scanf()返回成功读取的项数,如果没有读取任何项或者要读取数字却输入了一个非数值字符串,scanf()便会返回0

void example6() {
	int num;
	char name[50];//字符数组,用于存储字符串
	scanf("%d\n", &num);//读取基本类型的值
	int result=scanf("%s\n", name);
	printf("%d\n",result);//结果是1
	printf("%s have %d apples",name,num);
}

猜你喜欢

转载自blog.csdn.net/alexshi5/article/details/80146518