Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C程序不';不认识'\n';在从MATLAB导出的文件中_C_Matlab_Newline - Fatal编程技术网

C程序不';不认识'\n';在从MATLAB导出的文件中

C程序不';不认识'\n';在从MATLAB导出的文件中,c,matlab,newline,C,Matlab,Newline,我在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.

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

写入文件时,这将自动在每条换行符之前插入回车符。

如果我正确理解matlab语法,这将扩展为3x2矩阵的格式字符串,如
%f\t%f\t%f\t\n\%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 ... */
}

代码的方法太脆弱,无法“只为理解列的维度而对第一行的列进行计数”<代码>fscanf(文件“%lf%c”…
太容易受到各种空白分隔符和EOL的影响,无法检测
”\n'

建议明确检查空白以确定宽度:

// 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
    }
  }
  ...
}
//成功返回0,错误返回1
int GetWidth(文件*文件,大小*宽度){
*宽度=0;
对于(;;){
int-ch;
while(isspace(ch=fgetc(文件))){
如果(ch=='\n')返回0;
}
if(ch==EOF)返回0;
ungetc(ch,文件);
双d;
如果(fscanf(文件“%lf”,&d)!=1)){
返回1;//意外的不可转换文本
}
(*宽度)++;
}
}
//样品、用法
尺寸和宽度;
if(GetWidth(文件和宽度))返回1;
//读取整个文件
倒带(文件);
对于(size_t line=0;foo();line++)
对于(size\u t column=0;columnMatlab将行写入为

 %f\t%\f .. %f\t\n 
这是个问题,我用过

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

这很好!

使用二进制编辑器/查看器查看文件之间的差异。第二个文件不应该在第一个文件中吗?另外,编写一些小测试矩阵并在调试器中逐步执行。是的,好的。我已经更改了循环,但它不会更改结果。我将尝试使用小矩阵。使用
\r\n
可以解决您的问题吗问题?这没问题,但向量“buf”需要一个维度,我经常需要读取列顺序从1e2到1e6的矩阵。在这种情况下,一次读取一个字符的文件,计算
\t
字符,直到你点击
\n
并使用
malloc()
作为大小为
(Ng*(#maxlen(float)#+2)
,最大长度是文本表示法中浮点的最大长度。。。