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');
很好!
我在 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');
很好!