【问题标题】:How to print part of a tokenized string from a file in C如何从C中的文件中打印部分标记化字符串
【发布时间】:2021-03-11 15:42:14
【问题描述】:

我在处理来自文件的一行的标记化字符串时遇到了一些问题。我想打印找到令牌的行,但我似乎找不到解决方法。请忽略文件部分的输出以及作者、类和方法 if 语句,因为我已将它们整理出来。

例如,我希望它从这一行打印: @return the matric 仅此部分:the matric

代码:

#include <stdio.h>
#include <string.h>

int main (int argc, char **argv)
{
    char line [1000];
    char *delimeters = ".,; \t\n";
    int total_lines = 0;
    int total_comments = 0;
    int nonblank_lines = 0;

    FILE *input = fopen (argv[2], "r");
    FILE *output = fopen (argv[4],"w");
    
    while(fgets(line,1000,input) != NULL)
    {
        char *word = strtok(line, delimeters);
        total_lines++;
        
        if(word != NULL)
        {
            nonblank_lines++;
        }
        
        if(word != NULL && strcmp(word,"/**") == 0)
        {
            total_comments++;
        }
        
        while(word != NULL)
        {
            if(word != NULL && strcmp(word,"@author") == 0)
            {
                char *author_name = strtok(NULL, delimeters);
                char *author_surname = strtok(NULL, delimeters);
                printf ("Author: %s %s\n", author_name, author_surname);
            }
        
            if(word != NULL && strcmp(word,"public") == 0)
            {
                char *jmp = strtok(NULL, delimeters);
                    
                if(jmp != NULL && strcmp(jmp,"class") == 0)
                {
                    char *class_name = strtok(NULL, delimeters);
                    printf ("Class %s\n", class_name);
                }else{
                    char *method_name = strtok(NULL, delimeters);
                    printf ("Method %s\n", method_name);
                }
            }
            
            if(word != NULL && strcmp(word,"@return") == 0)
            {
                printf("Enters IF 4\n");
                
                char *return_value = strtok(NULL, delimeters);
                
                printf ("Returns: %s\n", return_value;
            }
        
            /*if(word != NULL && strcmp(word,"@param") == 0)
            {   
                printf("Enters IF 5\n");
                char *parameters = strtok(NULL, delimeters);
                printf("Parameter: %s\n", parameters);
                
                //int param_found
                
            }*/
            word = strtok(NULL, delimeters);
        }
    }
    
    printf ("The total number of lines is %d\n", total_lines);
    printf ("The total number of  non-blank lines is %d\n", nonblank_lines);
    printf ("The total number of comments is %d\n", total_comments);
    
    fclose(input);
    fclose(output);
    return 0;
}

【问题讨论】:

  • 如果您的行中的第一个标记不是@return(在该行示例中是*),您的内部while循环将永远不会转到下一个标记,因为if语句条件将是假的。
  • 但我得到的输出是the
  • 这意味着您没有提供一些信息。使用您编写的代码和包含您提到的行的文件,您的程序将进入内部 while 循环的无限循环,因为它的条件结果没有任何改变。
  • 我添加了所有我拥有的代码。
  • 如果您的目标是从每一行返回 @word 之后的其余单词,那么您需要在每个 if 语句中使用 while 循环迭代 strtok()当前行中的其余单词并一一输出。现在你只输出第一个。

标签: c string printing token


【解决方案1】:

因此,按照我的评论,您会希望每个 if 语句都有类似这样的块:

        while(fgets(line, 1000, input) != NULL)
        {
            char *first_word_in_line = strtok(line, delimeters);

            if(strcmp(first_word_in_line, "@return") == 0)
            {
                char *word = strtok(NULL, delimeters);
                printf ("Returns: ");
                while(word != NULL)
                {
                    printf ("%s ", word);
                    word = strtok(NULL, delimeters);
                }
                printf("\n");
            }
        }

请注意,我在 word 顶部添加了另一个变量 first_word_in_line - 这不是必须的,但它可以在您编码时减少混淆,并且它表明该行中的第一个单词具有不同的含义,因为这只是标题.

另外,您应该阅读有关 strcmpstrncmp 的信息。通常最好使用strncmp

【讨论】:

  • 非常感谢您的帮助,即使我已经想出了另一种方法,我也会尝试您的代码
【解决方案2】:

我得到的答案是这样的:

if(word != NULL && strcmp(word,"@return") == 0)
        {
            char *return_value = strtok(NULL, delimeters);
            printf ("Returns: ");
                while(return_value != NULL)
                {
                    printf ("%s ", return_value);
                    return_value = strtok(NULL, delimeters);                
                }
            printf("\n");
        }

【讨论】:

    【解决方案3】:

    一开始你的参数有点乱。

    ./program.c input.txt output.txt
    

    argv[0] 会给你程序的名称(在本例中是 program.c),argv[1] 你传递的第一个参数(input.txt)和argv[2] 第二个参数(output.txt)

    还缺少一个括号,对于评论/* comment */,c 中的一颗星就足够了。

    修复它对我有用。 但是请注意,如果您按照自己的方式使用 strtok() 剪切注释,则注释的开头左右必须有一个分隔符。

    somecode; /* This should be recognized */
    somecode;/* This not */
    somecode; /*This neither */
    

    这里是更正的代码:

    #include <stdio.h>
    #include <string.h>
    
    int main (int argc, char **argv)
    {
        char line [1000];
        char *delimeters = ".,; \t\n";
        int total_lines = 0;
        int total_comments = 0;
        int nonblank_lines = 0;
    
        FILE *input = fopen (argv[1], "r");
        FILE *output = fopen (argv[2],"w");
        
        while(fgets(line,1000,input) != NULL)
        {
            char *word = strtok(line, delimeters);
            total_lines++;
            
            if(word != NULL)
            {
                nonblank_lines++;
            }
            
            if(word != NULL && strcmp(word,"/*") == 0)
            {
                total_comments++;
            }
            
            while(word != NULL)
            {
                if(word != NULL && strcmp(word,"@author") == 0)
                {
                    char *author_name = strtok(NULL, delimeters);
                    char *author_surname = strtok(NULL, delimeters);
                    printf ("Author: %s %s\n", author_name, author_surname);
                }
            
                if(word != NULL && strcmp(word,"public") == 0)
                {
                    char *jmp = strtok(NULL, delimeters);
                        
                    if(jmp != NULL && strcmp(jmp,"class") == 0)
                    {
                        char *class_name = strtok(NULL, delimeters);
                        printf ("Class %s\n", class_name);
                    }else{
                        char *method_name = strtok(NULL, delimeters);
                        printf ("Method %s\n", method_name);
                    }
                }
                
                if(word != NULL && strcmp(word,"@return") == 0)
                {
                    printf("Enters IF 4\n");
                    
                    char *return_value = strtok(NULL, delimeters);
                    
                    printf ("Returns: %s\n", return_value);
                }
            
                /*if(word != NULL && strcmp(word,"@param") == 0)
                {   
                    printf("Enters IF 5\n");
                    char *parameters = strtok(NULL, delimeters);
                    printf("Parameter: %s\n", parameters);
                    
                    //int param_found
                    
                }*/
                word = strtok(NULL, delimeters);
            }
        }
        
        printf ("The total number of lines is %d\n", total_lines);
        printf ("The total number of  non-blank lines is %d\n", nonblank_lines);
        printf ("The total number of comments is %d\n", total_comments);
        
        fclose(input);
        fclose(output);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-05
      • 2021-04-28
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多