什么是std::string...?怎么用?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是std::string...?怎么用?相关的知识,希望对你有一定的参考价值。
如题..小弟初学c++,请教这个是what``?怎么用?
std::string是标准C++的字符串实现,用法:要想使用标准C++中string类,必须要包含
#include
<string>//
注意是<string>,不是<string.h>,带.h的是C语言中的头文件
using
std::string;
using
std::wstring;
或
using
namespace
std;
下面你就可以使用string/wstring了,它们两分别对应着char和wchar_t。
扩展资料:
string类的字符操作:
const
char
&operator[](int
n)const;
const
char
&at(int
n)const;
char
&operator[](int
n);
char
&at(int
n);
operator[]和at()均返回当前字符串中第n个字符的位置,但at函数提供范围检查,当越界时会抛出out_of_range异常,下标运算符[]不提供检查访问。
const
char
*data()const;//返回一个非null终止的c字符数组。
const
char
*c_str()const;//返回一个以null终止的c字符串。
int
copy(char
*s,
int
n,
int
pos
=
0)
const;//把当前串中以pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目。
参考资料来源:string-百度百科 参考技术A std::string是标准C++的字符串实现。为了让程序好移植,要用std::string。比如:
方法1:
#include <string>
std::string
方法2:
#include <string>
using
namespace
std;
string
string类的构造函数:
string(const
char
*s);
//用c字符串s初始化
string(int
n,char
c);
//用n个字符c初始化
此外,string类还支持默认构造函数和复制构造函数,如string
s1;string
s2="hello";都是正确的写法。当构造的string太长而无法表达时会抛出length_error异常
;
扩展资料
string类的字符操作:
const
char
&operator[](int
n)const;
const
char
&at(int
n)const;
char
&operator[](int
n);
char
&at(int
n);
operator[]和at()均返回当前字符串中第n个字符的位置,但at函数提供范围检查,当越界时会抛出out_of_range异常,下标运算符[]不提供检查访问。
const
char
*data()const;//返回一个非null终止的c字符数组
const
char
*c_str()const;//返回一个以null终止的c字符串
int
copy(char
*s,
int
n,
int
pos
=
0)
const;//把当前串中以pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目
string的特性描述:
int
capacity()const;
//返回当前容量(即string中不必增加内存即可存放的元素个数)
int
max_size()const;
//返回string对象中可存放的最大字符串的长度
int
size()const;
//返回当前字符串的大小
int
length()const;
//返回当前字符串的长度
bool
empty()const;
//当前字符串是否为空
void
resize(int
len,char
c);//把字符串当前大小置为len,并用字符c填充不足的部分 参考技术B return
后面定义了一个std::hash<std::string>临时变量(第一对圆括号),然后调用该临时变量函数operator()(第二对圆括号,这里是运算符重载),并传sd.isbn()的返回值作为参数。
临时变量的定义语法:
类型(参数列表)
将文件读入std :: string的最有效方法是什么?
我目前这样做,最后转换为std :: string需要98%的执行时间。肯定有更好的办法!
std::string
file2string(std::string filename)
{
std::ifstream file(filename.c_str());
if(!file.is_open()){
// If they passed a bad file name, or one we have no read access to,
// we pass back an empty string.
return "";
}
// find out how much data there is
file.seekg(0,std::ios::end);
std::streampos length = file.tellg();
file.seekg(0,std::ios::beg);
// Get a vector that size and
std::vector<char> buf(length);
// Fill the buffer with the size
file.read(&buf[0],length);
file.close();
// return buffer as string
std::string s(buf.begin(),buf.end());
return s;
}
作为C ++迭代器抽象和算法的忠实粉丝,我希望以下是将文件(或任何其他输入流)读入std::string
(然后打印内容)的禁食方式:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
int main()
{
std::string s(std::istreambuf_iterator<char>(std::ifstream("file")
>> std::skipws),
std::istreambuf_iterator<char>());
std::cout << "file='" << s << "'
";
}
对于我自己实现的IOStream来说,这当然很快,但实际上要快速实现它需要很多技巧。首先,它需要优化算法来处理分段序列:流可以被视为输入缓冲器序列。我不知道任何STL实现始终如一地进行此优化。奇怪的使用std::skipws
只是为了引用刚创建的流:std::istreambuf_iterator<char>
需要一个临时文件流不会绑定的引用。
由于这可能不是最快的方法,我倾向于使用std::getline()
与特定的“换行符”字符,即不在文件中的字符:
std::string s;
// optionally reserve space although I wouldn't be too fuzzed about the
// reallocations because the reads probably dominate the performances
std::getline(std::ifstream("file") >> std::skipws, s, 0);
这假定该文件不包含空字符。任何其他角色都可以。不幸的是,std::getline()
将char_type
作为界定参数,而不是int_type
,这是成员std::istream::getline()
用于分隔符:在这种情况下,你可以使用eof()
作为一个永远不会发生的角色(char_type
,int_type
和eof()
指的是相应的成员of char_traits<char>
)。反过来,成员版本无法使用,因为您需要提前知道文件中有多少个字符。
顺便说一句,我看到一些尝试使用seek来确定文件的大小。这一定不会太好用。问题是在std::ifstream
中完成的代码转换(实际上在std::filebuf
中)可以创建与文件中的字节不同的字符数。不可否认,使用默认的C语言环境时并非如此,并且可以检测到这不会进行任何转换。否则,流的最佳选择是遍历文件并确定正在生成的字符数。我实际上认为这是代码转换可能需要做的事情,尽管我认为它实际上并没有完成。但是,没有一个示例使用例如明确设置C语言环境。 std::locale::global(std::locale("C"));
。即使这样,也需要以std::ios_base::binary
模式打开文件,因为否则在读取时行尾序列可能被单个字符替换。不可否认,这只会使结果更短,而不会更长。
使用std::streambuf*
提取的其他方法(即那些涉及rdbuf()
的方法)都要求在某些时候复制所得到的内容。鉴于该文件实际上可能非常大,这可能不是一种选择。但是,如果没有副本,这很可能是最快的方法。为了避免副本,可以创建一个简单的自定义流缓冲区,它引用std::string
作为构造函数参数并直接附加到此std::string
:
#include <fstream>
#include <iostream>
#include <string>
class custombuf:
public std::streambuf
{
public:
custombuf(std::string& target): target_(target) {
this->setp(this->buffer_, this->buffer_ + bufsize - 1);
}
private:
std::string& target_;
enum { bufsize = 8192 };
char buffer_[bufsize];
int overflow(int c) {
if (!traits_type::eq_int_type(c, traits_type::eof()))
{
*this->pptr() = traits_type::to_char_type(c);
this->pbump(1);
}
this->target_.append(this->pbase(), this->pptr() - this->pbase());
this->setp(this->buffer_, this->buffer_ + bufsize - 1);
return traits_type::not_eof(c);
}
int sync() { this->overflow(traits_type::eof()); return 0; }
};
int main()
{
std::string s;
custombuf sbuf(s);
if (std::ostream(&sbuf)
<< std::ifstream("readfile.cpp").rdbuf()
<< std::flush) {
std::cout << "file='" << s << "'
";
}
else {
std::cout << "failed to read file
";
}
}
至少使用适当选择的缓冲区,我希望版本相当快。哪个版本最快将取决于系统,正在使用的标准C ++库,以及可能还有许多其他因素,即您想要衡量性能。
你可以试试这个:
#include <fstream>
#include <sstream>
#include <string>
int main()
{
std::ostringstream oss;
std::string s;
std::string filename = get_file_name();
if (oss << std::ifstream(filename, std::ios::binary).rdbuf())
{
s = oss.str();
}
else
{
// error
}
// now s contains your file
}
如果你愿意,你也可以直接使用oss.str()
;只是确保你在某处有某种错误检查。
不能保证它是最有效的;你可能无法击败<cstdio>
和fread
。正如@Benjamin指出的那样,字符串流只能通过副本公开数据,因此您可以直接读取目标字符串:
#include <string>
#include <cstdio>
std::FILE * fp = std::fopen("file.bin", "rb");
std::fseek(fp, 0L, SEEK_END);
unsigned int fsize = std::ftell(fp);
std::rewind(fp);
std::string s(fsize, 0);
if (fsize != std::fread(static_cast<void*>(&s[0]), 1, fsize, fp))
{
// error
}
std::fclose(fp);
(你可能想用RAII wrapper作为FILE*
。)
编辑:第二个版本的fstream-analogue如下:
#include <string>
#include <fstream>
std::ifstream infile("file.bin", std::ios::binary);
infile.seekg(0, std::ios::end);
unsigned int fsize = infile.tellg();
infile.seekg(0, std::ios::beg);
std::string s(fsize, 0);
if (!infile.read(&s[0], fsize))
{
// error
}
编辑:使用streambuf-iterators的另一个版本:
std::ifstream thefile(filename, std::ios::binary);
std::string s((std::istreambuf_iterator<char>(thefile)), std::istreambuf_iterator<char>());
(注意额外的括号以获得正确的解析。)
具有讽刺意味的是,example for string::reserve正在将文件读入字符串。您不希望将文件读入一个缓冲区,然后必须分配/复制到另一个缓冲区中。
这是示例代码:
// string::reserve
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
string str;
size_t filesize;
ifstream file ("test.txt",ios::in|ios::ate);
filesize=file.tellg();
str.reserve(filesize); // allocate space in the string
file.seekg(0);
for (char c; file.get(c); )
{
str += c;
}
cout << str;
return 0;
}
我不知道它有多高效,但这里只是简单(阅读)方式,只需将EOF设置为分隔符:
string buffer;
ifstream fin;
fin.open("filename.txt");
if(fin.is_open()) {
getline(fin,buffer,'x1A');
fin.close();
}
这样做的效率显然取决于getline算法内部的内容,因此您可以查看标准库中的代码以了解它是如何工作的。
以上是关于什么是std::string...?怎么用?的主要内容,如果未能解决你的问题,请参考以下文章
使用 std::string.c_str() 作为另一个方法的参数时的段错误
std::string::c_str() 覆盖函数返回的前一个
我想将std :: string转换为const wchar_t *