c - 如何在 C 编程中泛化 SSCANF 和#DEFINE

标签 c generics parsing

下面的代码尝试解析包含这 3 行的文件:

 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 };

但是实际上,实际输入文件中的字段数不固定。 因此,每行它们可以大于 6、12 和 12。

有什么方法可以为此目的概括definesscanf 吗? 完整代码如下:

#include <stdio.h>
#include <stdlib.h>

// This is hard coded
#define LINE1_COUNT 6
#define LINE2_COUNT 12
#define LINE3_COUNT 12 

int main() {
    int Line1[LINE1_COUNT], Line2[LINE2_COUNT] ;
    float Line3[LINE1_COUNT] ;
    int j, check;

    FILE *file = fopen("test.dat","r");

    if (file) {
        char line[BUFSIZ];

        if (fgets(line, BUFSIZ, file)) { // read line 1, integers
            int *i = Line1;//for easier reading
            check = sscanf(line, "%i%i%i%i%i%i", &i[0],&i[1],&i[2],&i[3],&i[4],&i[5]) ;
            if (check != LINE1_COUNT){
                fprintf(stderr, "Failed to read expected %d values from line 1\n", LINE1_COUNT);
                exit(1);
            }
        }else fprintf(stderr, "Couldn't read line 1!\n");
        if (fgets(line, BUFSIZ, file)) { // read line 2, integers
            int *i = Line2;//for easier reading
            check = sscanf(line, "%i%i%i%i%i%i%i%i%i%i%i%i", 
                &i[0],&i[1],&i[2],&i[3],&i[4],&i[5],&i[6],&i[7],&i[8],&i[9],&i[10],&i[11]) ;
            if (check != LINE2_COUNT){
                fprintf(stderr, "Failed to read expected %d values from line 2\n", LINE2_COUNT);
                exit(1);
            }
        }else fprintf(stderr, "Couldn't read line 2!\n");
        if (fgets(line, BUFSIZ, file)) { // read line 3, floats
            float *f = Line3;//for easier reading
            check = sscanf(line, "%f%f%f%f%f%f%f%f%f%f%f%f", 
                &f[0],&f[1],&f[2],&f[3],&f[4],&f[5],&f[6],&f[7],&f[8],&f[9],&f[10],&f[11]) ;
            if (check != LINE3_COUNT){
                fprintf(stderr, "Failed to read expected %d values from line 3\n", LINE3_COUNT);
                exit(1);
            }
        }else fprintf(stderr, "Couldn't read line 3!\n");
        fclose(file);
    }else {
         perror("test.dat");
    }

    for (j=0;j<LINE1_COUNT;j++){
        printf("%i\t",Line1[j]);
    }
    printf("\n");
    for (j=0;j<LINE2_COUNT;j++){
        printf("%i\t",Line2[j]);
    }
    printf("\n");
    for (j=0;j<LINE3_COUNT;j++){
        printf("%f\t",Line3[j]);
    }
    printf("\n");

    printf("Press return to exit");
    getchar();
    return 0;
}

最佳答案

如果一行中的元素数量不固定(行数可能也是如此),您可以执行以下操作之一:

  1. 使用数组的数组 - int line_elements[MAX_LINES][MAX_LINE_LENGTH] - 但这仍然只有静态大小
  2. 使用指针数组 - int* lines[],然后在迭代槽线时动态分配所需的空间。

你不能使用一个 sscanf 里面有预定义数量的 %s。尝试使用 strtok用于将字符串标记为标记,因为您用空格分隔数字。

关于c - 如何在 C 编程中泛化 SSCANF 和#DEFINE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1339258/

相关文章:

java - 将一串数字从已解析字符串的一部分更改为 int

ruby-on-rails - 如何删除开始转发的消息 : part of an email body in a rails 3 app

c++ - 从 C++ 调用 C 函数时,如何告诉 gcc 放宽对类型转换的限制?

c - 为什么 while 循环会无限运行而不是等待来自 fgets() 的更多输入?

delphi - TDictionary<TVehicle, TPerson> 的 Equals 和 GetHashCode

c# - 是否可以创建一个通用的 Func<T><T>

java智能日期解析器

objective-c - 枚举按位掩码限制

c++ - 记事本显示 Unicode 字符,因为文件是 ANSI?

c# - 在运行时使用动态泛型参数转换泛型