【问题标题】:C using strtok to parse an input fileC使用strtok解析输入文件
【发布时间】:2015-10-05 23:05:16
【问题描述】:

目前正在尝试解析 C 中的输入文件以提取变量。

输入文件如下所示:

% this is a comment
x 3
% another comment
y 5.0
% one last comment
z 4

x、y 和 z 是我的 C 类中的预定义变量。我的目标是解析这个文件,使 int x 的值为 3,y 的值为 5.0,z 的值为 4。任何以 % 开头的行最终都会被忽略

我已经设法使用 fgets 和 sscanf 做到这一点 - 这是尝试:

while (!feof(inputFile)) {
    fgets(ch,500,inputFile);
    if (sscanf(ch, "x %d", &x)) {
        printf("x: %d\n", x);
    } else if (sscanf(ch, "y %lf", &y)) {
        printf("y: %lf\n", y);
    } else if (sscanf(ch, "z %d", &z)) {
        printf("z: %d\n", z);
    }

这会打印出所需的结果。但是现在我正在尝试使用 fgets 和 strtok 因为我认为我不能让上面的代码与矩阵一起使用(即如果我在输入文件中有(注意在这种情况下 a 也将在我的 c文件):

a
1 -1 3
2 1 6
9 3 0

我想将这些值存储在一个 3x3 矩阵中,我认为使用 sscanf 是不可能的(特别是如果矩阵维度是可变的 - 但它始终是一个 n * n 矩阵)。我使用 fgets 和 strtok 的尝试是:

while (!feof(inputFile)) {
    fgets(ch,500,inputFile);
    token = strtok(ch, " ");
    while (token) {
        if (strcmp(token, "x")) {
            printf("%s", "x found");
            // Here is my problem - how do I look at the next token where the value for x is stored

        }
        token = strtok(NULL, " ");
        break;
}
    break;
}

我的代码中的问题已在评论中说明。我一直在考虑这个问题,尝试了各种各样的事情。我认为困难在于理解 strtok 的工作原理——最初我试图将每个标记存储到一个数组中。

感谢任何帮助,帮助我找出如何复制现有代码以使用 strtok 而不是 sscanf,以便我可以解析矩阵。

我知道有一些解析问题,但我还没有看到解决如何解析矩阵的问题。

谢谢

【问题讨论】:

  • 首先将while (!feof(inputFile)) { fgets(ch,500,inputFile); 替换为while (fgets(ch,500,inputFile)) {(在某处可能有重复的帖子,why (!feof()) {...} 总是错误的。)
  • 它是否有效地做同样的事情?我相信我最初尝试了后者并得到了一些奇怪的结果 - 但是很可能我搞砸了。会这样做,谢谢。
  • 你知道sscanf()的返回值是什么意思吧? 3 x 3 矩阵是什么意思,能举个例子吗?
  • 据我了解,它返回匹配的项目数 - 但我已经看到它使用了我在代码中使用它的方式。
  • while-feof-file-is-always-wrong 是 wildplasser 所指的帖子。看看strtolstrtod 来解决您的问题。

标签: c parsing matrix


【解决方案1】:

首先将行分成一组标记。然后,基于第一个令牌,您可以使用strtolstrtod 来转换剩余的令牌。下面的代码演示了如何将输入行分解为一个标记数组

char line[500];
char *token[200];
int tokenCount = 0;
while ( fgets( line, sizeof line, fp ) != NULL )
{
    token[0] = strtok( line, " " );
    if ( strcmp( token[0], "%" ) == 0 )   // skip comments
        continue;

    // break the line into tokens
    int i;
    for ( i = 1; i < 200; i++ )
        if ( (token[i] = strtok( NULL, " " )) == NULL )
            break;
    tokenCount = i;

    // output the token array
    for ( i = 1; i < tokenCount; i++ )
        printf( "%s: %s\n", token[0], token[i] );
}

for 循环生成从 1 到 200 的数组索引。strtok( NULL, " " ) 从行中提取下一个标记,并返回指向该标记的指针(如果没有更多标记,则返回 NULL)。返回值存储在token[i] 中。如果返回值为NULL,则循环中断。

【讨论】:

  • 谢谢。只是想知道您是否可以解释代码的第二位 (//break the line into tokens) 是如何工作的?
  • @F.Tahir 最后添加了解释,希望对您有所帮助。
  • 好的,所以基本上我们从文件中取出一行,将其分解为一个字符串数组,对其执行一些操作,然后转到文件中的下一行。如果这是正确的,那么旧的数组值是否刚刚被覆盖?
  • 是的,输入行和令牌指针数组都将被每一行覆盖。但期望您将标记转换为数字并将这些数字存储在其他地方(或在继续下一行之前使用它们)。
  • 第一次调用strtok,你传递一个指向整行的指针,strtok返回一个指向第一个标记的指针。从那时起,您将NULL 传递给strtok,它会返回一个指向下一个令牌的指针。因此,例如,token[0] = strtok(line," "); 行会将token[0] 设置为"x""y""z""%"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多