csv文件数据操作函数总结

在C++课程设计中,由于采用了csv格式存储数据,故对文件操作涉及较多,在此总结一下csv文件格式的数据处理函数。


####C++文件流

流,简单来说就是建立在面向对象基础上的一种抽象的处数据的工具。在流中,定义了一些处理数据的基本操作,如读取数据,写入数据等,程序员是对流进行所有操作的,而不用关心流的另一头数据的真正流向。流不但可以处理文件,还可以处理动态内存、网络数据等多种数据形式。如果你对流的操作非常熟练,在程序中利用流的方便性,写起程序会大大提高效率的。

####文件操作

以下类型需要包含头文件 < fstream>

ofstream 输出流:是从内存(控制台)读到硬盘;
ifstream 输入流:是从硬盘读到内存(控制台).
fstream 文件流:是可对打开的文件进行读写操作.

打开文件的方式 在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
ios::app 文件不存在则创建, 在原文件内容后写入新的内容,app即单词 [append:附加] 的缩写。
ios::ate 文件打开后定位到文件尾,ios:app就包含有此属性
ios::binary 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
ios::in 文件以输入方式打开(文件数据输入到内存),文件不存在则创建(ifstream默认的打开方式)
ios::out 文件以输出方式打开(内存数据输出到文件), 文件不存在则创建,若文件已存在则清空原内容(ofstream默认的打开方式)
以下几个不常用:
ios::nocreate 不建立文件,所以文件不存在时打开失败
ios::noreplace 不覆盖文件,所以打开文件时如果文件存在失败
ios::trunc 如果文件存在,把文件长度设为0

关闭文件:file.close(); //与new之后要delete一样,打开文件后必须关闭文件

例:ifstream file(“d:\\date.csv”,ios::app); //路径名中的\要双写

####使用函数:

1
2
3
4
5
6
7
 ch = file.get(); //去读一个字符,然后才能用eof判断是否为空 
if(file.eof()) //如果 一个字符都未读到,表示文件为空
{
....
}
//eof()函数要跟在读取语句后,用来判断是否读到文件结束符EOF。原因为:
//要清楚"文件结束符"(0xff).就是说我们文件最后的字符不是文件结束符,而最后的字符的下一位才是.所以操作再读多一次.

参考资料

####操作文件指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//ifstream和ofstream都提供了成员函数来重定位文件定位指针(文件中下一个被读取或写入的字节号)

//在ifstream中 这个成员函数为seekg("seek get");在ofstream中为seekp("seek put")

//输入流操作

seekg(绝对位置);  //绝对移动, 

seekg(相对位置,参照位置);  //相对操作

tellg();  //返回当前指针位置

//输出流操作

seekp(绝对位置);  //绝对移动, 

seekp(相对位置,参照位置);  //相对操作

tellp()和tellg()成员函数分别用来返回当前get和put的指针位置

参照位置:

ios::beg  //相对于文件头

ios::cur  //相对于当前位置

ios::end  //相对于文件尾

例: file.seekg(0,ios::end); //参照位置为文件结束处,相对位置为0,即相对于文件尾移动0,于是指针定位在文件结束处

​ file.seekg(0,ios::beg); //基地址为文件头,偏移量为0,于是定位在文件头

参考资料

string函数

getline()函数

getline()的原型是istream& getline ( istream &is , string &str , char delim );

其中 istream &is 表示一个输入流,譬如cin;string&str表示把从输入流读入的字符串存放在这个字符串中(可以自己随便命名,str什么的都可以);char delim表示遇到这个字符停止读入,在不设置的情况下系统默认该字符为’\n’,也就是回车换行符(遇到回车停止读入)。

参考资料

s.erase()函数

erase函数的原型如下:

(1)string& erase ( size_t pos = 0, size_t n = npos );

(2)iterator erase ( iterator position );

(3)iterator erase ( iterator first, iterator last );

也就是说有三种用法:

(1)erase(pos,n); 删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符

(2)erase(position);删除position处的一个字符(position是个string类型的迭代器)

(3)erase(first,last);删除从first到last之间的字符(first和last都是迭代器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string str ("This is an example phrase.");  
string::iterator it;

// 第(1)种用法
str.erase (10,8);
cout << str << endl; // "This is an phrase."

// 第(2)种用法
it=str.begin()+9;
str.erase (it);
cout << str << endl; // "This is a phrase."

// 第(3)种用法
str.erase (str.begin()+5, str.end()-7);
cout << str << endl; // "This phrase."

参考资料

atoi()与stoi()函数

atoi:表示 ascii to integer,C语言函数,包含在头文件

stoi:表示 string to integer,包含在头文件

二者作用均为把字符串转换为int.在使用Dev-C++编译时,在编译选项中已选iso C++11选项但仍然出错,必须在编译时加入如下指令:-std=c++11。使用VS2017

不同的是atoi()的参数是 const char* ,因此对于一个字符串str我们必须调用 c_str()的方法把这个string转换成 const char类型的,而stoi()的参数是const string,不需要转化为 const char*;

stoi函数默认要求输入的参数字符串是符合int范围的[-2147483648, 2147483647],否则会runtime error。
atoi函数则不做范围检查,若超过int范围,则显示-2147483648(溢出下界)或者2147483647(溢出上界)。

参考资料1

参考资料2

参考资料3

参考资料4

itoa()函数

itoa表示:integer to array,是广泛应用的非标准C语言和C++语言扩展函数。由于它不是标准C/C++语言函数,所以不能在所有的编译器中使用。但是,大多数的编译器(如Windows上的)通常在<stdlib.h>/头文件中包含这个函数。

功能:将任意类型的数字转换为字符串。在<stdlib.h>中与之有相反功能的函数是atoi。

char *itoa( int value, char * string,int radix);

原型说明:

value:欲转换的数据。

string:目标字符串的地址。

radix:转换后的进制数,可以是10进制、16进制等。

例:itoa(nu,str,10); //将nu转换为字符串并赋给str,第三个参数采用十进制。

参考资料

replace()函数

此函数常用方法有九种,这里简单介绍第一种,其他方法见参考资料:

string& replace (size_t pos, size_t len, const string& str) 用str 替换指定字符串从起始位置pos开始长度为len 的字符

例:s.replace(s.find(“,”),1,”\t”); //在字符串s中查找第一个逗号,然后把逗号换成\t

参考资料

find()函数

所有重载函数:

PS:网上关于以下函数的返回类型有int、size_type、size_t

int find(char c, int pos = 0) const; //从pos开始查找字符c在当前字符串的位置
int find(const char *s, int pos = 0) const; //从pos开始查找字符串s在当前串中的位置
int find(const char *s, int pos, int n) const; //从pos开始查找字符串s中前n个字符在当前串中的位置
int find(const string &s, int pos = 0) const; //从pos开始查找字符串s在当前串中的位置

int find_first_of(char c, int pos = 0) const; //从pos开始查找字符c第一次出现的位置

//从pos开始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置
int find_first_of(const char *s, int pos = 0) const;

int find_first_of(const char *s, int pos, int n) const;
int find_first_of(const string &s,int pos = 0) const;

共同点:

查找成功时返回所在位置,失败返回string::npos的值,string::npos一般是MAX_INT(即2^32 - 1)

差异:

find(): 查找字符串中第一次出现字符c、字符串s的位置;

find_first_of(): 查找字符串中字符c、字符数组s中任意一个字符第一次出现的位置。

以上所讲的所有的string查找函数,都有唯一的返回类型,那就是size_type,即一个无符号整数(按打印出来的算)。若查找成功,返回按查找规则找到的第一个字符或子串的位置;若查找失败,返回npos,即-1(打印出来为4294967295)。

现区分size_type、size_t:

为了使自己的程序有很好的移植性,c++程序员应该尽量使用size_t和size_type而不是int, unsigned

size_t是全局定义的类型;size_type是STL类中定义的类型属性,用以保存任意string和vector类对象的长度

string::size_type 制类型一般就是unsigned int, 但是不同机器环境长度可能不同 win32 和win64上长度差别;size_type一般也是unsigned int

使用的时候可以参考:

string::size_type a =123;
vectorsize_type b=234;
size_t b=456;

size_t 使用的时候头文件需要 ;size_type 使用的时候需要或者

sizeof(string::size_type)

​ sizeof(vector::size_type)
sizeof(vector::size_type)
sizeof(size_t)
上述长度均相等,长度为win32:4 win64:8

二者联系:在用下标访问元素时,vector使用vector::size_type作为下标类型,而数组下标的正确类型则是size_t

例:std::string::size_type posA = s.find(a); //使用size_type容器 ,
if (posA != std::string::npos) //如果s字符串中存在a,即posA不是npos
{….}

参考资料1

参考资料2

resize()函数

1、resize(n)
调整容器的长度大小,使其能容纳n个元素。
如果n小于容器的当前的size,则删除多出来的元素。
否则,添加采用值初始化的元素。
2、 resize(n,t)
多一个参数t,将所有新添加的元素初始化为t。

参考资料

peek()函数

功能:peek函数用于读取并返回下一个字符,但并不提取该字符到输入流中,也就是说,依然让该字符作为将要提取到输入流的下一个字符。

例:

if(file.peek() == EOF) //如果文件指针下一个字符为EOF,即读到文件尾。
{….}

参考资料

作者

BaldStrong

发布于

2018-06-20

更新于

2018-07-11

许可协议

评论