是否有可能使用一个std ::字符串read()?

问题描述:

是否有可能使用std :: string作为read()?是否有可能使用一个std ::字符串read()?

例子:

std::string data; 

read(fd, data, 42); 

Normaly,我们必须使用的char *,但它可以直接使用的std :: string? (我宁愿不创建店面的结果为char *)如果读取功能需要一个char *,则没有

感谢的

+0

如果零拷贝是你的目标,它是否会帮助你用“mmap”替换“read”,然后在它周围包装一个固定分配的std :: string? – user1202136 2012-04-11 13:11:50

+0

您正在阅读的字符串中是否有空格? – 2012-04-11 14:07:36

嗯,你需要创建一个char*莫名其妙,因为这就是 函数所需要的。 (顺便说一句:你所谈论的POSIX函数 read,不是你,而不是std::istream::read?)这个问题不是 的char*,这是什么char*点(我怀疑是什么 你实际上意味着)。

最简单和常用的解决方案在这里将使用本地阵列:如果您想直接捕捉到std::string

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 data; 
data.resize(42); 
int len = read(fd, &data[0], data.size()); 
// error handling as above... 
data.resize(len); // If no error... 

这样避免了复制,但坦率地说......相比于时间的副本是微不足道 必要的实际读取和 分配Ø f字符串中的内存。这也有(产生的 可以忽略)缺点,结果字符串具有42字节的实际缓冲区 (四舍五入到任何值),而不仅仅是实际读取字符所需的最小值 。

(而且因为人们有时会提出这个问题,关于该 连续性内存在std:;string:这是一个问题,十个或更多 年前std::string原来的规格设计 expressedly允许非连续的。实施中,沿着 当时流行的rope类的行。实际上,没有一个实现者发现这个 是有用的,人们确实开始假设连续性。在这一点上,标准委员会决定将该标准与现行的 惯例对齐,并要求连续性。所以......没有实现从来没有过 连续的,没有前途的实施将放弃连续性, 鉴于C++ 11的要求。)

+0

“这可以避免复制,但很坦率地说...复制与实际读取和分配所需时间相比是微不足道的在字符串中的内存“。这取决于正在读取的数据的大小。人们投入了大量精力,使Linux内核在多个数据传输路径上零拷贝。 – user1202136 2012-04-11 13:08:14

+0

@ user1202136在这种情况下,副本的大小为42个字节。并且有一个动态分配,并从系统传输字节。内核中的情况不同,至少在处理诸如缓冲区(可能大约4KB或更多,并且从池中分配)等事情时。 – 2012-04-11 13:45:54

。只要首先调整大小,就可以使用char的std :: vector的第一个元素的地址。我不认为旧的(C++ 11之前的)字符串是保证连续的内存,否则你可以做一些类似的字符串。

不,你不能,你不应该。通常,std :: string实现内部存储其他信息,例如分配内存的大小和实际字符串的长度。 C++文档明确指出修改由c_str()data()返回的值会导致未定义的行为。

没有,但

std::string data; 
cin >> data; 

的作品就好了。如果你真的想要read(2)的行为,那么你需要分配和管理你自己的字符缓冲区。

+0

这将打破空白。 – 2012-04-11 12:25:52

+2

我们可以从这个问题中得知所有可能的结果...... – DRVic 2012-04-11 12:29:12

因为read()方法适用于原始数据输入,标准::字符串实际上是一个不好的选择,因为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"; 
} 

从标准输入(CIN),并从文件(ifstream的)阅读时那么会工作。

+0

为什么这是相关的?读取是在posix上的系统调用,并且与控制台无关。 – 2016-10-12 14:04:55