C语言格式化输出输入

1.简单的输入输出的例子

#include <stdio.h>
int main(void) {
    char your_print[40];
    scanf("%s", your_print);
    printf("this is your print:%s", your_print);

    return 0;
}

一个%s表示对位后面的一个字符串,当然输入输出也可以不加入占位符。

2.printf函数的转换说明

转换说明 输出
%a 浮点数,十六进制数和p记数法(C99/C11)
%A 同上
%c 单个字符
%d 有符号十进制整数
%e 浮点数,e记数法
%E 同上
%f 浮点数,十进制记数法
%g 自动选择%f或%e,%e用于指数小于-4
%G 自动选择%f或%E,
%i 有符号十进制整数(同%d)
%o 无符号八进制整数
%p 指针
%s 字符串
%u 无符号十进制整数
%x 无符号十六进制整数,使用十六进制数0f
%X 同上,使用0F
%% 百分号
%zd sizeof()

一个简单的例子:

#include <stdio.h>
#define PI 3.141593

int main(void) {
    int number = 7;
    float pies = 12.75;
    int cost = 7800;

    printf("The %d contestants ate %f berry pies.
", number, pies);
    printf("The value of pi is %f.
", PI);
    printf("Farewell! thou art too dear for my possessing,
");
    printf("%c%d
", '$', 2*cost);

    return 0;
}

输出:

The 7 contestants ate 12.750000 berry pies.
The value of pi is 3.141593.
Farewell! thou art too dear for my possessing,
$15600

3.printf的转换说明修饰符

在%和转换字符之间插入修饰符可修饰基本的转换说明。注意编译器要支持C99.

修饰符

数字 最小字符宽度  %4d
.数字 精度,小数点右边的数字表示如下
对于%e%E%f,表示小数点右边数字的位数
对于%g%G,表示有效数字最大位数
对于%s,表示待打印字符的最大数量
对于整型,表示最小位数,不够的前面加0
只用.表示其后跟随一个0,所以%.f和%.0f相同
比如:%5.2f
h 和整型转换说明一起使用,表示short int或者unsigned short int类型的值
hh 表示signed char或者unsigned char类型的值
j 表示intmax_t或者uintmax_t类型的值,这些类型在stdint.h中
l 表示long int或者unsigned long int类型的值
ll long long int或者unsigned long long int(C99)
L long double
t 表示ptrdiff_t类型的值。(C99)
z 表示size_t类型的值。(C99)

标记修饰符

- 待打印左对齐,从字段的左侧开始打印该项
+ 显示符号,为正显示+,为负显示-,没有则不显示。比如%+6.2f
空格 同显示符号,为正不显示符号显示空格,负号显示-。比如% 6.2f
# 将结果转换成另外一种形式,如果是%o格式,则以0开始,%x或者%X,则以0x或者0X。浮点格式则是强行打印一个小数点,,对于%g或%G格式,防止结果后面的0被删除
比如:%#o, %#8.0f, %+#10.3e
0 对于数值格式,用前导0代替空格填充字符宽度。对于整数格式,如果出现-标记或者指定精度,则忽略该标记。
比如:%010d和%0.83f

打印整数的例子:

#include <stdio.h>
#define PAGE 959

int main(void) {
    printf("*%d*
", PAGE);
    printf("*%2d*
", PAGE);
    printf("*%10d*
", PAGE);
    printf("*%-10d*
", PAGE);

    return 0;
}

输出如下,第二个字段宽度会自动扩大,第三个例子两个星号之间有7个空格和三个数字。

*959*
*959*
*       959*
*959       *
打印浮点数的例子:
#include <stdio.h>

int main(void) {
    const double RENT = 3852.99;

    printf("*%f*
", RENT);
    printf("*%e*
", RENT);
    printf("*%4.2f*
", RENT);
    printf("*%3.1f*
", RENT);
    printf("*%10.3f*
", RENT);
    printf("*%10.3E*
", RENT);
    printf("*%+4.2f*
", RENT);
    printf("*%010.2f*
", RENT);

    return 0;
}

输出,注意010.2f第一个0是标记0.

*3852.990000*
*3.852990e+03*
*3852.99*
*3853.0*
*  3852.990*
* 3.853E+03*
*+3852.99*
*0003852.99*
一些格式标记:
#include <stdio.h>

int main(void) {

    printf("%x %X %#X
", 31, 31, 31);
    printf("%**d**% d**% d**
", 42, 42, -42);
    printf("**%5d**%5.3d**%05d**%05.3d**
", 6, 6, 6, 6);

    return 0;
}
输出结果,在有精度的情况下,多余的0会被忽略。
1f 1F 0X1F
**42** 42**-42**
**    6**  006**00006**  006**

字符串格式的例子:

#include <stdio.h>
#define BLURB "Authentic imitation!"

int main(void) {

    printf("[%2s]
", BLURB);
    printf("[%24s]
", BLURB);
    printf("[%24.5s]
", BLURB);
    printf("[%-24.5s]
", BLURB);

    return 0;
}

结果如下,对于.5则是只打印5个字符

[Authentic imitation!]
[    Authentic imitation!]
[                   Authe]
[Authe                   ]

4.printf的返回值

大部分的C函数都有一个返回值,printf函数返回打印字符的个数。如果输出错误,printf则返回一个负值。

5.跨行打印

使用反斜杠,注意第二行代码不要缩进,如果缩进每个空格都会成为字符串的一部分。

printf("here is a way to print a  
long string.
")

6.scanf函数的基本使用

对于scanf函数和printf函数类似,不过scanf函数会使用指针。如果scanf函数读取基本变量的值,则使用指针,如果把字符串读入字符数组,不要使用&。

int main(void) {
    int age;
    float assets;
    char pet[30];

    printf("Enter your age, assets, and favorite pet.
");
    scanf("%d %f", &age, &assets);
    scanf("%s", pet);
    printf("%d $%.2f %s
", age, assets, pet);

    return 0;
}

输出结果:

Enter your age, assets, and favorite pet.
38
92360.88 llama
38 $92360.88 llama

7.scanf的转换说明

scanf的转换说明与printf的转换说明几乎相同,主要区别在于多了%c这个把整个输入变成字符,和float类型和double类型中,printf会区分%f%e%F%g%G,而scanf()只把他用于float类型,double类型要使用l修饰符。

转换说明比较复杂在这里就不列出了。

scanf函数的转换说明与输入字符会严格匹配。

比如

scanf("%d,%d", &n, &m);

用户必须在n的后面输入一个逗号,否则scanf会跳过所有空白。

类似下面的输入是合法的:

88, 121

88,       121

88  ,  121

8.scanf的返回值

scanf函数返回成功读取的项数,如果没有,则返回0.当检测到”文件结尾”,会返回EOF。

9.printf和scanf函数的修饰符*

printf和scanf都可以用*修饰符来修改转换说明,但是用法不一样。下面是printf使用变宽输出的例子

#include <stdio.h>

int main(void) {
    unsigned width, precision;
    int number=256;
    double weight=242.5;

    printf("Enter a field 
");
    scanf("%d", &width);
    printf("The number is:%*d:
", width, number);
    printf("Now enter a width and a precision:
");
    scanf("%d %d", &width, &precision);
    printf("weight=%*.*f
", width, precision, weight);

    return 0;
}

输出结果如下:

Enter a field 
6
The number is:   256:
Now enter a width and a precision:
8 3
weight= 242.500

但是scanf用法不同,如果放在%和字符之间,就会跳过相应输出。

10.总结

转换说明的意义:转换说明把以二进制格式储存在计算机中的值转换成一系列字符来显示。实际上,转换是一种翻译说明。比如把01001100, %d转换将其翻译为字符7和6.

转换说明应该与待打印值的类型相匹配,否则就会出现问题。