文件处理
FILE * f1=open(‘file’,’r’) 读取文件file
FILE * f1=open(‘file’,’w’) 写入 文件file,如file不存在,则创建
-
fscanf(f1,正则表达式,输入列表);将f1文件指针指向的file,以正则表达式匹配,其中空格或tab会被跳过,将内容赋值给输入列表,每次只匹配一次正则表达式,并返回相应的匹配个数——当正则表达式与对应的数据不匹配时,将会返回错误的信息
返回值:成功时返回从流中读取成功的数据的个数。失败时返回-1(Debian Linux)。
1 原型
int fscanf(FILE stream, const char format, …)
功能: 从stream流中连续读取能够匹配format格式的字符到参数列表中对应的变量里。
参数: “stream”是FILE指针类型变量,它指向一个真实的流对象。
“format”是C字符串,由“空格”、“非空格”及“转换符”组成。具体格式为%[*][width][modifiers]type。见2.1与format参数相关的概念。
“…”是与“format”中“转换符”对应变量地址的列表,两地址间用逗号隔开。
返回值:成功时返回从流中读取成功的数据的个数。失败时返回-1(Debian Linux)。
头文件:< stdio.h>2 与format参数相关的概念
fscanf()的format参数允许的格式为:“%[*][width][modifiers]type”。[]中的内容根据需要供选,可缺省,%type必须要有,不可省。
%:是format参数的起始符号,不可缺少。以拥有3个数字行的最后一个数字决定拥有两个数字的行数 2.2.1 fscanf()对空格的处理 用fopen成功打开ffReadFile.dat文件后,单用以下语句读取文件的第一行内容: [cpp] view plaincopyprint? re = fscanf(pF, "%d%d%d", &oLine.p, &oLine.l, &oLine.x); if( 3 == re){ //Print on stdout printf("%d\t%d\t%d\n", oLine.p, oLine.l, oLine.x); } re = fscanf(pF, "%d%d%d", &oLine.p, &oLine.l, &oLine.x); if( 3 == re){ //Print on stdout printf("%d\t%d\t%d\n", oLine.p, oLine.l, oLine.x); }
此时,可以正确的打印第一行内容到屏幕之上。fscanf()函数读取第一行三个数据的过程如下:
Figure2:fscanf()函数读取数据过程
文件指针最开始指向ffReadFile.dat的第一个字符(即1)处,然后fscanf()根据“format”中的第一个“转换符”读取文件中的内容直到不符合当前“转换符”能够转换的字符为止,如果不符合“转换符”的数据为空格或者tab则舍掉空格或者tab使文件指针指向下一个数据。然后fscanf()继续在文件中匹配下一个“转换符”的数据。直到为所有的“转换符”匹配完数据为止。2.2.2 fscanf()对不符合“特定格式”数据的处理
当不符合“特定格式”所要求的数据且不为空格和tab时,fscanf()将匹配到符合“特定格式”的数据赋给地址后不再往下读。如现将ffReadFile.dat中的内容修改如下:3 使用fscanf()注意的地方
确保检查返回值,以确定找到了期待的值。而使用%s 格式的时候,一定要小心缓冲区溢出如:
# include<stdio.h> # include<stdlib.h> int main() { int fd; long dev; long offset; long length; char ch; double ts=0.000000; if((fd=fopen("/home/haixian/ceshi/data.txt","r"))<0) { printf("open the file is error!\n"); exit(0); } lseek(fd,0,SEEK_SET); while(5==fscanf(fd,"%ld,%ld,%ld,%c,%lf\n",&dev,&offset,&length,&ch,&ts)) {//在这里就是第二个参数指定分隔参数的格式,在这里使用的是,来分隔。这样就很容易的获取了记录的各个字段的值并不需要自己编写函数来进行解析什么的。 printf("%ld,%ld,%ld,%c,%lf\n",dev,offset,length,ch,ts); } close(fd); return 0; }
容器
1. vector
头文件#include < vector>
创建vector对象,vector< int> vec;
- vector的元素不仅仅可以是int,double,string,还可以是结构体,但是:结构体要定义为全局的,否则会出错
Vector作为函数的参数或者返回值时,需要注意它的写法:
double Distance(vector< int>&a, vector< int>&b) 其中的“&”绝对不能少
尾部插入数字:vec.push_back(a);
使用下标访问元素,cout<< vec[0]<< endl;记住下标是从0开始的。
使用迭代器访问元素.
vector<int>::iterator it; for(it=vec.begin();it!=vec.end();it++) cout<<*it<<endl;
插入元素: vec.insert(vec.begin()+i,a);在第i+1个元素前面插入a;
- 删除元素:vec.erase(vec.begin()+2);删除第3个元素;
- vec.erase(vec.begin()+i,vec.end()+j);删除区间[i,j-1];区间从0开始
- 向量大小:vec.size();
- 清空:vec.clear();
vector算法
使用reverse将元素翻转:需要头文件#include< algorithm>
reverse(vec.begin(),vec.end());将元素翻转,即逆序排列!
(在vector中,如果一个函数中需要两个迭代器,一般后一个都不包含)
使用sort排序:需要头文件#include< algorithm>
sort(vec.begin(),vec.end());(默认是按升序排列,即从小到大).
可以通过重写排序比较函数按照降序比较,如下:
定义排序比较函数:
bool Comp(const int &a,const int &b)
{return a>b;}
调用时:
sort(vec.begin(),vec.end(),Comp)//实现降序排列
2.map< key_type,value_type>
是一种键值对容器,< key,value>形式存在,类似于python中的字典,关键字key(在一个组map中key值存在唯一性),和关键字对应的值value
include< map>
赋值形式如下:
//头文件 include< map> map<int, string> ID_Name; // 1,使用{}赋值是从c++11开始的,因此编译器版本过低时会报错,如visual studio 2012 map<int, string> ID_Name = { { 2015, "Jim" }, { 2016, "Tom" }, { 2017, "Bob" } }; //2.使用[]赋值 ID_Name[2014]='jock'
- 插入值:
#include < iostream>
#include < map>
int main()
{
std::map< char, int> mymap;
// 插入单个值
mymap.insert(std::pair<char, int>('a', 100));
mymap.insert(std::pair<char, int>('z', 200));
//返回插入位置以及是否插入成功
std::pair<std::map<char, int>::iterator, bool> ret;
ret = mymap.insert(std::pair<char, int>('z', 500));
if (ret.second == false) {
std::cout << "element 'z' already existed";
std::cout << " with a value of " << ret.first->second << '\ n';
}
//指定位置插入
std::map<char, int>::iterator it = mymap.begin();
mymap.insert(it, std::pair<char, int>('b', 300)); //效率更高
mymap.insert(it, std::pair<char, int>('c', 400)); //效率非最高
//范围多值插入
std::map<char, int> anothermap;
anothermap.insert(mymap.begin(), mymap.find('c'));
// 列表形式插入
anothermap.insert({ { 'd', 100 }, {'e', 200} });
return 0;
}
取值方式:at和[]两种,使用at时,如果key不存在,则会报错,而不会打印[]值
//ID_Name中没有关键字2016,使用[]取值会导致插入 //因此,下面语句不会报错,但打印结果为空 cout<<ID_Name[2016].c_str()<<endl; //使用at会进行关键字检查,因此下面语句会报错 ID_Name.at(2016) = "Bob";
resize(n)
调整容器的长度大小,使其能容纳n个元素。
如果n小于容器的当前的size,则删除多出来的元素。
否则,添加采用值初始化的元素。
resize(n,t)
多一个参数t,将所有新添加的元素初始化为t。
参考:https://blog.csdn.net/shuzfan/article/details/53115922
pair
定义 :pair< first_type,second_type> p
pair是一种模板类型,每个pair都可以存储两个值,两个值的属性类型无限制,主要为了方便返回两个值的函数,而不用定义struct的麻烦。
赋值:
pair<int ,int >p (5,6); pair<int ,int > p1= make_pair(5,6); pair<string,double> p2 ("aa",5.0); pair <string ,double> p3 = make_pair("aa",5.0);
输出形式:利用pair的两个属性first和second(不是方法,是属性)
cout<<p1.first<<p1.second;
class 类
class类
- 构造函数——赋值,无返回值,与类名同名
- 析构函数——释放内存,无返回值,无参数,~类名
- public,private,protected
rand
srand((unsigned) time(NULL));//保证每次运行随机性,不能在循环中使用
rand()#
makefile
文件内容:
all: file1,file2
file1:File1.cpp
g++ File1.cpp -o fil1 -2
file2: File2.cpp
g++ File2.cpp -o fil2 -2
在Makefile目录下只需执行
make all
即可执行整个编译
target: a.cpp,a.h
g++ target
详细内容请参考:https://blog.csdn.net/ruglcc/article/details/7814546/
main(int argc, char *argv[])
- argc是命令行总的参数个数,(注意:文件名本身也算一个参数),argc的值是在输入命令行时由系统按实际参数的个数自动赋予的。不需要手动添加。即表示argv[]的数组长度
- argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数命令行后面跟的用户输入的参数(字符串参数),传入的只是字符串,不是相应的‘file’内的内容,如:text a.c 只是传入两个字符串:argv[0] = “test”argv[1] = “a.c”,a.c内容如是否正确,是否真的存在不得而知
- char *argv[]是一个字符串指针数组,其大小是int argc(系统自动统计),所以参数可以是任何形式的字符串,以空格相隔。
举例:test.cpp代码如下:
int main(int argc, char* argv[])
{
int i;
for (i=0;i<argc;i++)
cout<<argv[i]<<endl;//输入数组到argv[i]中
cin>>i; //输出数组argv[i]
return 0;
}
比如你输入:
test a.c b.txt stringdata
//实际参数为4个,即argc=4,argv长度为4(0-3)
输出如下:
test
a.c
b.txt
stringdata
即:
/*
argc = 4
argv[0] = “test”
argv[1] = “a.c”
argv[2] = “b.txt”
argv[3] = “stringdata”
*/
参考:https://blog.csdn.net/hopeneversleep/article/details/55798722
注:如需转载,篇头请务必标明出处及作者信息:
@洋石灰儿
@2018-5-21
@链接:https://blog.csdn.net/Yshihui/article/details/80388916