【问题标题】:Access the next word/string访问下一个单词/字符串
【发布时间】:2016-02-17 02:55:03
【问题描述】:

我有一个简单的基于 C 的代码来读取文件。逐行读取输入。标记该行并打印当前标记。我的问题是,如果满足某些条件,我想打印下一个令牌。你知道怎么做吗?我真的需要你对这个项目的帮助。谢谢 代码如下:

main(){

FILE *input;
FILE *output;
//char filename[100];

const char *filename = "sample1.txt";
input=fopen(filename,"r");
output=fopen("test.st","w");
char word[1000];
char *token;
int num =0;
char var[100];

fprintf(output,"LEXEME, TOKEN");
while( fgets(word, 1000, input) != NULL ){ //reads a line

token = strtok(word, " \t\n" ); // tokenize the line    
while(token!=NULL){ // while line is not equal to null
    fprintf(output,"\n");
    if (strcmp(token,"SIOL")==0)
        fprintf(output,"SIOL, SIOL", token);
    else if (strcmp(token,"DEFINE")==0)
        fprintf(output,"DEFINE, DEFINE", token);
    else if (strcmp(token,"INTEGER")==0){
        fprintf(output,"INTEGER, INTEGER");
        strcpy(var,token+1);
        fprintf(output,"\n%s,Ident",var);
    }
    else{
        printf("%s\n", token);
    }       
    token = strtok(NULL, " \t\n" ); //tokenize the word     
}}fclose(output);return 0;}

【问题讨论】:

  • 你试过strtok吗?
  • strtok 是一个不错的选择,但如果我理解正确,您想根据当前的某些条件打印或不打印下一个,那么如果您正在解析该行串行方式,为什么不在“无打印”情况下跳到以下空格或换行符。您将需要发布更多详细信息以获得更详细的帮助。不知道自己目前在做什么极大地限制了您可以获得的帮助。
  • 是的,这就是我用来标记该行的方法。我可以打印当前的令牌。如果满足某些条件,我需要打印下一个或即将到来的令牌。例如,字符串是“The quick brown fox” 当前标记是 'The'。 if (strcmp("The", "The")==0) printf ("quick").

标签: c string pointers file-handling


【解决方案1】:

使用strtok函数很容易实现。请注意,如果您将空指针作为第一个参数,该函数将继续扫描先前成功调用该函数的相同字符串。因此,如果您需要下一个令牌,只需调用

char* token = strtok(NULL, delimeters);

看下面的小例子

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

int main(void)
{
    char str[] = "The quick brown fox";

    // split str by space
    char* token = strtok(str, " ");

    // if a token is found
    if(token != NULL) {
        // print current token
        printf("%s\n", token);
        // if token is "The"
        if(strcmp(token, "The") == 0) {
            // print next token
            printf("%s\n", strtok(NULL, " "));
        }
    }
    return 0;
}

输出将是

The
quick

【讨论】:

    【解决方案2】:

    继续我的评论。我不确定我是否完全理解您的需求,但如果您有字符串:

    "The quick brown fox";
    

    而且,你想对字符串进行标记,打印 next 单词,只有满足 current 单词的条件,那么你需要调整你的想法只是一点点。在您的示例中,您想要打印 next 单词 "quick",前提是 current 单词是 "The"

    思维的调整是你看待考试的方式。如果 current 匹配某些条件,而不是考虑打印 next 单词,您需要保存 last 单词,并且只打印 current 如果 last 单词匹配某些条件 -- 在您的示例中为 "The"

    要处理这种情况,您可以使用至少包含47 个字符的静态声明字符数组(Merriam-Websters Unabridged Dictionary 中最长的单词是 46 个字符)。我将在下面的示例中使用48。您可能很想只保存指向最后一个单词的指针,但是当使用 strtok 时,无法保证上一次迭代返回的内存地址会被保留——所以请复制该单词。

    将各个部分放在一起,您可以执行以下操作。它将先前的标记保存在last 中,然后将当前单词与最后一个单词进行比较,如果last == "The" 则打印当前单词:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAXW 48
    
    int main (void) {
    
        char str[] = "The quick brown fox";
        char last[MAXW] = {0};
        char *p;
    
        for (p = strtok (str, " "); p; p = strtok (NULL, " ")) 
        {
            if (*last && strcmp (last, "The") == 0)
                printf (" '%s'\n", p);
            strncpy (last, p, MAXW);
        }
    
        return 0;
    }
    

    输出

    $ ./bin/str_chk_last
     'quick'
    

    如果您有任何问题,请告诉我。


    测试说明

    正如评论中所写,*last 只是last[0] 的简写。所以测试的第一部分,*last 只是测试if ((last[0] != 0) &amp;&amp; ..。由于 last 最初被声明和初始化:

    char last[MAXW] = {0};
    

    last 中的所有字符都是 0 第一次通过循环。通过包含检查last[0] != 0,这只会导致printffor 循环第一次执行时被跳过。测试的速记如下:

        if ((last[0] != 0) && strcmp (last, "The") == 0)
            printf (" '%s'\n", p);
    

    伪代码中只是说:

        if (NOT first iteration && last == "The")
            printf (" '%s'\n", p);
    

    如果这没有意义,请告诉我。

    【讨论】:

    • 我明白你的意思 Mr.@david。我会尝试使用它,如果它有效,我会告诉你。非常感谢您的回复。顺便说一句,你答对了我的问题。
    • if (*last && strcmp (last, "The") == 0) 我想知道这个语句中*last是什么意思
    • 抱歉,这只是last[0] 的简写。只是检查字符串中的第一个字符不是'\0'。 (这是数字0 - 否则称为null-terminating 字符)这样想。在指针符号中array[0]*(array + 0)+ 0 不做任何事情,所以*array 只是array[0] 的快捷方式,完整的测试是((array[0] != '\0') &amp;&amp; ..。所有这一切都意味着它只是跳过了第一次迭代——因为 *array 是 NULL 然后通过初始化。 (例如char last[MAXW] = {0};)希望能解释一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 2021-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多