解析选项卡用C编程语言将行转换为数组

给定一个带有此内容的文件(例如myfile.txt)(总是三行):

0 2 5 9 10 12 0 1 0 2 4 1 2 3 4 2 1 4 2 3 3 -1 4 4 -3 1 2 2 6 1 

我们如何解析文件,使其存储在数组中,就像它们以这种方式硬编码一样:

 int Line1[] = { 0, 2, 5, 9, 10, 12 }; int Line2[] = { 0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4 }; double Line3[] = { 2, 3, 3, -1, 4, 4, -3, 1, 2, 2, 6, 1 }; 

更新 :基于争吵的评论。 我目前仍然坚持使用此代码。

 #include  #include  #include  int main ( int arg_count, char *arg_vec[] ) { int ch; FILE * fp; int i; if (arg_count <2) { printf("Usage: %s filename\n", arg_vec[0]); exit(1); } //printf("%s \n\n", arg_vec[i]); // print file name if ((fp = fopen(arg_vec[1], "r")) == NULL) { // can't open file printf("Can't open %s \n", arg_vec[1]); exit(1) } const unsigned MAX_N=1000; int Line1[MAX_N]; int Line2[MAX_N]; double Line3[MAX_N]; unsigned N3=0; // Parsing content while ((ch = fgetc(fp)) != EOF) { if (ch=='\n' || ch=='\r') break; ungetc(ch,fp); assert(N3<MAX_N); fscanf(fp, " %1f", &Line3[N3++]); // not sure how to capture line 1 and 2 for // for array Line1 and Line2 } fclose(fp); // This fails to print the content the array for (int j=0; j <Line3; j++) { printf(Line3[j],"\n"); } return 0; } 

原则上我有问题:

  1. 找到如何将每一行分配给正确数组的方法。
  2. 打印出arrays的内容(用于检查)。

string.h strtok()应该完成工作。

  1. 您将需要动态分配的数组。 除非你在编译时能够完全确定你要读入的数据量(并且你不能,或者至少不应该),否则你将不得不使用指向使用malloc()分配的数组的指针malloc()realloc() 。 如果您不知道如何执行此操作,请阅读C中的内存管理。
  2. 您将需要将char * (文本)数据转换为数字类型。 我个人最喜欢的函数是strtol()strtod() ,但也有atoi()atof()函数可以使用。 但是,由于我们正在处理文件流,因此您可以通过fscanf()更好地为您进行转换。 所有这些函数都在标准库中,除了strtod() ,它是特定于C99的(如果幸运的话,它就在那里)。

如果您不知道如何使用那里命名的任何函数,那么在您的系统(第3部分,例如man 3 malloc )或互联网( malloc(3) )上应该很容易找到它们的联机帮助页。

这是一种不太常见的方法,只对输入字节进行一次传递。 Scanf会为您跳过空格,但您不希望它跳过换行符。 只要您的换行符紧跟最后一个非空格字符,读取单个字符并将其放回(如果它不是换行符)将起作用。 更强大的解决方案可以手动解析空格并在scanf之前放回第一个非空格字符。

也许只是将非空格字符复制到缓冲区并使用字符串 – >数字转换之一(sscanf,strtol等)会更简单。

使用库函数一次读取整行更常见,然后解析行。 ANSI C中没有任何内容可以帮助您,更不用说任意行长度了。

 #include  #include  const unsigned MAX_N=1000; /* use malloc/realloc if it matters to you */ double Line3[MAX_N]; unsigned N3=0; unsigned c; FILE *f; f=fopen("myfile.txt","r"); while ((c=fgetc(f)) != EOF) { if (c=='\n'||c=='\r') break; ungetc(c,f); assert(N3