03-字符串和格式化输入/输出

0x00 前导程序

 
//talkback.c –演示与用户交互

#include <stdio.h>

#include <string.h> //提供strlen()函数的原型

#define DENSITY 62.4 //人体密度(单位:磅/立方英尺)

int main()

{
float weight, volume;
int size, letters;
char name[40]; //name是一个可容纳40个字符的数组
printf(“Hi! What’s your first name?\n”);
scanf(“%s”, name);
printf(“%s, what’s your weight in pounds?\n”, name);
scanf(“%f”, &weight);
size = sizeof name;
letters = strlen(name);
volume = weight / DENSITY;
printf(“Well, %s your volume is %2.2f cubic feet.\n”, name, volume);
printf(“Also, your first name has %d letters,\n”, letters);
printf(“and we have %d bytes to store it.\n”, size);
return 0;
}

  • 用数组储存字符串
  • 使用%s转换说明来处理字符串的输入和输出
  • 用C预处理器把字符常量DENSITY定义为62.4
  • 用C函数strlen()获取字符串的长度

0x01 字符串简介

  • 字符串是一个或多个字符的序列,双引号不是字符串的一部分,用来给编译器识别
  • 在C语言中没有专门用于储存字符串的变量类型,字符串都被储存在char型数组中。数组由连续的储存单元组成,字符串中的字符被储存在相邻的存储单元中,每个单元储存一个字符,以\0结束。数组的容器必须至少比待存储字符串中的字符数多1
  • 数组是一行连续的多个存储单元,是同类型数据元素的有序序列。char name[40]; name后面的方括号表明这是一个数组,方括号中的40表明该数组中的元素数量,char表明每个元素的类型。
 
//pralse1.c –使用不同类型的字符串
#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;
}
  • %s告诉printf()打印一个字符串。打印了两个字符串,一个储存在name数组中,一个由PRAISE来表示。scanf()遇到第1个空白(空格、制表符或换行符)时就不在读取输入。
  • 字符串常量”X”和字符‘X’不同,区别在于’X’是基本类型char,而”X”是派生类型char数组,”X”实际上由两个字符组成,’x’和空字符\0

sizeof运算符以字节为单位给出对象的大小,streln()函数给出字符串中的字符长度。

 
 //praise2.c – sizeof运算符和stelen()比较
//如果编译器不识别%zd,尝试换成%u或%lu
#include <stdio.h>
#include <string.h> /*提供strlen()函数的原型*/
#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);
printf("Your name of %zd letters occupies %zd memory cells.\n",
strlen(name), sizeof name);
printf("The phrase of praise has %zd letters ",
strlen(PRAISE));
printf("and occupies %zd memory cells.\n", sizeof PRAISE);
return 0;

}

string.h头文件包含多个与字符串相关的函数原型,包括strlen()函数和其他一些与字符串相关的函数。对于PRAISE,用strlen()得出的也是字符中的字符数,sizeof运算符给出的数更大,因为它把字符串末尾不可见的空字符也计算在内。早期的C,还要知道sizeof和strlen()返回的实际类型(unsigned or unsigned long)。对于类型应该写成sizeof(char)或sizeof(float)。对于特定量,可写成sizeof name或sizeof 6.28,建议所有情况下都使用圆括号

0x02 常量和C预处理器

  • 使用常量符号表达的信息更多,别使用数值更清楚。特定程序中可能会随着实际变化的参数多处修改使用常量比较省事。声明一个变量,在程序运行中改变它的值。使用C预处理器定义常量,在程序顶部添加下面一行:

#define CHANGE 200

  1. 编译程序的时候,程序中的所有CHANGE都会被替换成200,这一过程被称为编译时替换。也叫做明示常量。在名称前使用c_或者k_前缀来表示常量。常量可以定义为C语言合法的表达式或数据类型

  1. const关键字限定一个变量为只读,其声明如下:const int MONTHS = 12; //MONTHS在程序中不可更改,值为12。在程序中使用可以打印MONTHS,但不能更改MONTHS的值。
  2. 明示常量:limits.h和float.h分别提供了整数类型和浮点类型大小限制相关信息。每个头文件都定义了一系列供实现使用的明示常量。

FLT_DIG和DBL_DIG分别表示float类型和double类型的有效数字位数。

0x03 printf()和scanf()

printf()函数和scanf()函数能让用户可以与程序交流,它们是输入/输出函数,或简称I/O函数。

printf(格式字符串,待打印项1,待打印项2,…); //待打印项可以是变量、常量甚至是打印之前要计算的表达式。格式化字符串应该包含每个待打印项对于的转换说明。打印’%’使用两个‘%’

printf()的修饰符

stddef.h文件(在包含stdio.h头文件时已包含其中)把size_t定义成系统使用sizeof返回的类型,这被称为底层类型。其次,printf()使用z修饰符表示打印相应的类型。C还定义了ptrdiff_t类型和t修饰符来表示系统使用的两个地址差值的底层有符号整数类型

对于浮点类型,有用于double和Long double类型的转换说明。因为float类型值会被自动转换成double类型。

printf()的标记

转换说明的意义:把二进制格式储存在计算机中的值转换成一系列字符以便于显示。

printf()的返回值是打印字符的个数,输出错误返回一个负值。printf()打印字符串使用’\’断行。两个用双引号括起来的字符串隔开,编译器把多个字符串看作是一个字符串。

scanf()把输入的字符串转换成整数、浮点数、字符或字符串,scanf()中的格式字符串表明字符输入流的目标数据类型。scanf()中的格式字符串表明字符输入流的目标数据类型。指向变量的指针。读取基本变量类型的值,在变量前加上一个&,如果用scanf()把字符串读入字符数组中,不要使用&。scanf()转换说明符

scanf()转换修饰符

`

  • scanf()读取%d遇到空白字符跳过,遇到非空白字符才读取。读取到第一个数字字符或-、+,读取下一个字符,遇到非数字字符停止。下一次读取到的数据开始会是跳过的字符。

  • scanf()函数允许把普通字符放在格式字符串中,除空格字符外的普通字符必须与输入字符串严格匹配。scanf(“%d,%d”, &n, &m); 用户必须输入22,33这种格式。
  • scanf()函数返回成功读取的项数,如果读取非指定类型返回0,文件结尾返回EOF

  • printf()用*代替字段宽度或者代替浮点值精度和字段宽度

  • scanf()用*跳过相应的输出项,在程序需要读取文件中特定列的内容时。

  • printf()使用足够大的固定字段宽度可以让输出整齐美观

 

0 条评论
发表一条评论