C++ 使用GNU/Linux read()函数的正确方法
在GNU/Linux手册页中,对读取功能的描述如下:C++ 使用GNU/Linux read()函数的正确方法,c++,c,linux,pointers,C++,C,Linux,Pointers,在GNU/Linux手册页中,对读取功能的描述如下: ssize_t read(int fd, void *buf, size_t count); 我想使用此函数从套接字或串行端口读取数据。如果计数大于1,函数参数中提供的指针将指向从内存端口读取的最后一个字节,因此指针减量是将指针指向数据的第一个字节所必需的。这是危险的,因为使用它的C++语言,根据容器的大小和空间需要动态地分配容器,可能会在从 Read()/函数返回的点上损坏数据。我想用C样式的数组代替指针。这是正确的方法吗?如果没有,正确
ssize_t read(int fd, void *buf, size_t count);
我想使用此函数从套接字或串行端口读取数据。如果计数
大于1,函数参数中提供的指针将指向从内存端口读取的最后一个字节,因此指针减量是将指针指向数据的第一个字节所必需的。这是危险的,因为使用它的C++语言,根据容器的大小和空间需要动态地分配容器,可能会在从QSerialPort
类用于配置和打开具有以下参数的端口:
- 波特率115200
- 8个数据位
- 不对等
- 一站式钻头
- 无流量控制
std::vector
包含大量struct
s,定义如下:
struct DataMember
{
QString name;
size_t count;
char *buff;
}
然后在while循环中,直到达到所述std::vector
的末尾,基于所述struct
的count
成员变量执行read()
,并且数据存储在同一struct
的buff中:
ssize_t nbytes = read(port->handle(), v.at(i).buff, v.at(i).count);
然后在控制台上打印数据。在我的测试用例中,只要数据是一个字节,打印的值就是正确的,但是对于多个字节,显示的值是从端口读取的最后一个值加上一些垃圾值。我不知道为什么会这样。请注意,当char*buff
更改为char buff[count]
时,将获得正确的结果
如果计数大于1,函数参数中提供的指针将指向从内存端口读取的最后一个字节
否。指针是通过值传递给read()
方法的,因此,调用后的值完全不可能与调用前的值有任何不同,无论计数如何
因此,指针减量是将指针移到数据的第一个字节所必需的
指针已指向数据的第一个字节。不需要减量
<>这是危险的,因为使用C++语言,根据其大小和空间需求动态存储容器,可能会在读()函数返回点损坏数据。
这都是基于不可能的胡说八道
这一切你都错了
如果计数大于1,函数参数中提供的指针将指向从内存端口读取的最后一个字节
否。指针是通过值传递给read()
方法的,因此,调用后的值完全不可能与调用前的值有任何不同,无论计数如何
因此,指针减量是将指针移到数据的第一个字节所必需的
指针已指向数据的第一个字节。不需要减量
<>这是危险的,因为使用C++语言,根据其大小和空间需求动态存储容器,可能会在读()函数返回点损坏数据。
这都是基于不可能的胡说八道
这一切你都错了
在我的测试用例中,只要数据是一个字节,打印的值就是正确的,但是对于多个字节,显示的值是从端口读取的最后一个值加上一些垃圾值
从阅读(2)手册页:
成功时,返回读取的字节数(零表示文件结束),
文件位置将按此数字前进。如果此数字为,则不是错误
小于请求的字节数;例如,这可能是因为
字节现在实际上是可用的(可能是因为我们快到文件末尾了,或者
因为我们正在从管道或终端进行读取),或者因为read()被中断
通过信号。在出现错误时,返回-1,并正确设置errno。在这种情况下
未指定文件位置(如果有)是否更改
对于管道、套接字和字符设备(包括串行端口)以及阻塞文件描述符(默认)读取,实际上不会等待完整计数。在您的情况下,read()会一直阻塞,直到串行端口上出现一个字节并返回。这就是为什么在输出中第一个字节是正确的,其余的是垃圾(未初始化内存)。如果需要完整计数,则必须在read()周围添加一个循环,该循环将一直重复,直到读取了count字节
在我的测试用例中,只要数据是一个字节,打印的值就是正确的,但是对于多个字节,显示的值是从端口读取的最后一个值加上一些垃圾值
从阅读(2)手册页:
成功时,返回读取的字节数(零表示文件结束),
文件位置将按此数字前进。如果此数字为,则不是错误
小于请求的字节数;例如,这可能是因为
字节现在实际上是可用的(可能是因为我们快到文件末尾了,或者
因为我们正在从管道或终端进行读取),或者因为read()被中断
通过信号。在出现错误时,返回-1,并正确设置errno。在这种情况下
未指定文件位置(如果
struct fnord {
std::string name;
std::vector data;
};
size_t readsomething(int fd, size_t count, fnord &f)
{
// reserve memory
f.data.reserve(count);
int rbytes = 0;
int rv;
do {
rv = read(fd, &f.data[rbytes], count - rbytes);
if( !rv ) {
// End of File / Stream
break;
}
if( 0 > rv ) {
if( EINTR == errno ) {
// signal interrupted read... restart
continue;
}
if( EAGAIN == errno
|| EWOULDBLOCK == errno ) {
// file / socket is in nonblocking mode and
// no more data is available.
break;
}
// some critical error happened. Deal with it!
break;
}
rbytes += rv;
} while(rbytes < count);
return rbyteS;
}