ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【C语言基础】字符串和格式化输入/输出

2022-07-26 22:01:49  阅读:216  来源: 互联网

标签:格式化 name scanf 打印 C语言 printf 字符串 define


字符串的介绍

数组由连续的存储单元组成,字符串中的字被存储在相邻的存储单元中,每个单元存储一个字符。在数组末尾位置的字符为\0,代表字符串的结束。

#define _CRT_SECURE_NO_WARNINGS 
#include<stdlib.h>
#include<stdio.h>
#include<string.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);
	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);
	// system("pause"); 
	return 0;
}

// 一般来说,根据%是转换说明,scanf只读取第一个单词,而不是一整句

// 当输入ding c时,scanf函数只读取到ding
// What's your name? ding c
// Hello, ding.You are an extraordinary being.
// Your name of 4 letters occupies 40 memory cells.
// The phrase of praise has 31 letters and occupies 32 memory cells.

// 当输入ding_c时,scanf可以读取到ding_c
// What's your name? ding_c
// Hello, ding_c.You are an extraordinary being.
// Your name of 6 letters occupies 40 memory cells.
// The phrase of praise has 31 letters and occupies 32 memory cells.
// 请按任意键继续. . .

// string.h头文件包含多个与字符串相关的函数原型,包括strlen()
// 用 strlen()得出的也是字符串中的字符数(包括空格和标点符号)。
// 然而,sizeof运算符给出的数更大,因为它把字符串末尾不可见的空字符也计算在内。
// 该程序并未明确告诉计算机要给字符串预留多少空间,所以它必须计算双引号内的字符数。

// sizeof 运算符,它以字节为单位给出对象的大小。
// strlen()函数给出字符串中的字符长度。因为 1 字节储存一个字符,读者可能认为把两种方法应用于字符串得到的结果相同,但事实并非如此。

在用scanf输入字符串时,不用在字符串末尾放入空字符,scanf在读取输入时就已经完成了这项工作,但是scanf在遇到空格后,会自动结束,也就是scanf只会读取一个单词,祥见上述程序的注解。

字符串和字符:
字符串常量"x":x+\0
字符常量'x':x

sizeof运算符:以字节为单位给出对象大小,计算范围包括空格、标点符号、空字符
strlen()函数:给出字符串中字符的长度,计算范围包括空格、标点符号

常量和c预处理器

在程序运行过程中,一个数会多次参与运行,且为了提高程序的可读性,一般设置一个变量来代替常量。

float pi=3.14;
circum=pi*diameter;
#define _CRT_SECURE_NO_WARNINGS 
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<limits.h> // 整型限制
#include<float.h> // 浮点型限制
#define PI 3.14159
int main()
{
    float area, circum, radius;

    // const int pi=3.14;//const是不可修改的变量
    // printf("pi=%d",pi);
    // pi=5; 
    // // 编辑器警告,表达式必须是可修改的左值C/C++
    // // 但是还是可以运行
    // printf("new_pi=%d\n",pi);


    printf("What is the radius of your pizza?\n");
    scanf("%f", &radius);
    area = PI * radius * radius;
    circum = 2.0 * PI *radius;
    printf("Your basic pizza parameters are as follows:\n");
    printf("circumference = %1.2f, area = %1.2f\n", circum,area);

    // What is the radius of your pizza?
    // 12
    // Your basic pizza parameters are as follows:
    // circumference = 75.40, area = 452.39
    // 请按任意键继续. . .

    printf("Some number limits for this system:\n");
    printf("Biggest int: %d\n", INT_MAX);
    printf("Smallest long long: %lld\n", LLONG_MIN);
    printf("One byte = %d bits on this system.\n", CHAR_BIT);
    printf("Largest double: %e\n", DBL_MAX);
    printf("Smallest normal float: %e\n", FLT_MIN);
    printf("float precision = %d digits\n", FLT_DIG);
    printf("float epsilon = %e\n", FLT_EPSILON);
    // Some number limits for this system:
    // Biggest int: 2147483647
    // Smallest long long: -9223372036854775808
    // One byte = 8 bits on this system.
    // Largest double: 1.797693e+308
    // Smallest normal float: 1.175494e-038
    // float precision = 6 digits
    // float epsilon = 1.192093e-007


    system("pause"); 
    return 0;
}

在上述程序中运行过程中,会反复调用pi,于是可以用c预处理器处理,只需要在主函数上面添加一行代码:

#define PI 3.14159

编译程序时,程序中所有的PI都会被替换成3.14159,这一过程被称为编译时替换。在运行程序时,程序中所有的替换均已完成。通常,这样定义的常量也称为明示常量。

格式:#define 符号常量名 符号常量的值

其中dfine还可以定义字符和字符串常量,前者使用单引号,后者使用双引号,如:

#define BEEP "Now you have done it!"
#define BEEP 'T'

const限定符

const定义的变量是一个只读变量,如:
const int a=12;//其中a在运行过程中值不能被更改,但在运行过程中可以打印,参与运算等

明示常量

C头文件limits.h和float.h分别提供了与整数类型和浮点类型大小限制相关的详细信息。每个头文件都定义了一系列供实现使用的明示常量。例如,limits.h头文件包含以下类似的代码:

#define INT_MAX +32767
#define INT_MIN -32768

limits.h中的一些明示常量,如下表所示:

float.h中的一些明示常量,如下表所示:

printf()和scanf()

这两个函数能让用户可以与程序交流,它们是输入/输出函数,或者简称I/O函数,虽然printf()是输出函数,scanf()是输入函数,但是它们的工作原理几乎相同。两个函数都使用格式字符串和参数列表。

printf()

printf打印输出函数,但打印时打印数据的指令要与待打印数据的类型相匹配,此时需要一些表示转换说明的符号,转换说明及其打印的输出结果:

printf( 格式字符串, 待打印项1, 待打印项2,...);

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

#include <stdio.h>
#define PAGES 959
#define BLURB "Authentic imitation!"
int main(void)
{

    const double RENT = 3852.99;// const变量

    // 打印数字
    printf("*%f*\n", RENT);
    // 打印浮点数
    printf("*%e*\n", RENT);
    // 打印科学计数法的方法输出
    printf("*%4.2f*\n", RENT);
    // 打印浮点数,字段宽度占4个字符,其中小数点2位
    printf("*%3.1f*\n", RENT);
    // 打印浮点数,字段宽度占3个字符,其中小数点1位
    printf("*%10.3f*\n", RENT);
    // 打印浮点数,字段宽度占10个字符,其中小数点3位
    printf("*%10.4E*\n", RENT);
    // 打印科学计数法的方法输出*3.8530E+003*,小数点后保留四位
    printf("*%+4.2f*\n", RENT);
    // 打印项显示符号,正的显示+,负的显示-,有10个字宽,字段宽度占10个字符,其中小数点3位
    printf("*%010.2f*\n", RENT);
    // 打印浮点数,字段宽度占10个字符,其中小数点3位
    printf("*%d*\n", PAGES);
    // %d:以十进制数打印
    printf("*%2d*\n", PAGES);
    // 打印以十进制数,字段宽度占2个字符
    printf("*%10d*\n", PAGES);
    // 打印使用10个字宽
    printf("*%-10d*\n", PAGES);
    // 打印项左对齐,有10个字宽

    // 打印字符串
    printf("[%2s]\n", BLURB);
    // 打印字宽为2的字符,由于字符串长度大于2,则整个都会打印
    printf("[%24s]\n", BLURB);
    // 打印字宽位24的字符串
    printf("[%24.5s]\n", BLURB);
    // 打印字宽为24的字符串,输出前5位
    printf("[%-24.5s]\n", BLURB);
    // 靠左打印,打印字宽为24的字符串,输出前5位


}
// 试试如何用一个语句打印以下格式的内容:
// The NAME family just may be $XXX.XX dollars richer!
// 这里,NAME和XXX.XX代表程序中变量(如name[40]和cash)的值。
// 可参考以下代码:
// printf("The %s family just may be $%.2f richer!\n",name,cash);

# include<stdio.h>
int main()
{
    char name[40];
    float cash;
    printf("please,write name:");
    scanf("%s",name);
    fflush (stdin);//清理缓冲区
    printf("enter cash:");
    scanf("%f",&cash);
    printf("The %s family just may be $%.2f richer!\n",name,cash);
}

当在C语言中需要两个及以上scanf,运行时却发现只能第一个可以输入,通过查询得知在C语言中,如果使用字符型变量(char类型)时在有连续输入两个及以上的情况下,很容易因为出现垃圾字符二导致程序的流程非法。因为第一个scanf输入后当我们点击enter时第一个存放字符串的(str1)并没有接受这个回车符,而是存入缓冲区中了,当执行第二个scanf时这个回车符就赋给(str2)了所以程序没有提示输入字符就直接执行下面程序了。解决方法:可以使用fflush (stdin);函数 此函数是清除缓冲区的,将此函数放到第一个scanf输入函数后即可。

#include <stdio.h>
#define PAGES 336
#define WORDS 65618
int main(void)
{
short num = PAGES;
short mnum = -PAGES;
printf("num as short and unsigned short: %hd %hu\n", num,num);
// num as short and unsigned short: 336 336
printf("-num as short and unsigned short: %hd %hu\n", mnum,mnum);
// -num as short and unsigned short: -336 65200
printf("num as int and char: %d %c\n", num, num);
// num as int and char: 336 P
printf("WORDS as int, short, and char: %d %hd %c\n",WORDS,WORDS,WORDS);
// WORDS as int, short, and char: 65618 82 R
return 0;
/*
代码说明:
首先,short int的大小是2字节;其次,系统使用二进制补码来表示有符号整数。这种方法,数字0~32767代表它们本身,而数字32768~65535则表示负数。其中,65535表示-1,65534表示-2,以此类推。因此,-336表示为65200(即, 65536-336)。所以被解释成有符号int时,65200代表-336;而被解释成无符号int时,65200则代表65200。一定要谨慎!一个数字可以被解释成两个不同的值。尽管并非所有的系统都使用这种方法来表示负整数,但要注意一点:别期望用%u转换说明能把数字和符号分开。
*/
}

scanf()

scanf()和 printf()类似,也使用格式字符串和参数列表。scanf()中的格式字符串表明字符输入流的目标数据类型。两个函数主要的区别在参数列表中。printf()函数使用变量、常量和表达式,而scanf()函数使用指向变量的指针。这里,读者不必了解如何使用指针,只需记住以下两条简单的规则:

如果用scanf()读取基本变量类型的值,在变量名前加上一个&;
如果用scanf()把字符串读入字符数组中,不要使用&。

复习题

2.假设下列示例都是完整程序中的一部分,它们打印的结果分别是什么?

a.printf("He sold the painting for $%2.2f.\n", 2.345e2);
// He sold the painting for $234.50.
// 2.345e2表示科学计数发,原始数值为234.5,打印时占两个字宽,小数两位
b.printf("%c%c%c\n", 'H', 105, '\41');
// Hi!:第一个字符正常输出,第二个对应ascll字母表查出是i,第三个所有的数字加上\按八进制表示,转换成十进制是33,对应ascll字母表查出是!
c.#define Q "His Hamlet was funny without being vulgar."printf("%s\nhas %d characters.\n", Q, strlen(Q));
// His Hamlet was funny without being vulgar.
//has 42 characters.
d.printf("Is %2.2e the same as %2.2f?\n", 1201.0, 1201.0);
// Is 1.20e+003 the same as 1201.00?

3.在第2题的c中,要输出包含双引号的字符串Q,应如何修改:

#define Q "\"His Hamlet was funny without being vulgar.\""
printf("%s\nhas %d characters.\n", Q, strlen(Q));

#define Q "His Hamlet was funny without being vulgar."
printf("\"%s\"\nhas %d characters.\n", Q, strlen(Q));

6.格式打印:

a.一个字段宽度与位数相同的十进制整数
// %d
b.一个形如8A、字段宽度为4的十六进制整数
// %4x
c.一个形如232.346、字段宽度为10的浮点数
// %10.3f
d.一个形如2.33e+002、字段宽度为12的浮点数
// %12.3e
e.一个字段宽度为30、左对齐的字符串
// %-30s

7.打印下面各项内容要分别使用什么转换说明?

a.字段宽度为15的unsigned long类型的整数
// %15lu
b.一个形如0x8a、字段宽度为4的十六进制整数
// %#4x
c.一个形如2.33E+02、字段宽度为12、左对齐的浮点数
// %-12.2E
d.一个形如+232.346、字段宽度为10的浮点数
// %+10.3f
e.一个字段宽度为8的字符串的前8个字符
// %8.8s

8.打印下面各项内容要分别使用什么转换说明?

a.一个字段宽度为6、最少有4位数字的十进制整数
// %6.4d
b.一个在参数列表中给定字段宽度的八进制整数
// %*o
c.一个字段宽度为2的字符
// %2c
d.一个形如+3.13、字段宽度等于数字中字符数的浮点数
// %+0.2f
e.一个字段宽度为7、左对齐字符串中的前5个字符
// %-7.5s

编程练习

1.编写一个程序,提示用户输入名和姓,然后以“名,姓”的格式打印出来。

2.编写一个程序,提示用户输入名和姓,并执行一下操作:
a.打印名和姓,包括双引号;
b.在宽度为20的字段右端打印名和姓,包括双引号;
c.在宽度为20的字段左端打印名和姓,包括双引号;
d.在比姓名宽度宽3的字段中打印名和姓。

3.编写一个程序,读取一个浮点数,首先以小数点记数法打印,然后以指数记数法打印。用下面的格式进行输出(系统不同,指数记数法显示的位数可能不同):
a.输入21.3或2.1e+001;
b.输入+21.290或2.129E+001;

4.编写一个程序,提示用户输入身高(单位:英寸)和姓名,然后以下面的格式显示用户刚输入的信息:
Dabney, you are 6.208 feet tall
使用float类型,并用/作为除号。如果你愿意,可以要求用户以厘米为单位输入身高,并以米为单位显示出来。

5.编写一个程序,提示用户输入以兆位每秒(Mb/s)为单位的下载速度和以兆字节(MB)为单位的文件大小。程序中应计算文件的下载时间。注意,这里1字节等于8位。使用float类型,并用/作为除号。该程序要以下面的格式打印 3 个变量的值(下载速度、文件大小和下载时间),显示小数点后面两位数字:
At 18.12 megabits per second, a file of 2.20 megabytes downloads in 0.97 seconds.

6.编写一个程序,先提示用户输入名,然后提示用户输入姓。在一行打印用户输入的名和姓,下一行分别打印名和姓的字母数。字母数要与相应名和姓的结尾对齐,如下所示:
Melissa Honeybee
7       8 
接下来,再打印相同的信息,但是字母个数与相应名和姓的开头对齐,如下所示:
Melissa Honeybee
7     8

7.编写一个程序,将一个double类型的变量设置为1.0/3.0,一个float类型的变量设置为1.0/3.0。分别显示两次计算的结果各3次:一次显示小数点后面6位数字;一次显示小数点后面12位数字;一次显示小数点后面16位数字。程序中要包含float.h头文件,并显示FLT_DIG和DBL_DIG的值。1.0/3.0的值与这些值一致吗?

8.编写一个程序,提示用户输入旅行的里程和消耗的汽油量。然后计算并显示消耗每加仑汽油行驶的英里数,显示小数点后面一位数字。接下来,使用1加仑大约3.785升,1英里大约为1.609千米,把单位是英里/加仑的值转换为升/100公里(欧洲通用的燃料消耗表示法),并显示结果,显示小数点后面 1 位数字。注意,美国采用的方案测量消耗单位燃料的行程(值越大越好),而欧洲则采用单位距离消耗的燃料测量方案(值越低越好)。使用#define 创建符号常量或使用 const 限定符创建变量来表示两个转换系数。

标签:格式化,name,scanf,打印,C语言,printf,字符串,define
来源: https://www.cnblogs.com/ding-c/p/16522775.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有