目录
第一天
数据类型
整型类型
浮点类型
void类型
基本类型书写
printf函数规定符列举
转义字符列举
字节对齐:
条件注释注释:#if0 #endif
第二天
printf()函数:
scanf()函数:scanf(参数,&地址)
getchar putchar
运算符
声明变量和定义变量的区别是什么?
变量的三大属性:作用域、链接属性、存储属性。
作用域:
链接属性
存储属性
堆栈的不同:
其他区域(或者其他叫法)
二维数组
ASCII码对照表
数组指针
指针数组
字符数组
第三天
函数指针
指针函数
typedef关键字
结构体
大小端判断
文件句柄 :
C的关键字
C语言的预处理
位运算
积累例题
switch case的执行总结:
c---清空stdin
scanf("%d",&n); 但输入字符
\ddd转义字符表示8进制数(\d,\dd都行最多3个),算一个字符,如'A'='\101' , \xdd转义字符表示16进制数算一个字符 , 'A'='x41'
可以一用#pramga pack(n); 设置字节对齐数。
指定数据类型的变量存放的起始地址数值必须是其对应数据类型所占字节的整数倍
上图中:结构体C的成员占据10个字节,而结构体C的有效对齐值是其成员b的自身对齐值4,10不是4的倍数,故还需补齐两个字节,此时结构体C占据12个字节,是4的倍数。
printf("%-10d\n",60); //左对齐60后面补齐10个空格
printf("%10d\n",60); //右对齐60前面补齐10个空格
printf("%10.3f\n",1.12356); //%10.3f作用为:四舍五入保留3位有效数字 所以输出为1.124
printf("%f\n",12345678e-5); //小数的指数法输出123.456790 因为float为单精度浮点数,只能保留6位有效数字
可以成对嵌套使用:
#if 0
sss #endif
int m;
m=printf("Hello World!\n");
printf("m=%d\n",m);
输出为:m=13.
printf()函数里'\n'的含义:
(1)换行
(2)将输出缓冲区中的所有字符输出
(1)第一个参数字符里不能有换行符 \n
(2)从第二参数起,必须是变量地址
(3)在两个数据之间可以用一个或多个空格、tab 键、回车键分隔
(4)在用 %c 输入时,空格和"转义字符"均作为有效字符。
scanf 类型说明符:
类型 | 合格的输入 | 参数的类型 |
---|---|---|
%a、%A | 读入一个浮点值(仅 C99 有效)。 | float * |
%c | 单个字符:读取下一个字符。如果指定了一个不为 1 的宽度 width,函数会读取 width 个字符,并通过参数传递,把它们存储在数组中连续位置。在末尾不会追加空字符。 | char * |
%d | 十进制整数:数字前面的 + 或 - 号是可选的。 | int * |
%e、%E、%f、%F、%g、%G | 浮点数:包含了一个小数点、一个可选的前置符号 + 或 -、一个可选的后置字符 e 或 E,以及一个十进制数字。两个有效的实例 -732.103 和 7.12e4 | float * |
%i | 读入十进制,八进制,十六进制整数 。 | int * |
%o | 八进制整数。 | int * |
%s | 字符串。这将读取连续字符,直到遇到一个空格字符(空格字符可以是空白、换行和制表符)。 | char * |
%u | 无符号的十进制整数。 | unsigned int * |
%x、%X | 十六进制整数。 | int * |
%p | 读入一个指针 。 | |
%[] | 扫描字符集合 。 | |
%% | 读 % 符号。 |
实例:
scanf("%d%d",&m,&n);
printf("%d,%d",m,n);
输入为:12 15(中间有空格) 输出为:12,15
int m,n;
scanf("%d,%d",&m,&n);
printf("%d,%d\n",m,n);
输入为:12 ,15(中间必须有‘,’且',' 前一定要紧跟在数字后面,数字与 ', '之间不能有空格) 输出为:12,15
scanf("%c%c%c",&a,&b,&c);
printf("%c,%c,%c\n", a,b,c); return 0; }
产生以下结果:
$ ./a.out 请输入三个字符:run r,u,n $ ./a.out 请输入三个字符:r u n r, ,u
printf("请输入用户名:");
scanf("%s", str1);
printf("请输入您的网站:");
scanf("%s", str2);
printf("输入的用户名:%s\n", str1);
printf("输入的网站:%s", str2);
运行结果为:
请输入用户名:admin 请输入您的网站:www.runoob.com 输入的用户名:admin 输入的网站:www.runoob.com
while((c = getchar()) != EOF){ putchar(c); }
上述结果, 必须输入是文件结束符EOF,Windows下为组合键Ctrl+Z, Unix/Linux下为组合键Ctrl+D,getchar才会停止执行,循环才能结束,整个程序将会往下执行
#include "stdio.h"
main()
{
char
c,d,e,f;
printf
(
"please input two characters:\n"
);
c=
getchar
();
putchar
(c);
putchar
(
'\n'
);
d=
getchar
();
putchar
(d);
putchar
(
'\n'
);
e=
getchar
();
putchar
(e);
putchar
(
'\n'
);
f=
getchar
();
putchar
(f);
putchar
(
'\n'
);
printf
(
"c= %c\n"
,c);
printf
(
"d= %c\n"
,d);
printf
(
"e= %c\n"
,e);
printf
(
"f= %c\n"
,f);
}
运行后先输入“12”,回车,再输入“34”,回车。运行流程:
printf("int_%lu\n",sizeof (int));
运行结果:int_4
a=10; b = a+=a*=a-=a+a;
运算过程即:a+a=20; a=a-20=-10; a=a*a=100; a=a+a=200; b=a=200;
C语言的运算符包括单目运算符、双目运算符、三目运算符,优先级如下:
1、最高级:出现同级别运算符时的结合方向是从左往右(下面级别没写结合顺序时,默认是从左往右)。
( )圆括号
[ ]下标运算符号
->指向结构体成员运算符
.结构体成员运算符
2、第二级:!、~、++、--、-、(类型)、*、&、sizeof。
这一级都是单目运算符号,这一级的结合方向是从右向左。
比如出现*p++,这时*和++同级别,先算右边,再左边。
所以*p++等价于*(p++),而不是(*p)++。
3、第三级:+、-、*、/、%
这一级都是算术运算符,结合顺序和数学学习中一致的,先乘除取余数,后加减。
4、第四级:<<、>>
这是左移、右移运算符,位运算时可能需要用到。
5、第五级:<、<=、>、>=、!=、==
这些运算符也称为关系运算符,其中<、<=、>、>=高于!=、==。
6、第六级:&、^、|
这三个符号也是位运算符号,其中内优先级,&>^>|。
7、第七级:&&、||
逻辑与&&优先级大于逻辑或||。
8、第八级:? :
也称为条件运算符号,是C语言中唯一的一个三目运算符,结合顺序是从右往左。
9、第九级:=、+=、-+、*=、/=、%=
这些运算符也叫做赋值运算符,除此之外,>>=、<<=、&=、^=、|=这些赋值运算符也在这一级别内,结合顺序是从右往左。
10、最低级:,
逗号运算符也称为顺序求值运算符,在C语言中,运算级别最低。
(此处转载)
什么是定义,什么是声明
变量的使用范围:
判断标准:
void fun(int a); //函数声明(原型)
int a=100; //全局变量
int main()
{
int a = 200; //函数内定义变量
{
int a = 300; //代码块内定义变量
}
fun(500);
return 0;
}
void fun(int a) //函数定义
{
printf("a4");
}
同一项目不同文件中的相同名称的变量是否是同一变量。
判断标准:
变量存放在内存的哪个区域:
从编译开始就占用内存,直到项目运行结束,内存被操作系统回收
用时申请内存,不用系统释放内存。栈的分配运算内置于处理器的指令集中,效率极高,但是分配的内存容量有限。存储在栈中的对象,遇到 ' } ' ,即删除局部变量,不会有有内存碎片。
程序员向操作系统申请的内存空间。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。可存储较大的数据。堆是以匿名方式保存的,只能通过指针访问,安全性最高,由程序员分配与释放,自由度最高。
(1)内存申请方式的不同:如果函数中声明一个局部变量int a,系统会自动在栈中为a 开辟空间;而堆空间需要程序员自己申请,还需要指明变量的大小。
(2)系统响应的不同:只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则提示overflow,栈溢出;而对于堆,系统在收到申请空间的要求后,遍历操作系统用于记录内存空间地址的链表,当找到一个空间大于所申请空间的堆结点后,就会将该结点从记录内存空闲地址的链表中删除。并将该结点的内存分配给程序,然后在这块内存区域的首地址处记录分配的大小。这样在使用delete来释放的时候,delete才能正确识别并删除该内存区域的所有变量。另外,申请的内存空间与堆结点的内存空间不一定相等,这是系统个会自动将堆结点上多出来的那一部分内存空间回收到空闲链表中。
(3)空间大小的不同:栈是一块连续的区域,大小在编译时就确定的常数,有系统预先根据栈顶的地址和栈的最大容量定义好的;堆是不连续的区域,各块区域由链表串联起来。串联起来的内存空间叫作堆!上限是由系统的虚拟内存来定的。
(4)执行效率的不同:栈比较快,由系统自动分批;堆速度较慢,且容易产生内存碎片。
(5)执行函数时的不同:函数调用时,第一个进栈的是被调函数下一行的内存地址(栈的先进后出)。其次是函数的参数,假如参数多于一个,那么次序是从右往左。最后才是函数的局部变量。
(1)数据段(属于数据存储区)是存取全局变量和静态变量的。全局变量和静态变量是放在一块的,初始化的在一块区域,未初始化的在相邻的另一块区域。程序结束后由系统释放。
(2)代码段是存取函数体的二进制代码的。
(3)文字常量区,常量和字符串就放在这里,程序结束之后由系统释放。
(4)寄存器区,用来保存栈顶指针和指令指针。
****************************************************************************
与存储类型相关的几个属性:
一维数组数组名: 数组首元素的地址
a <=====> &a[0] *a <=======> a[0]
地址是有类型的,地址+1 相当于是加了一个类型的字节
a+1 <=====> &a[1]
a+i <====>&a[i] ; *(a+i) <======>a[i]
二维数组:
&b[0][0] -----------> 第0个一维数组第0个int型的地址
b ------------> 第0个一维数组的地址
&b ------------> 二维数组本身的地址
*b ------------> 第0个一维数组第0个int型的地址
b[0] ------------> 第0个一维数组第0个int型的地址
b+i ---------------> 第i个一维数组的地址
*(b+i) -------------> 第i个一维数组的首元素地址
*(b+i)+j --------> 第i个一维数组的第j个元素的地址 <=======> &b[i][j]
*(*(b+i)+j) -----> 第i个一维数组的第j个元素的值 <=======> b[i][j]
b[i] + j -----------> 第i个一维数组的第j个元素的地址 <=======> &b[i][j]
*(b[i] + j) ---------> 第i个一维数组的第j个元素的值 <=======> b[i][j]
二进制 | 十进制 | 十六进制 | 字符/缩写 | 解释 |
---|---|---|---|---|
00000000 | 0 | 00 | NUL (NULL) | 空字符 |
00000001 | 1 | 01 | SOH (Start Of Headling) | 标题开始 |
00000010 | 2 | 02 | STX (Start Of Text) | 正文开始 |
00000011 | 3 | 03 | ETX (End Of Text) | 正文结束 |
00000100 | 4 | 04 | EOT (End Of Transmission) | 传输结束 |
00000101 | 5 | 05 | ENQ (Enquiry) | 请求 |
00000110 | 6 | 06 | ACK (Acknowledge) | 回应/响应/收到通知 |
00000111 | 7 | 07 | BEL (Bell) | 响铃 |
00001000 | 8 | 08 | BS (Backspace) | 退格 |
00001001 | 9 | 09 | HT (Horizontal Tab) | 水平制表符 |
00001010 | 10 | 0A | LF/NL(Line Feed/New Line) | 换行键 |
00001011 | 11 | 0B | VT (Vertical Tab) | 垂直制表符 |
00001100 | 12 | 0C | FF/NP (Form Feed/New Page) | 换页键 |
00001101 | 13 | 0D | CR (Carriage Return) | 回车键 |
00001110 | 14 | 0E | SO (Shift Out) | 不用切换 |
00001111 | 15 | 0F | SI (Shift In) | 启用切换 |
00010000 | 16 | 10 | DLE (Data Link Escape) | 数据链路转义 |
00010001 | 17 | 11 | DC1/XON (Device Control 1/Transmission On) |
设备控制1/传输开始 |
00010010 | 18 | 12 | DC2 (Device Control 2) | 设备控制2 |
00010011 | 19 | 13 | DC3/XOFF (Device Control 3/Transmission Off) |
设备控制3/传输中断 |
00010100 | 20 | 14 | DC4 (Device Control 4) | 设备控制4 |
00010101 | 21 | 15 | NAK (Negative Acknowledge) | 无响应/非正常响应/拒绝接收 |
00010110 | 22 | 16 | SYN (Synchronous Idle) | 同步空闲 |
00010111 | 23 | 17 | ETB (End of Transmission Block) | 传输块结束/块传输终止 |
00011000 | 24 | 18 | CAN (Cancel) | 取消 |
00011001 | 25 | 19 | EM (End of Medium) | 已到介质末端/介质存储已满/介质中断 |
00011010 | 26 | 1A | SUB (Substitute) | 替补/替换 |
00011011 | 27 | 1B | ESC (Escape) | 逃离/取消 |
00011100 | 28 | 1C | FS (File Separator) | 文件分割符 |
00011101 | 29 | 1D | GS (Group Separator) | 组分隔符/分组符 |
00011110 | 30 | 1E | RS (Record Separator) | 记录分离符 |
00011111 | 31 | 1F | US (Unit Separator) | 单元分隔符 |
00100000 | 32 | 20 | (Space) | 空格 |
00100001 | 33 | 21 | ! | |
00100010 | 34 | 22 | " | |
00100011 | 35 | 23 | # | |
00100100 | 36 | 24 | $ | |
00100101 | 37 | 25 | % | |
00100110 | 38 | 26 | & | |
00100111 | 39 | 27 | ' | |
00101000 | 40 | 28 | ( | |
00101001 | 41 | 29 | ) | |
00101010 | 42 | 2A | * | |
00101011 | 43 | 2B | + | |
00101100 | 44 | 2C | , | |
00101101 | 45 | 2D | - | |
00101110 | 46 | 2E | . | |
00101111 | 47 | 2F | / | |
00110000 | 48 | 30 | 0 | |
00110001 | 49 | 31 | 1 | |
00110010 | 50 | 32 | 2 | |
00110011 | 51 | 33 | 3 | |
00110100 | 52 | 34 | 4 | |
00110101 | 53 | 35 | 5 | |
00110110 | 54 | 36 | 6 | |
00110111 | 55 | 37 | 7 | |
00111000 | 56 | 38 | 8 | |
00111001 | 57 | 39 | 9 | |
00111010 | 58 | 3A | : | |
00111011 | 59 | 3B | ; | |
00111100 | 60 | 3C | < | |
00111101 | 61 | 3D | = | |
00111110 | 62 | 3E | > | |
00111111 | 63 | 3F | ? | |
01000000 | 64 | 40 | @ | |
01000001 | 65 | 41 | A | |
01000010 | 66 | 42 | B | |
01000011 | 67 | 43 | C | |
01000100 | 68 | 44 | D | |
01000101 | 69 | 45 | E | |
01000110 | 70 | 46 | F | |
01000111 | 71 | 47 | G | |
01001000 | 72 | 48 | H | |
01001001 | 73 | 49 | I | |
01001010 | 74 | 4A | J | |
01001011 | 75 | 4B | K | |
01001100 | 76 | 4C | L | |
01001101 | 77 | 4D | M | |
01001110 | 78 | 4E | N | |
01001111 | 79 | 4F | O | |
01010000 | 80 | 50 | P | |
01010001 | 81 | 51 | Q | |
01010010 | 82 | 52 | R | |
01010011 | 83 | 53 | S | |
01010100 | 84 | 54 | T | |
01010101 | 85 | 55 | U | |
01010110 | 86 | 56 | V | |
01010111 | 87 | 57 | W | |
01011000 | 88 | 58 | X | |
01011001 | 89 | 59 | Y | |
01011010 | 90 | 5A | Z | |
01011011 | 91 | 5B | [ | |
01011100 | 92 | 5C | \ | |
01011101 | 93 | 5D | ] | |
01011110 | 94 | 5E | ^ | |
01011111 | 95 | 5F | _ | |
01100000 | 96 | 60 | ` | |
01100001 | 97 | 61 | a | |
01100010 | 98 | 62 | b | |
01100011 | 99 | 63 | c | |
01100100 | 100 | 64 | d | |
01100101 | 101 | 65 | e | |
01100110 | 102 | 66 | f | |
01100111 | 103 | 67 | g | |
01101000 | 104 | 68 | h | |
01101001 | 105 | 69 | i | |
01101010 | 106 | 6A | j | |
01101011 | 107 | 6B | k | |
01101100 | 108 | 6C | l | |
01101101 | 109 | 6D | m | |
01101110 | 110 | 6E | n | |
01101111 | 111 | 6F | o | |
01110000 | 112 | 70 | p | |
01110001 | 113 | 71 | q | |
01110010 | 114 | 72 | r | |
01110011 | 115 | 73 | s | |
01110100 | 116 | 74 | t | |
01110101 | 117 | 75 | u | |
01110110 | 118 | 76 | v | |
01110111 | 119 | 77 | w | |
01111000 | 120 | 78 | x | |
01111001 | 121 | 79 | y | |
01111010 | 122 | 7A | z | |
01111011 | 123 | 7B | { | |
01111100 | 124 | 7C | | | |
01111101 | 125 | 7D | } | |
01111110 | 126 | 7E | ~ | |
01111111 | 127 | 7F | DEL (Delete) | 删除 |
比如:int (*p)[4]。则p可以表示一个长度为4的int型的一维数组,sizeof(p)==8(64位系统)。 对二位数组用数组指针输入输出的代码如下
int main(){ int (*p)[4],a[2][4]; for (p=a;p
比如:int*p[4]。则表示包含4个int类型的指针,sizeof(p)==32(64位操作系统)。 对二位数组用指针数组输入输出代码如下:
int main() { int *p[2],a[2][4],i,j; for (i=0;i<2;++i) { p[i]=a[i]; } for (i=0;i<2;++i) { for (j=0;j<4;++j) { scanf("%d",*(p+i)+j); } } for (i=0;i<2;++i) { for (j=0;j<4;++j) { printf("%5d",*(p[i]+j)); } printf("\n"); } return 0; }
int a[5]={1,2,3,4,5},b[5];
memcpy(b,a,sizeof(a));
memcset(a,0,sizeof(a));
可以在是代码更简洁并在一定程度节约内存;如当你需要返回一个数组中的元素时,你就只需返回首元素的地址给调用函数,调用函数即可操作该数组(让函数返回多个值)。
或者是malloc函数动态分配内存,返回该内存的地址给另外一个函数,另一个函数才好操作该内存。
转载链接:https://blog.csdn.net/weixin_40315804/article/details/79283397
#include
typedef union BIAN{ int a; int b; char c; }BIAN; int main() { BIAN test_bian; test_bian.a=0x12345678; printf("c=0x%x\n",test_bian.c); //利用联合体 printf("c=0x%x\n",*(char *)&test_bian.a); //利用强转 return 0; }
打开文件 pf = fopen(文件路径文件名, 打开方式);
#include
typedef struct student{ int sum; char name[20]; }STU; int main() { STU array[5]={ {100,"zhangsan0"},{101,"zhangsan1"},{102,"zhangsan2"},{103,"zhangsan3"},{104,"zhangsan4"}}; FILE *fp; fp=fopen("mystudent.txt","w+"); int retwrite = fwrite(array,sizeof(STU),5,fp); if(retwrite!=5){ printf("Write Error! "); return -1; } STU temp[5],*p=&temp; fseek(fp,0*sizeof (STU),0); int retreed = fread(&temp,sizeof (STU),5,fp); if(retreed){ for (int i=0;i<5;++i,p++) { printf("p num=%d,name=%s\n",p->sum,p->name); } } fclose(fp); return 0; }
int const a=10;
const int b=20;
int *const ptr; //表示指针的指向不可变,但指针指向的地址的内容可变。
int const *ptr; //表示指针的指向可变,但指针指向的地址的内容不可变。
int const *const ptr3; //指针的指向不可变,指针指向的地址的内容也不可变。
enum week
{
MON,TUS,WED,THE,FRI,SAT=10,SUN
};
enum week w1=MON;
enum week w2=SUN;
printf("MON=%d,SUN=%d",w1,w2);
输出: MON=0,SUN=11;
宏展开(替换)#define 定义宏,#undef 取消宏定义 ;文件包含(指令#include):相当于复制文件内容;条件编译 如#ifdef,#ifndef,#else,#elif,#endif;特殊符号,例如LINE标识将被解释为当前行号,FILE被解释为当前被编译的C源程序的名称。 最后生成以.i为后缀的文件
#define A(x,y) x+y
#define B(x,y) (x+y)
#undef B
对预编译之后的文件进行编译,将其翻译成等价的中间代码或汇编代码生成以.a为后缀的文件
将汇编代码翻译成目标机器指令的过程,每一个C语言源程序将得到相应的目标文件,也就是说,一个.c文件就会生成一个.obj文件,而这些文件还没有建立起练习,并不能相互调用
链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。在这一阶段,根据指定的同库函数的链接方式的不同,链接处理可分为静态链接和动态链接
a.静态链接 在这种链接方式下,函数的代码将从其所在地静态链接库中被拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。
b.动态链接 在此种方式下,函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码。
#include
int main() { char s[]={"0120\x30y"};int i,n=0; for(i=0;s[i]!='\0';i++) if(s[i]>='0'&&s[i]<='9') n++; printf("%d\n",n); return 0; } 输出结果为:5 因为\x30表示16进制,其值为10进制的48,也就是字符'0',所以算一个'0'~'9'之内的字符! \ddd表示8进制数,如\60为10进制的48,也就是字符'0'!
如switch(n),则优先找case 中的值能和n相等的语句执行,然后直到遇见break或者switch结束的}为止,才结束运行,在此过程中会可能运行其他case值不与n匹配的语句段。
若有定义语句:int x=10;,则表达式 x - = x + x 的值为 -10!
int main(){ char c1[]={'h','h','h'}; char c2[]={"hhh"}; char c3[10]={"hhh"}; printf("sizeof(c1)=%llu\n",sizeof (c1)); printf("sizeof(c2)=%llu\n",sizeof (c2)); printf("sizeof(c3)=%llu\n",sizeof (c3)); }
输出结果为: sizeof(c1)=3 sizeof(c2)=4 //以字符串的形式赋值给字符数组,会默认在后面添加一个'\0’结束符 sizeof(c3)=10
判断浮点型(float)和0值比较的的方式:(-1e-6, 1e-6) 即: if( flag >-1e-6 && flag <1e-6 ) 也就是flagj比-0.000001大并且比0.000001小,落在这个范围内,就认为其大致等于0了。
如果想从一个函数中获取一个结构体数组,最好不要把函数的返回值设置为结构体指针,而是把要赋值的结构体指针传到函数中,然后在函数中用for为该结构体指针赋值即可!!!
在使用C语言中的文件系统时,当写入文件用的是"wb"即以二进制的形式写入时,读的时候也必须用“rb”或“rb+”,即以二进制的形式读出,否则会出错!!!
转载枫继续吹
今天在Linux程序设计的时候需要清空标准输入缓冲区,于是使用了如下Windows程序设计中的方法:
1.fflush(stdin);这个fflush()函数根本不是标准C中的函数,只是标准C的扩展,所以在Linux中使用根本不行;
2.中网上搜索了下,发现有网友建议使用rewind(stdin);这个函数其实是将指针指向流的开始处。但是它是文件操作中的一个函数,操作的是FILE型流,在Windows程序设计中是可以清空标准输入缓冲区的,但是在Linux中不行。
3.通过读完标准缓冲区中的剩余字符并丢弃掉来清空标准缓冲区,使用的函数是getchar(),此函数的作用是从标准输入缓冲区中读出一个字符,此方法中Linux中可行。
如果需要清除stdin可以通过如下循环实现:
char ch;
while((ch=getchar())!='/n'&&ch!=EOF);
以上语句将清除stdin中的字符,知道遇到换行符或者是读完缓冲区。
以上的方法均可以在Windows程序设计中用来清除缓冲区;
4.在Linux程序设计中也还是有一种用来清空stdin中的方法,直接调用如下的函数:
setbuf(stdin, NULL);
此函数我还没有来得及测试;
通过以上分析,在Linux下清空stdin用两种方法:
1.通过读取剩余的字符并丢弃掉;
char ch;
while((ch=getchar())!='/n'&&ch!=EOF);
或者是:
char s[1024];
fgets(s,1024,stdin);
2.使用函数setbuf(stdin,NULL);
应当输入数字,如果输入字母,scanf 语句执行失败。
int flag;
flag = scanf("%d",&n);
if (flag== 1) printf("good\n"); else printf("bad\n");
flag = scanf("%d",&n); 送返成功读入的数据个数。拍入字母,flag 得0,n 原有值不变。
由于输入流里的你拍入的字母 没有被清掉,后面的输入语句连续执行失败。可以用 fflush(stdin); 清除 多余的东西。
#include
using namespace std;
int main(){
int tmp,t,a[1000],count=0;
while((t=scanf("%d",&tmp)) != EOF){
if(!t)
//scanf函数接收整型数字要跳过所有非数字的字符专接收数字。那么如果输入了字符它就一直留在输入缓冲区;
//只要缓冲区有字符,scanf就要去读,一读不是数字,它就跳过。
fflush(stdin);//此函数可以清除缓冲区中的字符
else
a[count++] = tmp;
}
for(int i=0; icout< }
return 0;
}
————————————————
版权声明:本文为CSDN博主「liubin477」的原创文章,遵循 CC 4.0 BY-SA 版权协议。
原文链接:https://blog.csdn.net/qq_36668065/article/details/80154588
总结:用scanf("%d",&x);为变量赋值整数时,应用以下代码过滤:(这是原创不是转载)
while(!scanf("%d",&x)) //若输入的不是数字,返回0,知道输入的是数字为止 { printf("[Warining] You must input number!\n"); fflush(stdin); //输入的不是数字就清空缓冲区 }
养成一个每次用完scanf()函数时就清空缓冲区。以免影响程序的正常运行。 为此,自己编写了一个过滤非数字输入的scanf函数:
#define INT 1
int a; myScanfInt(INT,&a);
void myScanfInt(int datatype,int *p) { if(datatype==INT) while(!scanf("%d",p)) { printf("[Waring] You must input a number!\n"); fflush(stdin); } fflush(stdin); }
删除e69da5e6ba90e799bee5baa6e997aee7ad9431333337616635文件部分内容的大概步骤:新建一个临时文件,把原文件内容向临时文件里拷贝,遇到要删除的内容就跳过。结束后关闭文件,用remove("原文件名");把原文件删除,用rename("临时文件名","原文件名");把临时文件名改为原文件名。2、例如在原文件123.txt中删除以2和以4编号开头的行,可用以下代码实现:
|
|