如何在MATLAB中读取带有变量十六进制值列的文本文件?

3
我有一个相当大的文本文件(超过16,000行),其格式如下:
#ID     #Line Num       #Var Col Length Values (HEX):
45      00001           FFFF FFFF 0000 0000
45      00002           0000 0000 FFFF FFFF
47      00003           AAAA 1111 AAAA 1111 AAAA 1111
49      00004           BBBB 2222 

注意:这显然是虚构的数据,因为实际文件中有更多的HEX值。
在Matlab中,我尝试使用单行的textscan命令:
fp = fopen(filePath, 'rt');
readLine = fgetl(fp);
[ignored, pos] = textscan(readLine, '%d');
values = textscan(readLine(pos+1:end), '%x');

我遇到了一个格式不正确的字符串错误。我认为textscan不支持十六进制值的转换。我也尝试了这里找到的解决方案:

Problem (bug?) loading hexadecimal data into MATLAB

但是,这似乎也不起作用。我正在尝试避免逐个转换每个十六进制值(目前已实现的解决方案),因为这需要很长时间才能完成。如何从文本文件中扫描/解析可变列宽的十六进制值?
2个回答

3
您可以使用sscanf代替:
fp = fopen(filePath, 'rt');
readLine = fgetl(fp);
results = sscanf(readLine, '%x');

这将为您提供一个十六进制值转换为十进制的列。如果您需要单行输出,请将其转置:
results = results'

在此假设前两个术语也是十六进制值。如果您需要将前两个值分开为double,然后再将其余的值分为十六进制,请按以下步骤操作:

fp = fopen(filePath, 'rt');
readLine = fgetl(fp);
[ignored, pos] = textscan(readLine, '%d');
results = sscanf(readLine(pos+1:end), '%x');

2
您可以使用以下方法将文本文件读入字符串单元数组并使用 regexp 将其拆分为单独的值:
fp = fopen(filePath, 'rt');
C = textscan(fp, '%s', 'CommentStyle', '#', 'Delimiter', '');
C = regexp(C{:}, '\w+', 'match');
fclose(fp);

这应该会生成一个单元数组的单元数组,对于你的例子,它应该是这样的:
C =
    {'45'    '00001'    'FFFF'    'FFFF'    '0000'    '0000'}
    {'45'    '00002'    '0000'    '0000'    'FFFF'    'FFFF'}
    {'47'    '00003'    'AAAA'    '1111'    'AAAA'    '1111'    'AAAA'    '1111'}
    {'49'    '00004'    'BBBB'    '2222'}

您可以操作生成的单元格数组以满足您的需求。例如,丢弃每行中的前两列,并将所有内容转换为十进制:

result = cellfun(@(x)hex2dec(x(3:end)), C, 'UniformOutput', false)

1
这真的很整洁和有组织。它不是逐行读取文件,而是处理整个文件并将其转储到一个相当整齐有序的数据形式中。我对使用 hex2dec 感到担心,因为当我单独调用它时,它花费了很长时间(超过 2M 次和 136 秒),但这样做要快得多(小于 1 秒)! - James Mertz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接