Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 可以为read()使用std::string吗?_C++_Sockets_Stdstring - Fatal编程技术网

C++ 可以为read()使用std::string吗?

C++ 可以为read()使用std::string吗?,c++,sockets,stdstring,C++,Sockets,Stdstring,可以为read()使用std::string吗 例如: std::string data; read(fd, data, 42); 通常,我们必须使用char*,但是否可以直接使用std::string?(我不希望为存储结果创建char*) Thank's如果read函数需要char*,则不需要。您可以使用char的std::vector的第一个元素的地址,只要它已首先调整大小。我认为旧的(C++11之前的)字符串不能保证具有连续内存,否则您可以对字符串执行类似操作。不,您不能也不应该这样做

可以为read()使用std::string吗

例如:

std::string data;

read(fd, data, 42);
通常,我们必须使用char*,但是否可以直接使用std::string?(我不希望为存储结果创建char*)


Thank's

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

不,您不能也不应该这样做。通常,std::string实现在内部存储其他信息,如分配内存的大小和实际字符串的长度。C++文档明确地指出,修改由<代码> CyScript()/代码>或<代码>数据()/代码>返回的值导致未定义的行为。

< P>不,但

std::string data;
cin >> data;

很好用。如果您真的想要读取(2)的行为,那么您需要分配和管理自己的字符缓冲区

嗯,您需要以某种方式创建一个
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);
}

这避免了复制,但坦率地说。。。这本书无关紧要 与实际读取和 字符串中内存的分配。这也有可能 可忽略)结果字符串具有实际缓冲区的缺点 42字节(四舍五入到任意值),而不仅仅是最小值 实际读取的字符所必需的

(由于人们有时会提出这个问题
std:;string中内存的连续性:这是一个十个或更多的问题
多年前,
std::string
的原始规范是设计的 明确地允许非连续的实现,按照 当时流行的
rope
类。在实践中,没有实现者发现这一点 为了有用,人们开始假设连续性。在这一点上, 标准委员会决定使标准与现有标准保持一致 实践,需要连续性。所以…没有一个实现是不连续的 是连续的,未来的实现不会放弃连续性,
考虑到C++11.)中的要求

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

使用字符串库中的std::getline-请参阅-可以从流中读取数据并直接写入字符串对象。示例(同样摘自cplusplus.com——getline在google上的第一次点击):

int main(){
字符串str;

这可以避免复制,但坦率地说,与实际读取和字符串内存分配所需的时间相比,复制是微不足道的这取决于所读取数据的大小。人们投入了大量精力在几个数据传输路径上实现Linux内核的零拷贝。@user1202136在这种情况下,拷贝的大小是42字节。并且存在动态分配,以及从系统传输字节。内核中的情况不同,至少在n处理缓冲区之类的事情(可能是4KB或更多,并且是从池中分配的)。由于C++11使用
&str[0]
显式UB:对于第一个(非常量)版本,如果将此字符修改为
CharT()以外的任何值,则行为是未定义的
。这只是为了修改单个字符。然而,C++17确实添加了一个非常量重载,您可以在
.resize()
之后使用它。在实践中,您应该可以使用
&str[0]
,尤其是在C++11和更高版本中,其中保证
&str[i]=str.data()+i
如果零拷贝是您的目标,那么用“mmap”替换“read”是否有助于您,然后在其周围包装一个固定分配的std::字符串?您正在读取的字符串中是否有空格?为什么这与此相关?read是posix上的系统调用,与中的控制台无关。
std::string data;
data.resize( 42 );
int len = read( fd, &data[0], data.size() );
//  error handling as above...
data.resize( len );  //  If no error...
int main () {
  string str;
  cout << "Please enter full name: ";
  getline (cin,str);
  cout << "Thank you, " << str << ".\n";
}