10

是否可以将 std::string 用于 read() ?

例子 :

std::string data;

read(fd, data, 42);

通常,我们必须使用 char* 但可以直接使用 std::string 吗?(我更喜欢不创建 char* 来存储结果)

谢谢

4

6 回答 6

13

好吧,您需要以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 中的要求,未来的任何实现都不会放弃连续性。)

于 2012-04-11T12:52:50.127 回答
1

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

于 2012-04-11T12:13:07.333 回答
0

如果读取函数需要 char *,则不需要。您可以使用 char 的 std::vector 的第一个元素的地址,只要它首先被调整大小。我不认为旧的(C++ 11 之前的)字符串保证有连续的内存,否则你可以对字符串做类似的事情。

于 2012-04-11T12:13:06.577 回答
0

不是,但

std::string data;
cin >> data;

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

于 2012-04-11T12:18:27.963 回答
0

因为 read() 用于原始数据输入,所以 std::string 实际上是一个不好的选择,因为 std::string 处理文本。std::vector 似乎是处理原始数据的正确选择。

于 2012-04-11T12:56:42.093 回答
-1

使用字符串库中的 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)读取时,这将起作用。

于 2012-04-11T12:58:21.133 回答