将任意长度的字节从文件读取到字符串C++; 现在我对Python很熟悉,决定学习C++,所以我非常喜欢N0B,但是肯定愿意学习。 我制作了一个脚本,从一个非常严格指定的文件格式(.EDF,用于医疗信号)中读取,该文件的ascii头由字段大小(以字节为单位)定义。第一个字段读取8字节,第二个字段读取80字节,依此类推
我的工作python脚本如下所示:将任意长度的字节从文件读取到字符串C++; 现在我对Python很熟悉,决定学习C++,所以我非常喜欢N0B,但是肯定愿意学习。 我制作了一个脚本,从一个非常严格指定的文件格式(.EDF,用于医疗信号)中读取,该文件的ascii头由字段大小(以字节为单位)定义。第一个字段读取8字节,第二个字段读取80字节,依此类推,c++,string,file-io,C++,String,File Io,我的工作python脚本如下所示: ## HEADER FIELD NAMES AND SIZES FROM EDF SPEC: header_fields = ( ('version', 8), ('patinfo', 80), ('recinfo', 80), ('start date', 8), ('start time', 8), ('header bytes', 8), ('reserved', 44), ('nrecs',
## HEADER FIELD NAMES AND SIZES FROM EDF SPEC:
header_fields = (
('version', 8), ('patinfo', 80), ('recinfo', 80),
('start date', 8), ('start time', 8), ('header bytes', 8),
('reserved', 44), ('nrecs', 8), ('recduration', 8),
('nchannels', 4))
## TELL WHICH FILE TO OPEN
folder = os.path.expanduser('~/Dropbox/01MIOTEC/06APNÉIA/Samples')
f = open(folder + '/Osas2002plusQRS.rec', 'rb')
# READ FILE CONTENT TO DICTIONARY OF LABELLED FIELD CONTENTS,
# ALREADY STRIPPED FROM BLANK SPACES
header = {}
for key, value in header_fields:
header[key] = f.read(value).strip()
最终结果是“header”,这是一个字典,其中每对都是一个“标记”字符串
我目前的笨拙C++代码,它几乎工作于打印来筛选未被剥离的字符串,这是:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
static int header_bytes[] = {8,80,80,80,80,8,8,8,44,8,8,4};
static int header_bytes_len = sizeof(header_bytes)/sizeof(int);
static string header_fields[] =
{
"version",
"patinfo",
"recinfo",
"patinfo",
"recifo",
"start date",
"start time",
"header bytes",
"reserved",
"nrecs",
"rec duration",
"nchannels"
};
int main()
{
ifstream edfreader;
edfreader.open("/home/helton/Dropbox/01MIOTEC/06APNÉIA/Samples/Osas2002plusQRS.rec", ios::binary);
char * buffer = new char [80];
for (int n = 0; n<header_bytes_len; n++)
{
edfreader.read(buffer, header_bytes[n]);
buffer[header_bytes[n]] = '\0';
cout<<"'"<<buffer<<"'"<<endl;
}
return 0;
}
#包括
#包括
#包括
使用名称空间std;
静态int头_字节[]={8,80,80,80,8,8,8,44,8,8,8,4};
静态整数头字节数=sizeof(头字节数)/sizeof(整数);
静态字符串头_字段[]=
{
“版本”,
“patinfo”,
“recinfo”,
“patinfo”,
“recifo”,
“开始日期”,
“开始时间”,
“头字节”,
“保留”,
“nrecs”,
“记录持续时间”,
“nchannels”
};
int main()
{
ifstream-edfreader;
edfreader.open(“/home/helton/Dropbox/01MIOTEC/06APNÉIA/Samples/Osas2002plusQRS.rec”,ios::binary);
字符*缓冲区=新字符[80];
对于(int n=0;n
- 以二进制模式打开文件,否则可能会出现问题
- 您输出读取结果的方式存在问题:它假定以
'\0'
结尾的字符串,您不确定是否会得到这些字符串(或者如果字段中填充了空格,则可能无法得到这些字符串)。请在读取后放大缓冲区并添加'\0'
:
buffer[header_bytes[n]] = '\0';
- 以二进制模式打开文件,否则可能会出现问题
- 您输出读取结果的方式存在问题:它假定以
'\0'
结尾的字符串,您不确定是否会得到这些字符串(或者如果字段中填充了空格,则可能无法得到这些字符串)。请在读取后放大缓冲区并添加'\0'
:
buffer[header_bytes[n]] = '\0';
创建一个描述文件格式的类/结构,类似于在python中所做的
struct Header {
char version[8];
char patinfo[80];
...,
};
然后以二进制模式打开文件,并使用上述结构读取记录
ifstream file( "filename", ios::binary );
Header H;
file.read( reinterpret_cast<char*>(&H), sizeof(H) );
ifstream文件(“文件名”,ios::binary);
收割台H;
read(reinterpret_cast(&H),sizeof(H));
这将读取头记录现在您可以访问结构的内容,但您需要小心不要将成员视为字符串,因为它们可能有或可能没有结尾\0
您可以做得比上面更出色,但这只是对现有代码的快速更改,而不是创建更复杂的类/文件处理创建一个描述文件格式的类/结构,类似于您在python中所做的
struct Header {
char version[8];
char patinfo[80];
...,
};
然后以二进制模式打开文件,并使用上述结构读取记录
ifstream file( "filename", ios::binary );
Header H;
file.read( reinterpret_cast<char*>(&H), sizeof(H) );
ifstream文件(“文件名”,ios::binary);
收割台H;
read(reinterpret_cast(&H),sizeof(H));
这将读取头记录现在您可以访问结构的内容,但您需要小心不要将成员视为字符串,因为它们可能有或可能没有结尾\0
你可以做得比上面更有趣,但这只是对现有代码的快速更改,而不是创建更精细的类/文件处理< /p> 假设除了填充之外,字段中没有空格,可以使用
将其读入C++字符串中。
/* Read field of n bytes */
std::string read_field(std::istream &edfreader, size_t n)
{
// there's no need for new;
// in fact, new may lead to a memory leak if you forget to delete
std::vector<char> buf(n);
// read as a sequence of bytes
edfreader.read(&buf.front(), n);
// find the first space or end of buffer
size_t end = 0;
while (end < n && buf[end] != ' ')
end++;
// make a string object from the buffer
return std::string(buf, end);
}
/*n字节的读取字段*/
std::字符串读取字段(std::istream和edfreader,大小\u n)
{
//不需要新的;
//事实上,如果忘记删除,新的可能会导致内存泄漏
std::载体buf(n);
//作为字节序列读取
edfreader.read(&buf.front(),n);
//查找缓冲区的第一个空格或结尾
尺寸=0;
while(end
std::string
为您分配内存;您可以像Python字符串一样使用它,只是它是可修改的
<> P>这里唯一的假设是,你的操作系统的字符集是(ASCII的超集),而对于 EdFrADADER < P>假设除了填充之外,字段中没有空格,可以使用:将它们读入C++字符串中。
/* Read field of n bytes */
std::string read_field(std::istream &edfreader, size_t n)
{
// there's no need for new;
// in fact, new may lead to a memory leak if you forget to delete
std::vector<char> buf(n);
// read as a sequence of bytes
edfreader.read(&buf.front(), n);
// find the first space or end of buffer
size_t end = 0;
while (end < n && buf[end] != ' ')
end++;
// make a string object from the buffer
return std::string(buf, end);
}
/*n字节的读取字段*/
std::字符串读取字段(std::istream和edfreader,大小\u n)
{
//不需要新的;
//事实上,如果忘记删除,新的可能会导致内存泄漏
std::载体buf(n);
//作为字节序列读取
edfreader.read(&buf.front(),n);
//查找缓冲区的第一个空格或结尾
尺寸=0;
while(end
std::string
为您分配内存;您可以像Python字符串一样使用它,只是它是可修改的
这里所做的唯一假设是操作系统的字符集是(的超集)ASCII,对于edfreader
来说,这都是二进制数据吗?那么您不想将其读入std::string
对象,这不是它们的用途。相反,为您的信号定义一个类。实际上,只有报头是纯ASCII,但在报头后面是由16位整数组成的实际信号流ers(缩写),这就是为什么我以二进制形式打开它。但标题肯定是ASCII。ASCII字符串总是完全填充字段吗?还是以nul结尾?每个字段总是以nul结尾(即,是一个8字节字段,七个字符+一个nul)?@larsmans..EDF规范规定必须用空格填充字段的其余部分(禁止使用空终止符或其他任何内容),到目前为止,我用python打开的示例文件是这样的。这都是二进制数据吗?那么您不想将其读入std::string
对象,这不是它们的用途。相反,请为您的