C 程序无法识别从 MATLAB 导出的文件中的“\n”

C program doesn't recognize '\n' in file exported from MATLAB

我在 MATLAB 中有一个矩阵 G,我使用以下方法打印到文本文件中:

file = fopen('G.dat','w');
fprintf(file, [repmat('%f\t', 1, size(G, 2)) '\n'], G'); 
fclose(file);

这个矩阵的维度是 100 x 500。如果我使用 awk 计算行和列,例如,使用

cat G.dat | awk '{print NF}END{print NR}' 

我看到尺寸与原始尺寸一致。

现在,我想从计算第一行列数的 C 程序中读取此文件 G.dat,以了解列的维度,如:

    while (!feof(file) && (fscanf(file, "%lf%c", &k, &c) == 2) ) {
        Ng++; 
        if (c == '\n') 
            break;
}

不幸的是它给了我 Ng = 50000 并且它不识别任何'\n'。 相反,如果我只是通过复制和粘贴数据来创建文本文件,它就可以工作。你能解释一下为什么吗?谢谢!

你在Windows工作吗?尝试以文本模式打开输出文件:

file = fopen('G.dat','wt');

这将在写入文件时自动在每个换行符前插入一个回车return。

如果我正确理解了 matlab 语法,对于 3x2 矩阵,它会扩展为类似 %f\t%f\t%f\t\n\%f\t%f\t%f\t\n 的格式字符串。请注意每行末尾的额外 \t 。如果这个假设是正确的,一行中的最后一个 fscanf() 调用会将最后一个 \t 分配给 &c。下一个 fscanf() 调用将跳过 \n,因为它与您的格式不匹配。

我建议您使用 fgets() 代替读取每一行,然后使用 strtok() 遍历字段,使用 atof() 读取值,例如

char buf[8192];
if (fgets(buf, 8192, file))
{
    if (strtok(buf, '\t'))
    {
        ++Ng;
        while (strtok(0, '\t')) ++Ng;
    }
}
else
{
    /* error reading ... */
}

代码的方法对于 "counts the columns of the first row just to understand the columns' dimension" 来说太脆弱了。 fscanf(file, "%lf%c"... 太容易受到变体白色-space 分隔符和 EOL 的影响,无法检测到 '\n'.

建议明确检查white-space以确定宽度:

// return 0 on success, 1 on error
int GetWidth(FILE *file, size_t *width) {
  *width = 0;
  for (;;) {
    int ch;
    while (isspace(ch = fgetc(file))) {
      if (ch == '\n') return 0;
    }
    if (ch == EOF) return 0;
    ungetc(ch, file);
    double d;
    if (fscanf(file, "%lf", &d) != 1)) {
      return 1;  // unexpected non convertible text
    }
    (*width)++;
  }
}

//Sample, usage
size_t width;
if (GetWidth(file, &width)) return 1;

// read entire file
rewind(file);
for (size_t line = 0; foo(); line++)
  for (size_t column = 0; column<width; column++) {
    double d;
    if (fscanf(file, "%lf", &d) != 1)) {
      break;  // EOF, unexpected non convertible text or input error
    }
  }
  ...
}

Matlab 将行写为

 %f\t%\f .. %f\t\n 

这是个问题。我用过

dlmwrite('G.dat', G, '\t');

很好!