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

时间:2012-04-11 12:08:02

标签: c++ sockets stdstring

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

示例:

std::string data;

read(fd, data, 42);

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

感谢的

6 个答案:

答案 0 :(得分:8)

嗯,你需要以某种方式创建一个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中的要求。)

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

不,但是

std::string data;
cin >> data;

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

答案 4 :(得分:0)

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

答案 5 :(得分:-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";
}

从stdin(cin)和文件(ifstream)读取时也会有效。