Juconcurrent 学而不思则罔,思而不学则殆。

C语言学习杂记(3)—字符串格式化输入输出

2016-02-25

C语言的字符串不是基本类型,而是字符序列,可以把字符串看成一个以’\0’结尾的字符数组。’\0’其实是一种特殊字符,其数值为0。

一、示例

先看一个示例:

#include <stdio.h>
#include <string.h>
#define STIP "127.0.0.1"

int main(void)
{
    char name[40];
    int length;
    int size_of;
    int age;

    printf("please input your name.\n");
    scanf("%s", name);
    length = strlen(name);
    size_of = sizeof name;
    printf("hi %s, your name's length is %d and it's size of is %d\n", name, length, size_of);
    printf("please input your age.\n");
    scanf("%d", &age);
    printf("yes, %s, your age is %d, thanks for your input.\n", name, age);
    printf("now, the #define string is %s.\n", STIP);

    return 1;
}

这个程序可能会输出以下结果

please input your name. zhangfb hi zhangfb, your name’s length is 7 and it’s size of is 40 please input your age. 17 yes, zhangfb, your age is 17, thanks for your input. now, the #define string is 127.0.0.1.

我们有几点需要注意 1、字符串是使用字符数组来表示的; 2、输入字符串,跟输入数字不一样,不需要加入&符号,因为字符串的名称代表的是其所在字符数组首个元素的地址,且字符串的打印需要使用%s; 3、使用strlen函数返回的是字符串的长度(除’\0’之外的字符个数),而使用sizeof关键字返回的则是存储字符串的长度; 4、#define STIP “127.0.0.1”的定义,我们称之为宏定义,代码中STIP地方会被”127.0.0.1”替换,所以在STIP之后不能加“=”,如果加了,则会连”=“一并纳入替换; 5、strlen函数需要使用string.h中的声明; 6、双引号并不是字符串的一部分,它只是告知编译器其中包含了一个字符串。

二、常量与预处理器

1、常量

所谓常量,就是不可变的量。我们在什么时候或为什么要使用常量?举例来说,我们根据圆直接径计算周长,可以表示如下:

perimeter = 3.14159 * diameter;

但是如果我们用另一种方式来表达

pi = 3.14159;
perimeter = pi * diameter;

它带来的好处主要有两点:1、一个名字比一个数字表达更多的意思;2、当常量被程序多次引用的时候,如果要修改其值,只需修改一处。这就是为什么我们要使用常量的原因。

2、预处理器定义常量

C的预处理器除了使用#include <头文件.h>之外,还可以定义常量。

#define TAXRATE 0.015
#define TAXRATE1=0.015 // 这样写是不被推荐的,虽然运气好时不会出现错误。

当真实编译程序的时候,值TAXRATE出现的地方都会被0.015所替换。尤其需要注意的时候,使用预处理器定义常量的时候,中间不能加“=”号。至于TAXRATE全部是大写字母,只是一种约定或传统,即使你使用taxrate,仍然不会出现任何功能和语法上的错误。在其他一些项目中,可能会约定,常量需要命名成以c_或k_开头。但是更常用的却是常量命名成大写。

3、const修饰符

第二种定义常量的方法是使用const修饰符,即:

const int MONTHS = 12; // const修饰的变量,其实就是常量
4、系统常量

除了可以自己定义常量,系统本身也带了很多常量。例如,limits.h和float.h就有很多常量。现简单举例如下:

#include <stdio.h>
#include <limits.h>

int main(void)
{
    printf("max int is %d\n", INT_MAX);
    printf("min int is %d\n", INT_MIN);

    return 1;
}

输出如下:

max int is 2147483647 min int is -2147483648

三、printf()和scanf()

这两个函数的引入,带来的直接好处是交互更友好和有趣,不再是枯燥不变的程式了。在整个计算机中,IO的引入可谓是一种伟大的进步。我们日常点点滴滴记录,都是先由自身进行输入,再由计算机进行处理,并输出到缓存、磁盘或网络etc。尽管其对外表现不同,但其工作方式却是相同的,只是流向不同而已。在C语言中,他们的函数声明也是大同小异,都是由一个控制字符串,外加可变参数列表组成。

1、printf()函数

使用此函数打印输出的指令,取决于实际的值类型。比如打印int类型变量使用%d,打印字符使用%c,打印字符串使用%s。这些符号被称为转换说明。因为真实的转换很复杂,类型也很多,不管是作为备忘,还是作为增强记忆,都有必要梳理整理出来,现罗列如下表。

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

另外,我们可以在%和转换说明字符之间加入修饰符加以修改,现罗列部分。

修饰符

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

Content