【问题标题】:Iterating through each token of a line within a file in C遍历C中文件中一行的每个标记
【发布时间】:2013-11-22 03:59:23
【问题描述】:

我正在尝试解析文件每一行中的每个标记。但是我在内部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?
                    }
                }
            }
        }
    }

【问题讨论】:

    标签: c file token tokenize


    【解决方案1】:

    几点:

    如果您将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 的条件是终止条件(因为第一个在进入while循环之前调用strtok。

    【讨论】:

      【解决方案2】:

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

      这样

        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

      【讨论】:

        猜你喜欢
        • 2020-02-02
        • 2011-01-31
        • 2016-01-22
        • 1970-01-01
        • 2015-10-27
        • 2013-01-21
        • 2015-08-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多