迭代C中文件中每行的每个标记

时间:2013-11-22 03:59:23

标签: c file token tokenize

我正在尝试解析文件每行中的每个标记。但是我在内部while循环中得到一个无限循环。为什么是这样?这不是因为“真实”条件,因为我在while循环中有break语句。我想我不对 当我到达一条线的末尾时检查。

char currentLine[MAXIMUM_LINE_LENGTH + 1]; // + 1 for terminating char

    while (true) {
        if (fgets(currentLine, MAXIMUM_LINE_LENGTH, inputFilePointer) == EOF ) {
            break;
        } else { // we need to parse the currentLine
            // check if the currentLine is too long
            if (strlen(currentLine) > MAXIMUM_LINE_LENGTH) {
                // print to the file that the currentLine being parsed it too long
                printf(
                        "WARNING: currentLine is too long and must be <= 256 characters\n");
                continue; // move on to next line in input file
            } else { // currentLine has valid length
                while (true) {
                    // iterate through each token within the currentLine and parse the token
                    char *currentToken = strtok(currentLine, " $,\t");
                    printf("currentToken = %s", currentToken);
                                    // do something with currentToken

                    if (currentToken == NULL || *currentToken == '#') {
                        break; // <== ERROR This break statement is never getting hit WHY?
                    }
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

您应该从第二次迭代开始使用strtok()调用NULL

喜欢这个

  token = strtok(input, tok);
  while (token ! = NULL ) {
        token = strtok(NULL, tok);
  /*do token processing*/
  }

有关详细信息,请参阅此示例:

http://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm

答案 1 :(得分:0)

几点:

如果您将MAXIMUM_LINE_LENGTH定义为常量,那么您的WARNING消息应该真正引用它,而不是对值256进行硬编码。但这不是实际问题。

代码需要

char currentLine[MAXIMUM_LINE_LENGTH + 1]; // + 1 for terminating char

while (true) {
    if (fgets(currentLine, MAXIMUM_LINE_LENGTH, inputFilePointer) == EOF ) {
        break;
    } else { // we need to parse the currentLine
        // check if the currentLine is too long
        if (strlen(currentLine) > MAXIMUM_LINE_LENGTH) {
            // print to the file that the currentLine being parsed it too long
            printf( "WARNING: currentLine is too long and must be <= 256 characters\n");
            continue; // move on to next line in input file
        } else { // currentLine has valid length
            char *currentToken = strtok(currentLine, " $,\t");
            while(currentToken != NULL && *currentToken != '#') {
                // iterate through each token within the currentLine and parse the token
                printf("currentToken = %s", currentToken);
                    // do something with currentToken
                currentToken = strtok(NULL, " $,\t"); // get next token
            }
        }
    }
}

发生了什么事? strtok函数实际上“记住”您要求的字符串,并在nul字符处找到一个令牌;下次调用它时,它将“在下一个点”启动,并扫描下一个令牌。所以它实际上会覆盖你的初始字符串,并慢慢地“扼杀”它。

在原始代码中,您不断将“新”字符串传递给strtok,因此它永远不会超过第一个令牌。它需要通过NULL来保持扼杀(如上例所示)。

另请注意,我使用了两个版本的strtok调用来清理代码结构的事实 - 现在while的条件是终止条件(因为第一次调用strtok发生在我们进入while循环之前)。