是否可以使用std :: string来进行read()操作?
示例:
std::string data;
read(fd, data, 42);
通常情况下,我们需要使用char*,但是是否可以直接使用std::string?(我不想为存储结果创建一个char*)
谢谢
好的,因为这是函数要求的内容,所以你需要创建一个 char*
。 (顺便说一下:你是在谈论 Posix 函数 read
,而不是 std::istream::read
吗?) 问题不在于 char*
,而在于 char*
指向的内容(我猜这才是你真正想表达的)。
这里最简单和常见的解决方案是使用一个本地数组:
char buffer[43];
int len = read(fd, buffer, 42);
if ( len < 0 ) {
// read error...
} else if ( len == 0 ) {
// eof...
} else {
std::string data(buffer, len);
}
如果你想直接将内容捕获到 std::string
中,这是可能的(尽管不一定是一个好主意):
std::string data;
data.resize( 42 );
int len = read( fd, &data[0], data.size() );
// error handling as above...
data.resize( len ); // If no error...
这样可以避免拷贝,但坦白说...与实际读取和分配字符串内存所需的时间相比,拷贝是微不足道的。此外,这也有(可能微不足道的)缺点,即生成的字符串具有实际缓冲区大小为42字节(向上舍入到任何值),而不仅仅是实际读取的字符所需的最小值。
(由于有些人有时会提出问题,关于std::string
中内存的连续性:这是十年或更久以前的问题。最初的std::string
规范专门设计为允许非连续实现,沿用当时流行的rope
类的方式进行。实际上,没有一个实现者发现这是有用的,人们开始假设连续性。在此之后,标准委员会决定将标准与现有实践对齐,并要求连续性。因此...没有任何实现不是连续的,也没有未来的实现会放弃连续性,考虑到C ++11中的要求。)
明确是UB:*对于第一个(非const)版本,如果修改此字符为任何值而不是
CharT(),则行为未定义。*而且这仅适用于修改该单个字符。但是,C++17确实添加了[
.data()](https://en.cppreference.com/w/cpp/string/basic_string/data)的非const重载,您可以在
.resize()之后使用它。实际上,在C++11及更高版本中,保证
&str[i] = str.data()+i,因此您应该可以放心使用
&str [0]`。 - Peter Cordesstd::string::append
和缓冲区内容直接读取以及缓冲读取来对std::string::resize
进行基准测试,到目前为止,我没有找到更好的答案,但我的火焰图在两者之间波动1%,具有讽刺意味的是,在8KiB缓冲区中,这个差距略微更倾向于缓冲区+附加...几个MiB缓冲区是resize约5%的优势,但是哪种IO会那么快呢? - user11877195不,但是
std::string data;
cin >> data;
这个程序运行得很好。如果你真的想要read(2)
的行为,那么你需要分配和管理自己的字符缓冲区。
因为read()函数旨在进行原始数据输入,所以std::string实际上是一个不好的选择,因为std::string处理文本。std::vector似乎是处理原始数据的正确选择。
使用字符串库中的std::getline - 参见cplusplus.com - 可以从流中读取并直接写入字符串对象。例如(再次从cplusplus.com中获取 - 在谷歌上第一次搜索getline):
int main () {
string str;
cout << "Please enter full name: ";
getline (cin,str);
cout << "Thank you, " << str << ".\n";
}
当从标准输入(stdin)和文件(ifstream)读取时,它将起作用。