Octave : replaced 'strread' with 'textscan' - throws "error: element number 4 undefined in return list

Octave : replaced 'strread' with 'textscan' - throws "error: element number 4 undefined in return list

我正在尝试 运行 Octave 中的 .m 脚本。它 运行 在 matlab 中很好。片段如下

fid=fopen(log_file);
number = 1;
while 1
    tline = fgetl(fid);
    if ~ischar(tline), break, end
    
    [time1,time2,time3, string1, string2, line_tag, data] = strread(tline,'%d%d%d%s%s%s%[^\n]','delimiter',': ');

Octave 抛出如下错误

log_file = ods_rlog.log
warning: strread is obsolete; use textscan instead
error: strread: %q, %c, %[] or bit width format specifiers are not supported yet.
error: called from
    strread at line 349 column 7
    plot_ods_rlog_s at line 35 column 59

根据建议,我用 textscan 替换了 strread,它给了我以下错误。

log_file = ods_rlog.log
error: element number 4 undefined in return list
error: called from
    plot_ods_rlog_s at line 35 column 59
>>

它读取的文件包含以下数据

02:30:18 : PROODS: OBSTACLE: CFUNS 25 27 22 25
02:30:18 : PROODS: OBSTACLE: START_END_ATOM 12 14
02:30:18 : PROODS: OBSTACLE: ATOMS 12 19 17 1 6058 R 4545031 3682089 4550870 3682088 4550670 3684688 4545231 3684689 3360 0
02:30:18 : PROODS: OBSTACLE: ATOMS 13 20 24 1 6058 R 4545231 3684689 4550670 3684688 4550669 3780977 4545230 3780978 3360 0
02:30:18 : PROODS: OBSTACLE: ATOMS 14 26 27 0 6058 R 4545230 3780978 4550669 3780977 4550670 3793976 4545231 3793977 3360 0

关于可能是什么问题的任何建议。

谢谢!

您使用的文本扫描有误。语法(根据文档)是:

 -- C = textscan (FID, FORMAT)
 -- C = textscan (FID, FORMAT, REPEAT)
 -- C = textscan (FID, FORMAT, PARAM, VALUE, ...)
 -- C = textscan (FID, FORMAT, REPEAT, PARAM, VALUE, ...)
 -- C = textscan (STR, ...)
 -- [C, POSITION, ERRMSG] = textscan (...)

即它需要一个或三个输出。你快过七了。

首先在单个输出中捕获您需要的内容,然后在必要时拆分它。

octave:1> datafile = fopen('data.colsv');
octave:2> C = textscan( datafile,'%d:%d:%d:%s:%s:%s%[^\n]');
octave:3> [time1,time2,time3, string1, string2, line_tag, data] = C{:}
time1 = 2
time2 = 30
time3 = 18
string1 =
{
  [1,1] = PROODS:
}

string2 =
{
  [1,1] = OBSTACLE:
}

line_tag =
{
  [1,1] = CFUNS
}

data =
{
  [1,1] = 25 27 22 25
}
    
    string2 =
    {
      [1,1] = OBSTACLE:
    }

    line_tag =
    {
      [1,1] = CFUNS
    }

    data =
    {
      [1,1] = 25 27 22 25
    }

但是,textscan 是一个可怕的 命令,您应该只使用它,因为 matlab 没有更好的选择(matlabexchange 中有一些 csv2cell 函数虽然)。

使用 textscan,您可以逐行捕获这些内容,并且必须循环。

更好的方法是使用 io 包中的 csv2cell 函数。 例如,使用上面的示例:

octave:4> pkg load io
octave:5> csv2cell ( 'data.colsv', ':' )
ans =
{
  [1,1] =  2
  [2,1] =  2
  [3,1] =  2
  [4,1] =  2
  [5,1] =  2
  [1,2] =  30
  [2,2] =  30
  [3,2] =  30
  [4,2] =  30
  [5,2] =  30
  [1,3] = 18 
  [2,3] = 18 
  [3,3] = 18 
  [4,3] = 18 
  [5,3] = 18 
  [1,4] =  PROODS
  [2,4] =  PROODS
  [3,4] =  PROODS
  [4,4] =  PROODS
  [5,4] =  PROODS
  [1,5] =  OBSTACLE
  [2,5] =  OBSTACLE
  [3,5] =  OBSTACLE
  [4,5] =  OBSTACLE
  [5,5] =  OBSTACLE
  [1,6] =  CFUNS 25 27 22 25
  [2,6] =  START_END_ATOM 12 14
  [3,6] =  ATOMS 12 19 17 1 6058 R 4545031 3682089 4550870 3682088 4550670 3684688 4545231 3684689 3360 0
  [4,6] =  ATOMS 13 20 24 1 6058 R 4545231 3684689 4550670 3684688 4550669 3780977 4545230 3780978 3360 0
  [5,6] =  ATOMS 14 26 27 0 6058 R 4545230 3780978 4550669 3780977 4550670 3793976 4545231 3793977 3360 0
}

您可能需要使用 strsplitcsvconcat / csvexplode 的某种组合进一步处理最后一列,但从这里开始已经更容易了。