访问下一个word/string
Access the next word/string
我有一个简单的基于 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
函数很容易实现。请注意,如果您将空指针作为第一个参数,该函数将继续扫描先前成功调用该函数结束的相同字符串。因此,如果您需要下一个令牌,只需调用
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
继续我的评论。我不确定我是否完全理解您的需求,但是如果您有字符串:
"The quick brown fox";
而且,你想标记字符串,打印 next 单词,只有满足关于 current 单词的条件时,那么你需要稍微调整一下你的想法。在您的示例中,您想要打印 next 单词 "quick"
,仅当 current 单词为 "The"
时。
思维上的调整,就是对考试的看法。如果 current 符合某些条件,而不是考虑打印 next 单词,您需要保存 last 字,并且仅在 last 字匹配某些条件时打印 current - 在您的示例中为 "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
只是 shorthand 对应 last[0]
。所以测试的第一部分 *last
只是测试 if ((last[0] != 0) && ..
。由于 last 最初被声明和初始化:
char last[MAXW] = {0};
last
中的所有字符在第一次通过循环时都是 0
。通过包含检查 last[0] != 0
,这只会导致 printf
在 for
循环第一次执行时被跳过。测试的普通格式如下:
if ((last[0] != 0) && strcmp (last, "The") == 0)
printf (" '%s'\n", p);
在伪代码中只是说:
if (NOT first iteration && last == "The")
printf (" '%s'\n", p);
如果这没有意义,请告诉我。
我有一个简单的基于 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
函数很容易实现。请注意,如果您将空指针作为第一个参数,该函数将继续扫描先前成功调用该函数结束的相同字符串。因此,如果您需要下一个令牌,只需调用
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
继续我的评论。我不确定我是否完全理解您的需求,但是如果您有字符串:
"The quick brown fox";
而且,你想标记字符串,打印 next 单词,只有满足关于 current 单词的条件时,那么你需要稍微调整一下你的想法。在您的示例中,您想要打印 next 单词 "quick"
,仅当 current 单词为 "The"
时。
思维上的调整,就是对考试的看法。如果 current 符合某些条件,而不是考虑打印 next 单词,您需要保存 last 字,并且仅在 last 字匹配某些条件时打印 current - 在您的示例中为 "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
只是 shorthand 对应 last[0]
。所以测试的第一部分 *last
只是测试 if ((last[0] != 0) && ..
。由于 last 最初被声明和初始化:
char last[MAXW] = {0};
last
中的所有字符在第一次通过循环时都是 0
。通过包含检查 last[0] != 0
,这只会导致 printf
在 for
循环第一次执行时被跳过。测试的普通格式如下:
if ((last[0] != 0) && strcmp (last, "The") == 0)
printf (" '%s'\n", p);
在伪代码中只是说:
if (NOT first iteration && last == "The")
printf (" '%s'\n", p);
如果这没有意义,请告诉我。