【问题标题】:Scanning numbers from a file in C从 C 中的文件中扫描数字
【发布时间】:2017-11-22 22:23:54
【问题描述】:

我试图从文件中扫描一些坐标 [X, Y, Z],但总是返回为分段错误。所以,我有一些问题要问:

  1. 我不知道文件中有多少个点,但是如果我将结构数组留空,则会出现错误。有没有办法在不定义最大数量的情况下做到这一点?

  2. 我可以使用指针吗?我对他们不是很有天赋。

我认为导致分段错误的原因是 fscanf,但我无法修复它

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define MAX 20000

FILE *f1;

struct points{
  int       n;
  float x[MAX];
  float y[MAX];
  float z[MAX];
};

int main (){

  int i;
  struct points cart1[MAX];
  f1 = fopen("point_cloud1.txt", "r");
  if (f1 == NULL){
    printf("Error Reading File\n");
    exit (0);
  }
  for(i = 0; !feof(f1); i++){
    fscanf(f1, "%f%f%f", &cart1[i].x[i], &cart1[i].y[i], &cart1[i].z[i]);
  }
  (*cart1).n = i+1;
  printf("\nNumber: %d coord1: %f, %f, %f\n", (*cart1).n, (*cart1).x[0], (*cart1).y[0], (*cart1).z[0]);

  fclose(f1);

return 0;
}

文件的开头是这样的:

2.84838 -1.21024 -0.829256
7.09443 -3.01579 0.134558
3.31221 -1.40868 -0.830969
7.09813 -3.01883 0.404243
4.05924 -1.72723 -0.857496

【问题讨论】:

  • 1) for(i = 0; !feof(f1); i++){ :: feof() 错误 2) 为什么要分配 3*MAX*MAX 个项目? 3) 20000*20000*something 可能不适合堆栈。
  • (*cart1).n = i+1; 仅更改第一个结构。
  • struct points cart1[MAX] 数组很大。它是一个包含 20000 个点的数组,每个点有 60000 个浮点数。超过 4 GB。你确定你是故意的吗?
  • 如果 x,y,z 坐标属于一起,那么使用结构数组而不是数组结构可能更有意义
  • 也许你应该用简单的英语告诉我们你实际上想要做什么。请edit您的问题并明确那里

标签: c linux


【解决方案1】:

你有一个非常大的数组声明为局部变量:

struct points cart1[MAX];

数组有20000个元素,每个数组元素(假设intfloat各占4个字节)4 + 4 * 20000 + 4 * 20000 + 4 * 20000 = 240004个字节大小为 4,800,080,000 ( 4.8 GB )。即使作为一个全局变量,这也是巨大的。作为在大多数实现中位于堆栈上的本地人,这很容易超过堆栈大小,从而导致核心转储。

您不需要这些结构的数组,只需要一个。然后你像这样使用它:

int main (){

  int i, r;
  struct points cart1;
  f1 = fopen("point_cloud1.txt", "r");
  if (f1 == NULL){
    printf("Error Reading File\n");
    exit (0);
  }
  for(i = 0, r = 3; r == 3; i++){
    r = fscanf(f1, "%f%f%f", &cart1.x[i], &cart1.y[i], &cart1.z[i]);
  }
  cart1.n = i+1;
  printf("\nNumber: %d coord1: %f, %f, %f\n", cart1.n, cart1.x[0], cart1.y[0], cart1.z[0]);

  fclose(f1);

return 0;
}

另外,don't use feof

【讨论】:

  • 谢谢,问题解决了。但现在我只有一个问题。通过不使用 EOF,for 将继续执行直到 fscanf r != 3 返回。而当文件结束时,它会再执行一次r = 0,然后结束for,对吧?
  • @LuisParente 没错。当到达文件末尾时,r 将为 0,循环将结束。所以在设置计数时,实际上应该使用i-1 而不是i+1。另请注意,您必须对 feof 执行相同操作。
  • 是的,我现在明白了。在我没有得到任何反馈之前,那是不可见的。关于第一个问题,如果我不知道坐标的数量,我怎么能在没有 MAX 的情况下使用数组?不可能吗?
【解决方案2】:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define MAX 20000


struct point {          /* structure for *one* point */
  int       n;
  float x;
  float y;
  float z;
};

int main (void){

  FILE *f1;
  int ii;
  char *name="point_cloud1.txt";
  struct point  points[MAX];    /* array of MAX structures, for MAX points */

  f1 = fopen(name, "r");
  if (f1 == NULL){              /* diagnostics to stderr, add relevant detail, such as the filename */
    fprintf(stderr, "Error Reading File:%s\n", name);
    exit (0);
  }

  for(ii = 0; ii < MAX ; ii++){ /*loop-sanity: test the array-bounds where you increment it */
    int ret;
    ret = fscanf(f1, "%f%f%f", &points[ii].x, &points[ii].y, &points[ii].z); /* use the return value */
    if(ret<3) {
        if( !feof(f1)) fprintf(stderr, "Reading %s failed at %d\n", name, ii);
        break;
        }
  points[ii].n = ii+1;
  }

  if (ii == MAX && !feof(f1)) {
        fprintf(stderr, "Reading %s : array may be incomplete\n", name);
        }

  fclose(f1);

  printf("Number: %d coord0: %f, %f, %f\n", ii, points[0].x, points[0].y, points[0].z);

return 0;
}

【讨论】:

    猜你喜欢
    • 2020-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-19
    • 2015-03-19
    相关资源
    最近更新 更多