【C primer plus 笔记】第四章 字符串和格式化输入输出

4.1前导程序

//talkback.c -- 演示与用户交互
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>    
#include <string.h>        //提供strlen()函数的原型
#define DENSITY 62.4    //人体密度(单位:磅/立方英尺)
int main()
{
    float weight, volume;
    int size, letters;
    char 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;
}
0

4.2 字符串简介

  字符串是一个或多个字符的序列

  4.2.1 插入类型数组和null字符

  C语言没有专门用于储存字符串的变量类型,字符串都被存储在char类型的数组中。数组由连续的存储单元组成,字符串中的字符被储存在相邻的存储单元中,每个单元储存一个字符
  数组末尾位置的字符\0,是空字符,C语言用它标记字符串的结束。C语言中的字符串一定以空字符结束,这意味着数组的容量必须至少比待存储字符串中的字符数多1.
  可以把数组看做是一行连续的多个存储单元。用更正式的说法,数组是同类型数据元素的有序序列。

  4.2.2 使用字符串

  %s告诉printf()打印一个字符串
  不用输入空字符,scanf()在读取输入时就已经完成了这项工作,也不用在字符串常量末尾添加空字符
  scanf()只会读取字符串中的一个单词,而不是一整句,读到第一个空格时就停止了。
  字符串是派生类型,"x"实际上由两个字符组成
 
0

  4.2.3 strlen() 函数

  strlen()函数给出字符串中的字符长度
  需要string.h头文件,string.h头文件包含多个与字符串相关的函数原型
  一般而言,C把函数库中相关的函数归为一类,并为每类函数提供一个头文件。
  处理很长的printf()语句:第一种方法是将printf()语句分为两行(可以在参数之间断为两行,但是不要在双引号中的字符串中间断开);第二种方法是使用两个printf()语句打印一行内容,只在第二条printf()语句中使用换行符(\n)。
  该函数不计入空字符。
  %zd对于sizeof和strlen都适用
  对于特定量,sizeof的括号可有可无,但建议都适用圆括号

4.3 常量和C预处理器

  符号常量方便修改,创建符号常量的方法:
  方法之一是声明一个变量,然后将该变量设置为所需的常量。
float taxrate; 
taxrate = 0.015;
  这样提供了一个符号名,但是taxrate是一个变量,程序可能会无意间改变它的值。
  另一种更好的方案是C预处理器。
#define TAXRATE 0.016;
  程序编译时会将所有的TAXRATE都替换成0.015,这一过程被称为编译时替换。在运行程序时,程序中所有的替换均已完成。通常,这样定义的常量也称为明示常量。
  其通用格式如下:
#define NAME value
  末尾不用加分号,大写常量会提高程序的可读性。
  可以在名称前待c_或k_前缀来表示常量。
  符号常量名后面的所有内容都被用来替换符号常量。
  #define指令还可以定义字符和字符串常量,前者使用单引号,后者使用双引号。

  4.3.1 const限定符

  const关键字用于限定一个变量是只读的。const比#define更灵活。

  4.3.2 明示常量

  C头文件limits.h和float.h分别提供了整数类型和浮点类型大小限制相关的详细信息,每个头文件都定义了一系列供实现使用的明示常量。
0
0
  把明示常量FLT改成DBL和LDBL即可表示double和 long double类型对应的明示常量。

4.4 printf()和scanf()

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

  4.4.1 printf()函数

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

  4.4.2 使用printf()

  这是printf()函数的格式:
printf(格式字符串,待打印项列表)
  待打印项可以是变量、常量,甚至是在打印之前先要计算的表达式,格式字符串应包含每个待打印项对应的转换说明。
  格式字符串是双引号括起来的内容。格式字符串中包含实际要打印的字符(字面字符)和转换说明。
  例如:
printf("The %d contestants ate %f berry pies.\n", number, pies);
  如果只打印短语或句子,就不需要使用任何转换说明,如果只打印数据,也不用加入说明文字。
  由于printf()函数使用%来标识转换说明,要打印%符号需要使用两个%符号。

  4.4.3 printf()的转换说明修饰符

  在%和转换字符之间插入修饰符可修饰基本的转换说明。
0
0

  4.4.4 转换说明的意义

  转换说明把以二进制格式储存在计算机中的值转换成一系列字符以便于显示。
  转换说明是翻译说明,%d的意思是”把给定的值翻译成十进制整数文本并打印出来“。
  大部分C函数都有一个返回值,这是函数计算并返回给主调程序的值。可以把返回值赋给变量,也可以用于计算,还可以作为参数传递。总之,可以把返回值像其他值一样使用。printf()函数也有一个返回值,它返回打印字符的个数。如果有输出错误,printf()则返回一个负值。
  有时,printf()语句太长,在屏幕上不方便阅读,一条语句可以写成多行,只需在不同部分之间输入空白(空格、制表符、换行符)即可。但是,不能在双引号括起来的字符串中间断行。
  给字符串断行有三个方法:
  方法1:使用多个printf()语句。因为第一个字符串没有以\n字符结束,所以第2个字符串紧跟第一个字符串末尾输出。
  方法2:用反斜杠和回车键组合来断行。这使得光标移至下一行,而且字符串中不会包含换行符。其效果是在下一行继续输出。
  方法3:ANSI C引入的字符串连接,在两个用双引号括起来的字符串之间用空白隔开,C语言会把多个字符串看做是一个字符串。
printf("Here's one way to print a");
printf("long string.\n");

printf("Here's another way to print a \
long string.\n");
printf("Here's the newest way to printf a"
"long string.\n");
0

  4.4.5 使用scanf()

  C库包含了多个输入函数,scanf()是最通用的一个,因为它可以读取不同格式的数据。当然,从键盘输入的都是文本,因为键盘只能生成文本字符:字母、数字和标点符号。如果要将其存储为数值而不是字符串,程序就必须把字符依次转换成数值,这就是scanf()要做的。scanf()把输入的字符串转换成整数、浮点数、字符或字符串,而printf()正好与它相反,把整数、浮点数、字符或字符串转换成显示在屏幕上的文本。
  scanf()和printf()类似,也使用格式字符串和参数列表。scanf()中的格式字符串表明字符输入流的目标数据类型。两个函数主要的区别在参数列表中。printf()函数使用变量、常量和表达式,而scanf()函数使用指向变量的指针。
  如果用scanf()读取基本变量类型的值,在变量名前加上一个&;
  如果用scanf()把字符串读入字符数组中,不要使用&
  scanf()函数使用空白(换行符、制表符和空格)把输入分成多个字段。再依次把转换说明和字段匹配时跳过空白。
  %c是例外,会读取每个字符,包括空白。
0
 
0
 
0
  scanf()函数返回成功读取的项数,当scanf()检测到“文件结尾”时,会返回EOF。

  4.4.6 printf()和scanf()的*修饰符

  printf()和scanf()都可以使用*修饰符来修改转换说明的含义。
  printf():
  如果不想预先指定字段宽度,希望通过程序来指定,那么可以用*修饰代替字段宽度。但还是要用一个参数告诉函数,字段宽度应该是多少,也就是说,如果转换说明是%*d,那么参数列表中应包含*和d对应的值。这个技巧也可用于浮点值指定精度和字段宽度。
  scanf():
  把*放在%和转换字符之间时,会使得scanf()跳过对应的输出项。

  4.4.7 printf()用法提示

  想把数据打印成列,制定固定字段宽度很有用。使用足够大的固定字段宽度可以让输出整齐美观。
  在两个转换说明中间插入一个空白字符,可以确保即使一个数字溢出了自己的字段,下一个数字也不会紧跟该数字一起输出。
  另一方面,如果要在文字中嵌入一个数字,通常指定一个小于或等于该数字宽度的字段会比较方便,这样,输出数字的宽度正合适,没有不必要的空白。
posted @ 2023-05-29 19:49  永生辉皇  阅读(52)  评论(0)    收藏  举报