C\C++中 fopen中文件打开方式的区别:
在C语言中,大家常用到fopen打开文件,准备进行写操作,再用fwrite把数据写入文件,最后用fclose关闭文件。
如以下C代码:
#include <stdio.h>
char buf[10] = {10,10,10,10,10,10,10,10,10,10};
FILE *fp = fopen("c:\\test.dat","w");
fwrite(buf,1,10,fp);
fclose(fp);
FILE *fp1 = fopen("c:\\test1.dat","wb");
fwrite(buf,1,10,fp);
fclose(fp1);
我们注意到,程序的第一段定义一个数组,每个分量的值为:10,等价的十六进制为0A。
第二段,先是打开一个文件test.dat进行写操作,再是把10个数据写入文件,最后关闭文件。
第三段,功能差不多,只是文件名换成了test1.dat,打开文件的模式换成了wb.
第二段和第三段有什么区别呢?我们看一下最后的文件内容:
test.dat: 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A
test1.dat: 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A
原因是为什么呢?这就是w 和 wb的区别,w是以文本方式打开文件,wb是二进制方式打开文件,以文本方式打开文件时,fwrite函数每碰到一个0x0A时,就在它的前面加入0x0D.其它内容不做添加操作。
r 以只读方式打开文件,该文件必须存在。
r+ 以可读写方式打开文件,该文件必须存在。
rb+ 读写打开一个二进制文件,只允许读写数据。
rt+ 读写打开一个文本文件,允许读和写。
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
wb 只写打开或新建一个二进制文件;只允许写数据。
wb+ 读写打开或建立一个二进制文件,允许读和写。
wt+ 读写打开或着建立一个文本文件;允许读写。
at+ 读写打开一个文本文件,允许读或在文本末追加数据。
ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。
上述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件。
开始入门C++
#include<iostream>
using namespace std;
int main()
{
char name[10];
cout<<"my name:"<<"\n";
cin>>name;
cout<<name<<"\n";
return 0;
}
1、输出语句cout 的使用
#include<iostream>
using namespace std;
int main()
{
int a,b;
float f;
a=100;
b=200;
cout<<"a="<<a<<endl;
cout<<"b="<<b<<endl;
cout<<"a+b="<<a+b<<endl;
cout<<"a/b="<<(f=((float)a/(float)b))<<endl;
cout<<"f="<<f<<endl;
cout<<"---换行---\n";
cout<<"整数输出形式控制\n";
cout<<dec<<"100的十进制"<<a<<endl;
cout<<hex<<"100的十六进制"<<a<<endl;
return 0;
}
2、std的作用
因为#include <iostream>
它包含了一个类,在类的使用之前要预处理一下,using namespace std;就是这个功能,然后你就可以使用cin,cout这两个成员函数了,假设你不使用预处理(using namespace std;),麻烦加上std::cin或者std::cout再去使用它的成员函数(头文件中存在这个类)
#include<iostream>
//using namespace std;注释掉
int main()
{
int a,b;
float f;
a=100;
b=200;
std::cout<<"a="<<a<<std::endl;
std::cout<<"b="<<b<<std::endl;
std::cout<<"a+b="<<a+b<<std::endl;
std::cout<<"a/b="<<(f=((float)a/(float)b))<<std::endl;
std::cout<<"f="<<f<<std::endl;
std::cout<<"---换行---\n";
std::cout<<"整数输出形式控制\n";
std::cout<<std::dec<<"100的十进制"<<a<<std::endl;
std::cout<<std::hex<<"100的十六进制"<<a<<std::endl;
return 0;
}
数据类型
char 1 -128到126
unsigned char 1 0到255
short 2 -32,768到32,767
unsigned short 2 0到65,535
long 4 -2,147,483,648到2,147,483,648
unsigned long 4 0到4,294,967,295
int 4 同long
unsigned int 4 同unsigned long
float 4 1.2E-38到3.4E381
double 8 2.2E-308到1.8E3082
bool 1 true或false
1、布尔型0–假false;1–真true
bool bool_var=1
or bool bool_var=true;
2、wchar_t双字节型变量
char 型变量可以存储一个字节的字符,只能用来保存英文字符和标点符号。
存储汉字、韩文与日文不可以,因为这个文字占据有两个字节。
C++引入 wchar_t 类型(双字节类型,又名宽字符类型)来解决。
定义:wchar_t wt[] = L"阿里巴巴";
宽字符输出:wcout << wt;
#include<iostream>
#include<locale>
using namespace std;
int main(){
setlocale(LC_ALL, "chs");
wchar_t wt[] = L"阿里巴巴";
wcout << wt;
return 0;
}
3、常量
使用const定义:const float price=12.1234;
有数据类型
使用#define定义:#define PRICE 12.1234;
(不占内存)没有数据类型 or #define CMD "ABCD";
(占内存)没有数据类型
4、枚举类型enum
定义:enum [enumeration_name] {iteam1[=value1].iteam2[=value2],...};
枚举值是常量,不是变量。不能在程序中用赋值语句再对它赋值。只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量
enum weekday {sun,mon,tue,wed,thu,fri,sat } a,b,c;
a=sum;
b=mon;
是正确的。而:
a=0;
b=1;
是错误的。如一定要把数值赋予枚举变量,则必须用强制类型转换。
如:a=(enum weekday)2;
其意义是将顺序号为2的枚举元素赋予枚举变量a,相当于:a=tue;
运算符
优先级 | 操作符 | 描述 | 例子 | 结合性 |
---|---|---|---|---|
1 | () [] -> . :: ++ – | 调节优先级的括号操作符 数组下标访问操作符 通过指向对象的指针访问成员的操作符 通过对象本身访问成员的操作符 作用域操作符 后置自增操作符 后置自减操作符 | (a + b) / 4; array[4] = 2; ptr->age = 34; obj.age = 34; Class::age = 2; for( i = 0; i < 10; i++ ) … for( i = 10; i > 0; i– ) … | 从左到右 |
2 | ! ~ ++ – - + * & (type) sizeof | 逻辑取反操作符 按位取反(按位取补) 前置自增操作符 前置自减操作符 一元取负操作符 一元取正操作符 解引用操作符 取地址操作符 类型转换操作符 返回对象占用的字节数操作符 | if( !done ) … flags = ~flags; for( i = 0; i < 10; ++i ) … for( i = 10; i > 0; –i ) … int i = -1; int i = +1; data = *ptr; address = &obj; int i = (int) floatNum; int size = sizeof(floatNum); | 从右到左 |
3 | ->* .* | 在指针上通过指向成员的指针访问成员的操作符 在对象上通过指向成员的指针访问成员的操作符 | ptr->*var = 24; obj.*var = 24; | 从左到右 |
4 | * / % | 乘法操作符 除法操作符 取余数操作符 | int i = 2 * 4; float f = 10 / 3; int rem = 4 % 3; | 从左到右 |
5 | + - | 加法操作符 减法操作符 | int i = 2 + 3; int i = 5 - 1; | 从左到右 |
6 | << >> | 按位左移操作符 按位右移操作符 | int flags = 33 << 1; int flags = 33 >> 1; | 从左到右 |
7 | < <= > >= | 小于比较操作符 小于或等于比较操作符 大于比较操作符 大于或等于比较操作符 | if( i < 42 ) … if( i <= 42 ) … if( i > 42 ) … if( i >= 42 ) … | 从左到右 |
8 | == != | 等于比较操作符 不等于比较操作符 | if( i == 42 ) … if( i != 42 ) … | 从左到右 |
9 | & | 按位与操作符 | flags = flags & 42; | 从左到右 |
10 | ^ | 按位异或操作符 | flags = flags ^ 42; | 从左到右 |
11 | | | 按位或操作符 | flags = flags | 42; | 从左到右 |
12 | && | 逻辑与操作符 | if( conditionA && conditionB ) … | 从左到右 |
13 | || | 逻辑或操作符 | if( conditionA || conditionB ) … | 从左到右 |
14 | ? : | 三元条件操作符 | int i = (a > b) ? a : b; | 从右到左 |
15 | = += -= *= /= %= &= ^= |= <<= >>= | 赋值操作符 复合赋值操作符(加法) 复合赋值操作符(减法) 复合赋值操作符(乘法) 复合赋值操作符(除法) 复合赋值操作符(取余) 复合赋值操作符(按位与) 复合赋值操作符(按位异或) 复合赋值操作符(按位或) 复合赋值操作符(按位左移) 复合赋值操作符(按位右移) | int a = b; a += 3; b -= 4; a *= 5; a /= 2; a %= 3; flags &= new_flags; flags ^= new_flags; flags |= new_flags; flags <<= 2; flags >>= 2; | 从右到左 |
16 | , | 逗号操作符 | for( i = 0, j = 0; i < 10; i++, j++ ) … | 从左到右 |
控制语句
①if( )~else 条件语句
②for( )~ 循环语句
③while( )~ 循环语句
④do~while( ) 循环语句
⑤continue 结束本次循环语句
⑥break 中止执行switch或循环语句
⑦switch 多分支选择语句
⑧goto 转向语句
⑨return 从函数返回语句
#include<iostream>
using std::cin;
using std::cout;
using std::endl;
int exp_z,exp_y;
int main()
{
char ch;
while(true)
{
cout<<"请输入两个整数,以空格分开"<<endl;
cout<<"退出的话请输入 q"<<endl;
cin.clear();//清除输入流的错误,只是为了保险起见
cin.sync();//同步输入流的,清空上次残余在输入流缓冲区的数据
ch=cin.peek();//返回下一个数据,但是不读取
if(ch=='q')
{
cout<<"执行完成,退出!"<<endl;
return 0;
}
cin>>exp_y>>exp_z;//读取输入的两个数字
if(exp_y>exp_z)
{
cout<<"比较大的是第一个数字"<<exp_y<<endl;
}
else
{
cout<<"比较大的是第二个数字"<<exp_z<<endl;
}
cout<<endl;
}
return 0;
}