使用 strtok 查找令牌对
Using strtok to find pair of token
我正在解决这个作业问题:在文本中找到一对相邻的单词,使得两个单词都以同一个字母开头。
我知道我需要使用strtok
功能来解决这个问题。
#include <string.h>
#include <stdio.h>
#include <conio.h>
int main(void) {
char testString[] = "In the end, we will remember not the words of our enemies, but the silence of our friends";
char *context = testString;
const char *token = strtok_s(testString, ", ", &context);
while (token) {
token = strtok_s(NULL, ", ", &context);
printf(" %s\n", token);
}
_getch();
}
那么我有两个问题:
- 我不明白为什么
printf
从第二个字开始打印?
- 接下来我需要做什么来找到单词对,我如何才能访问令牌的字母?
printf
从第二个单词开始打印,因为您永远不会打印第一个标记,即您在进入循环之前从初始调用 strtok_s
获得的标记。
- Token 是一个普通的 C 字符串。它的首字母是
token[0]
,一个char
。您可以将其存储在单独的 char
变量中,并将其带入循环的下一次迭代。
- 由于单词可能是大小写混合的,因此在存储和比较初始字符时,您可能应该使用
toupper
或 tolower
。
您提取了此语句中的第一个单词
const char *token = strtok_s(testString, ", ", &context);
但是你没有打印出来。在循环中调用 strtok_s 之后,您开始在 while 循环中打印单词。
您需要两个指向相邻提取字符串的指针,并使用这些指针可以比较字符串的首字母。
这是一个演示程序(为简单起见,我使用 strtok 而不是 strtok_s)
#include <stdio.h>
#include <string.h>
int main(void)
{
char testString[] = "In the end, we will remember not the words "
"of our enemies, but the silence of our friends";
char *first_word = NULL;
char *second_word = NULL;
const char *delim = ", ";
if ( ( first_word = strtok( testString, delim ) ) != NULL )
{
while ( ( second_word = strtok( NULL, delim ) ) != NULL &&
*first_word != *second_word )
{
first_word = second_word;
}
}
if ( second_word != NULL )
{
printf( "%s <-> %s\n", first_word, second_word );
}
return 0;
}
程序输出为
we <-> will
如果你想输出所有这样的词对,那么程序可以看下面的方式
#include <stdio.h>
#include <string.h>
int main(void)
{
char testString[] = "In the end, we will remember not the words "
"of our enemies, but the silence of our friends";
char *first_word = NULL;
char *second_word = NULL;
const char *delim = ", ";
if ( ( first_word = strtok( testString, delim ) ) != NULL )
{
while ( ( second_word = strtok( NULL, delim ) ) != NULL )
{
if ( *first_word == *second_word )
{
printf( "%s <-> %s\n", first_word, second_word );
}
first_word = second_word;
}
}
return 0;
}
程序输出为
we <-> will
of <-> our
of <-> our
然而,与其使用 strtok
或 strtok_s
,不如使用基于函数 strspn
和 strcspn
的方法要好得多。在这种情况下,您可以处理常量字符串。
你想找到两个具有相同首字符的连续标记,对吗?
所以你需要在检索下一个令牌时存储上一个令牌,以便你可以比较它们的初始字符并可能打印它们。
已编辑: 您对 strtok_s
的使用似乎不正确。我修复了下面代码中的错误 并且 将 strtok_s
的错误使用替换为 strtok
.
的正确使用
#include <string.h>
#include <stdio.h>
int main(void) {
char testString[] = "In the end, we will remember not the words of our enemies, but the silence of our friends";
const char *token_prev = strtok(testString, ", ");
const char *token_next = strtok(NULL, ", ");
while (token_next) {
if (token_next[0] == token_prev[0]) {
printf(" %s %s\n", token_prev, token_next);
// break; // to print the first pair only
}
token_prev = token_next;
token_next = strtok(NULL, ", ");
}
}
查看它在 GodBolt 的工作情况:https://godbolt.org/z/YzjcPKrq6
这将遍历整个输入字符串并打印找到的所有对。如果您在 if()
下的 printf()
之后添加 break;
,那么它将仅打印第一对。
我正在解决这个作业问题:在文本中找到一对相邻的单词,使得两个单词都以同一个字母开头。
我知道我需要使用strtok
功能来解决这个问题。
#include <string.h>
#include <stdio.h>
#include <conio.h>
int main(void) {
char testString[] = "In the end, we will remember not the words of our enemies, but the silence of our friends";
char *context = testString;
const char *token = strtok_s(testString, ", ", &context);
while (token) {
token = strtok_s(NULL, ", ", &context);
printf(" %s\n", token);
}
_getch();
}
那么我有两个问题:
- 我不明白为什么
printf
从第二个字开始打印? - 接下来我需要做什么来找到单词对,我如何才能访问令牌的字母?
printf
从第二个单词开始打印,因为您永远不会打印第一个标记,即您在进入循环之前从初始调用strtok_s
获得的标记。- Token 是一个普通的 C 字符串。它的首字母是
token[0]
,一个char
。您可以将其存储在单独的char
变量中,并将其带入循环的下一次迭代。 - 由于单词可能是大小写混合的,因此在存储和比较初始字符时,您可能应该使用
toupper
或tolower
。
您提取了此语句中的第一个单词
const char *token = strtok_s(testString, ", ", &context);
但是你没有打印出来。在循环中调用 strtok_s 之后,您开始在 while 循环中打印单词。
您需要两个指向相邻提取字符串的指针,并使用这些指针可以比较字符串的首字母。
这是一个演示程序(为简单起见,我使用 strtok 而不是 strtok_s)
#include <stdio.h>
#include <string.h>
int main(void)
{
char testString[] = "In the end, we will remember not the words "
"of our enemies, but the silence of our friends";
char *first_word = NULL;
char *second_word = NULL;
const char *delim = ", ";
if ( ( first_word = strtok( testString, delim ) ) != NULL )
{
while ( ( second_word = strtok( NULL, delim ) ) != NULL &&
*first_word != *second_word )
{
first_word = second_word;
}
}
if ( second_word != NULL )
{
printf( "%s <-> %s\n", first_word, second_word );
}
return 0;
}
程序输出为
we <-> will
如果你想输出所有这样的词对,那么程序可以看下面的方式
#include <stdio.h>
#include <string.h>
int main(void)
{
char testString[] = "In the end, we will remember not the words "
"of our enemies, but the silence of our friends";
char *first_word = NULL;
char *second_word = NULL;
const char *delim = ", ";
if ( ( first_word = strtok( testString, delim ) ) != NULL )
{
while ( ( second_word = strtok( NULL, delim ) ) != NULL )
{
if ( *first_word == *second_word )
{
printf( "%s <-> %s\n", first_word, second_word );
}
first_word = second_word;
}
}
return 0;
}
程序输出为
we <-> will
of <-> our
of <-> our
然而,与其使用 strtok
或 strtok_s
,不如使用基于函数 strspn
和 strcspn
的方法要好得多。在这种情况下,您可以处理常量字符串。
你想找到两个具有相同首字符的连续标记,对吗?
所以你需要在检索下一个令牌时存储上一个令牌,以便你可以比较它们的初始字符并可能打印它们。
已编辑: 您对 strtok_s
的使用似乎不正确。我修复了下面代码中的错误 并且 将 strtok_s
的错误使用替换为 strtok
.
#include <string.h>
#include <stdio.h>
int main(void) {
char testString[] = "In the end, we will remember not the words of our enemies, but the silence of our friends";
const char *token_prev = strtok(testString, ", ");
const char *token_next = strtok(NULL, ", ");
while (token_next) {
if (token_next[0] == token_prev[0]) {
printf(" %s %s\n", token_prev, token_next);
// break; // to print the first pair only
}
token_prev = token_next;
token_next = strtok(NULL, ", ");
}
}
查看它在 GodBolt 的工作情况:https://godbolt.org/z/YzjcPKrq6
这将遍历整个输入字符串并打印找到的所有对。如果您在 if()
下的 printf()
之后添加 break;
,那么它将仅打印第一对。