C++ STL 文件读取和容器(转载自http://blog.sina.com.cn/s/blog_735f29100102uwwd.html)
来源:互联网 发布:java 文件存在判断 编辑:程序博客网 时间:2024/05/22 03:11
STL部分:
- 用操纵符(endl, ends,flush)显式地刷新缓冲区:
cout<<"Hi!"<<endl; //插入换行符,并刷新缓冲区
cout<<"Hi!"<<ends; //插入空格字符null,并刷新缓冲区
cout<<"Hi!"<<flush; //仅仅刷新缓冲区,不插入任何其他字符
创建文件流对象时,我们可以提供文件名(可选)。如果提供了一个文件名,则open会自动隐式地被调用。
如果我们定义了一个空的文件流,我们使用它的成员函数open()
ofstream Out;
Out.open (“cpp-home.txt”, ios::out | ios::app | ios::binary)
这里ios代表某一种IO类型,比如fstream
ios::in为输入(读)而打开文件ios::out为输出(写)而打开文件ios::ate初始位置:文件尾ios::app所有输出附加在文件末尾ios::trunc如果文件已存在则先删除该文件ios::binary二进制方式#include 《fstream》
#include 《iostream》
using namespace std;
void Writefile();
void Readfile();
void main()
{
}
void Writefile()
{
}
void Readfile()
{
}
改进:
void Writefile()
{
}
string str1;
while(getline(OpenFile, str1))
cout<<str1;
打印
Hello World!
然后再试试:
string str1,str2;
while(OpenFile>>str1>>str2)
cout<<str1<<endl<<str2<<endl;
打印
Hello
World!
容器
标准STL序列容器:vector、string、deque和list,forward_list,array。
vector和string都是可变大小的数组, 一般用于在尾部插入或删除元素。
list 双向链表
forward_list 单项链表
这两个插入很快,在各个位置都很快的插入或者删除,但是不支持随机访问,查找很慢
forward_list容器与list容器的主要设计区别是list保持内部唯一的一个链接到下一个元素,而后者则保持每个元素的两个链接:一个指向下一个元素和一个前一个。
array 是大小固定的数组,更安全。
为了定义容器对象首先要包含相关头文件,如#include,#include,#include
对迭代器++ (递增)从当前元素移动到下一个元素。
forward_list的迭代器不支持--操作。
容器初始化:
1.
vector< int > ivec( 10 );
vector< int > ivec( 10,0 );
花括号列表初始化vector< int > ivec{1,2,3,4,5,6};
//注意,尽量这样初始化,或者一个一个的pushback,不要 vector A={"hello","world",..};尽管这个在C++11中已经支持。但最好不要用(起码我试过VS2012都不支持。但VS2013支持)。因为vectors1="Wusiwen";
顺序容器的一些操作:
http://www.cnblogs.com/ForFreeDom/archive/2012/04/26/2470971.html
3.容器的
c.begin()
c.end()
c.push_back(t)
c.push_front(t)
c.insert(p,t)
c.insert(p,n,t).
c.insert(p,b,e)
c.size()
c.max_size()
c.empty()
c.resize(n)
c.resize(n,t)
c.back()
c.front()
c[n]
c.at(n)
c.erase(p)
c.erase(b,e)
c.clear()
c.pop_back()
c.pop_front()
c1 = c2
c1.swap(c2)
c.assign(b,e)
例如:c1.assign(c2.cbegin(),c2.cend()) ;
c.assign(n,t)
D.swap
vector svec1(10); // vector with 10 elements vector svec2(24); // vector with 24 elements
vector::iterator itor=svec1.begin();
vector::iterator itor2=svec1.end();
svec1.swap(svec2); //执行 swap 后,容器 svec1 中存储 24 个 string 类型的元素,而 svec2 则存储 10 个元素。
//执行swap后,itor,itor2不失效,而是分别指向svec2中对应的元
然而,尽量使用非成员函数版本的swap:
额外的string操作
构造string的其他方法
</pre><pre code_snippet_id="390774" snippet_file_name="blog_20140613_2_4395731" name="code" style="white-space: normal; margin-top: 0px; margin-bottom: 0px; padding: 0px;">const char *cp="Hello World!!!"; //以空字符‘\0’结束的数组
string s(cp); //拷贝cp中的字符,直到遇到空字符;
</pre><pre code_snippet_id="390774" snippet_file_name="blog_20140613_1_1462365" name="code" style="white-space: normal; margin-top: 0px; margin-bottom: 0px; padding: 0px;">//n, len2, pos2 都是无符号值 <wbr></wbr>
<wbr>string s(s2, pos2, len2) //s是s2从pos2开始Len2个字符</wbr>
string s7(s, 6, 20); //正确,只拷贝到s1末尾;s7=="World!!!" <wbr></wbr>
substr操作
string s("hello world"); <wbr></wbr>
string s4=s.substr(6, 11); //s4=world <wbr></wbr>
</pre><h2 style="margin: 0px; padding: 0px; border: 0px; list-style: none;">改变string的其他方法</h2></div><div style="margin: 0px; padding: 0px; font-family: Tahoma; line-height: 24px;">string容器也支持assign(赋值),insert(插入),erase(删除),运算</div><div style="margin: 0px; padding: 0px; font-family: Tahoma; line-height: 24px;"><br style="margin: 0px; padding: 0px;" /></div><h3 style="margin: 0px; padding: 0px; border: 0px; list-style: none; font-family: Tahoma; line-height: 24px;">append和replace函数</h3><div style="margin: 0px; padding: 0px; font-family: Tahoma; line-height: 24px;">append就是在string末尾进行插入的一种简单的形式</div><p style="margin-top: 0px; margin-bottom: 8px; padding-top: 0px; padding-bottom: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;"> <wbr></wbr></p><div style="margin: 0px; padding: 0px; font-family: Tahoma; line-height: 24px;"><pre code_snippet_id="390774" snippet_file_name="blog_20140613_4_4505198" name="code" style="white-space: normal; margin-top: 0px; margin-bottom: 0px; padding: 0px;">string s("C++ Primer"), s2=s; //将s和s2初始化为C++ Primer
<wbr></wbr>
s.insert(s.size(), "4th Ed."); //s==“C++ Primer 4th Ed。”
s2.append("4th Ed."); //和上面的等价 <wbr></wbr>
</pre><pre code_snippet_id="390774" snippet_file_name="blog_20140613_4_4505198" name="code" style="white-space: normal; margin-top: 0px; margin-bottom: 0px; padding: 0px;">s.erase(11, 3); //s=="C++ Primer Ed." <wbr></wbr>
s.insert(11, "5th"); //s=="C++ Primer 5th Ed." //从位置11开始,删除3个字符并插入"5th" s2.replace(11, 3, "Fifth"); //s=="C++ Primer Fifth Ed."
string搜索操作 : 每个搜索操作都返回一个string::size_type 值,表示匹配发生位置的下标(大小写敏感)
最简单的是find函数
string name("AnnBelle");
auto pos1 = name.find("Anna"); //"Anna"的第一次出现的位置为0
1 s.find(args); //在s中args的第一次出现的位置 2 s.rfind(args); //最后一次出现 3 s.find_first_of(args);//在字符串s中查找第一个与args中的任意某个字符匹配的字符的位置
string name("A1n2");
string Num("1234567890");
auto pos1 = name.find_first_of(Num);//返回1,即name 中的第一个数字下标
s.compare(s2); //比较s和s2 //compare的返回值:>0 s大; <0 s小; =0 二者相等
容器适配器:
(为什么要搞一个这个?想想设计模式中的适配器模式。原理跟这个差不多吧。STL帮你实现了一个这个适配器,性能还不错,直接用就行了)
3种STL容器适配器是
栈、队列和优先级队列。
stack适配器所关联的容器可以是vector list deque中任意一种。
queue适配器则要求关联操作必须提供push_front操作,因此不能是vector
使用适配器时,必须包含相关的头文件:
#include
适配器的初始化
deque deq; //假定deq是一个deque
stack stk(deq);
默认的stack和queue都基于deque容器实现,
在创建适配器时,通过将一个顺序容器指定为适配器的第二个类型实参,可覆盖其关联的基础容器类型:
stack< string, vector《string》 > str_stk; //在vector上实现的空栈
stack< string, vector《string》 > str_stk(svec);//在vector上实现的栈,初始化时保存svec的拷贝
栈适配器
s.empty()
s.size()
s.pop()
s.top()
s.push(item)
队列和优先级队列
q.empty()
q.size()
q.pop()
q.front()
q.back()
q.push(item)
在C++标准模板库中,栈类(stack)的成员函数stack::push()在栈顶端添加元素,stack:pop()从非空栈的栈顶端中删除一个元素,stack:empty()判断栈是否为空,stack::top()返回非空栈的栈顶元素,stack::size()返回栈中元素的个数,构造一个int类型的栈,然后对这个栈调用以上几个函数,体会栈这种数据结构的特点及其成员函数的用法。
C++中的动态内存与智能指针
使用new和delete来管理动态内存常出的一些错误:
1.忘记delete,即导致了“内存泄漏”,
2.野指针。在对象已经被释放掉之后,指针会置为空。这时候我们再次使用,会产生使用非法内存的指针。注意delete并不是要删除指针,而是释放指针所指的内存。
不过如果我们需要保留指针,可以在delete以后将nullptr赋予指针,这样指针就不指向任何对象了,如下代码:
所以C++标准库中的智能指针很好的解决了这些问题。
shared_ptr是一个类,它跟vector类似,也是一个模板。
shared_ptr<string>
经常使用make_shared函数来分配和使用这种动态内存:
shared_ptr<int>
shared_ptr
或者经常使用auto方法 auto
r=q;
r的计数-1,q的计数+1
如果要在多个对象间共享数据,我们可以使用动态内存。这可以 结合shared_ptr指针来实现。
在这种情况下、 构造函数
当动态对象不再被使用时,shared_ptr还会自动释放动态对象。比如
int main()
{
...
void f1()
{
} //r离开作用域,它指向的内存会自动被释放。
...
}
在子函数f1中定义了一个局部变量的智能指针r。当r离开作用域,计数-1,它指向的内存会自动被释放。
当然了,如果在这期间它的计数增加了,离开作用域以后计数不为0那就不销毁了。
若某一个智能指针,
p.reset() 和p.unique()经常联合使用,来控制多个shared_ptr共享的对象。
通过shared_ptr可以让多个智能指针对象同时拥有某一块内存的访问权.unique_ptr同时只能有一个智能指针对象指向某块内存.
unique_ptr无法进行复制构造与赋值操作,但在函数中作为返回值却可以用.
pair《T1,T2》 p1; 创建一个空的pair对象,它的两个元素分别是T1和T2类型,采用值初始化
pair《T1,T2》
make_pair(v1, v2) 以v1和v2值创建一个新的pair对象,其元素类型分别是v1和v2的类型
map
multimap
multiset
map对象的定义
map 《k,v》 m; 创建一个名为m的空map对象,其键和值的类型分别为K和V
map《k,v》
查找元素
m.count(k) 返回m中键为k的出现次数(0或1)
m.find(k) 如果容器中存在键为k的元素,则返回指向该元素的迭代器。
map
map::key_type
在
map::mapped_type
在
map::value_type
一个
m.erase(k)
删除
m.erase(p)
从
使用下标访问map与使用下标访问数组或vector的行为截然不同;用下标访问不存在的元素将导致在map容器中添加一个新的元素,它的键即为该下标的值。
方法一:
map《string,int》 word_count;
word_count["Peter"]=10;//相当于增加一个键值对
//创建一个map对象,用来记录每个单词出现的次数,十分简洁。
map《string,int》
string word;
while(cin>>word)
{
++word_count[word];
}
通常,我们会立即为其赋值,其实就是对同一个对象进行初始化并赋值。而插入元素的另一个方法是:直接使用
map对象的迭代遍历:
set类型定义于头文件中。set容器支持大部分map容器的操作,如:构造函数;insert操作;count和find操作; erase操作。两个例外情况是:set不支持下标操作符,而且没有定义mapped_type类型。
map容器是键-值对的集合,而set容器只是单纯的键的集合。当只想知道一个值是否存在时,使用set容器是最合适的。
0 1 2 3 4 5 6 7 8 9
但是注意到
- C++ STL 文件读取和容器(转载自http://blog.sina.com.cn/s/blog_735f29100102uwwd.html)
- quartz 时间配置规则(转载自http://blog.sina.com.cn/s/blog_59833db10100hnvk.html)
- fedora17 安装(64bit)转载自http://blog.sina.com.cn/s/blog_88e0154d01019rxr.html
- ldap安装与学习(转载自:http://blog.sina.com.cn/s/blog_72ee04a40100p0ce.html)
- typedef函数指针的用法(C++) (转载的http://blog.sina.com.cn/s/blog_5e71ee700100fo13.html)
- Kosaraju算法的分析和证明 转自http://blog.sina.com.cn/s/blog_4dff87120100r58c.html
- Matlab以MEX方式调用C源代码(转载http://blog.sina.com.cn/s/blog_468651400100coas.html)
- IL与CLR两个概念(转自http://blog.sina.com.cn/s/blog_49947b280100gtde.html)
- 借鉴:CFD建模计算 (转自 http://blog.sina.com.cn/s/blog_497df1da0100akzt.html )
- SQL常用字符串函数(转载http://blog.sina.com.cn/s/blog_5e31641d0100cw3j.html)
- cookie与session(上) 转载 原文链接http://blog.sina.com.cn/s/blog_4745d1c10100ihnq.html
- cookie与session(下) 转载 原文链接http://blog.sina.com.cn/s/blog_4745d1c10100ihnq.html
- gawk 命令(转载:http://blog.sina.com.cn/s/blog_6238358c01012h1f.html)
- Referenced file contains errors 解决方法 (转载地址:http://blog.sina.com.cn/s/blog_6a6b141001011xhn.html)
- C++map的基本操作和使用 http://blog.sina.com.cn/s/blog_65ed0e8a01010yd3.html
- 理解strong与weak)强引用与弱引用转载自《http://blog.sina.com.cn/s/blog_7c8dc2d50101lc08.html》
- C的xml编程-libxml2(1) http://blog.sina.com.cn/s/blog_6a1837e90100ns2q.html
- IplImage 和 QImage的转换 (转:http://blog.sina.com.cn/s/blog_5c70dfc80100qzif.html)
- matlab之any()、imshow()、image()、imagesc()、取整函数fix, floor, ceil,round
- Android开发BroadcastReceiver中的Action使用说明
- 碉堡了!大学各系女生对初夜的描述!
- 3.1、Android Studio在虚拟机中运行应用
- iOS之SDWebimage下载图片链接带中文处理
- C++ STL 文件读取和容器(转载自http://blog.sina.com.cn/s/blog_735f29100102uwwd.html)
- 股票数据自动入库hive到oracle
- android 更换时区时间同步
- 原型模式(Prototype)
- 6 rotate-image
- 独显和集显设置,双显卡工作及cuda计算
- spring定时任务配置、使用说明(简单、全)
- Android之RecyclerView的使用总结
- ECMAScript 6