在 C 中的一个句子中查找最后一次出现的字符串
Finding the last occurrence of a string in a sentence in C
我正在练习,遇到了一个练习。练习说我要手动编写一个函数来查找字符串中最后一次出现的索引。现在,我知道以前可能有人问过这个问题,但我找不到我的代码有什么问题。它适用于几乎所有情况,但当 单词的最后一次出现在字符串的开头 .
时则不然
我尝试过的方法:我使用指针来存储我们要查找的句子和单词的 结尾 的地址。然后我使用 while 循环遍历字符串。如果当前字符与我们正在搜索的单词的 last 字符相匹配,我们将进入另一个比较两者的 while 循环。如果指向单词开头的指针和我们用来遍历单词的指针相等,则找到了单词。
这是一些代码:
#include <stdio.h>
int find_last( char *str, char *word)
{
char *p, *q;
char *s, *t;
p=str; /* Pointer p now points to the last character of the sentence*/
while(*p!='[=10=]') p++;
p--;
q = word;
while(*q!='[=10=]') q++; /* Pointer q now points to the last character of the word*/
q--;
while(p != str) {
if(*p == *q) {
s=p; /* if a matching character is found, "s" and "t" are used to iterate through */
/* the string and the word, respectively*/
t=q;
while(*s == *t) {
s--;
t--;
}
if(t == word-1) return s-str+1; /* if pointer "t" is equal by address to pointer word-1, we have found our match. return s-str+1. */
}
p--;
}
return -1;
}
int main()
{
char arr[] = "Today is a great day!";
printf("%d", find_last(arr, "Today"));
return 0;
}
所以,这段代码应该 return 0
但它 returns -1
.
它在我测试的所有其他实例中都有效!当在 CodeBlocks 中 运行 时,输出符合预期 (0
),但是使用任何其他在线 IDE 我发现输出仍然是 -1。
对于初学者,函数的参数应具有限定符 const,其 return 类型应为 size_t
或 ptrdiff_t
。
例如
ptrdiff_t find_last( const char *str, const char *word );
在任何情况下函数的声明至少要像
int find_last( const char *str, const char *word );
该函数应模拟标准 C 函数的行为 strstr
。也就是说,当第二个参数是空字符串时,函数应该 return 0.
如果其中一个参数是空字符串,那么由于这些语句,您的函数具有未定义的行为
p=str; /* Pointer p now points to the last character of the sentence*/
while(*p!='[=12=]') p++;
p--;
^^^^
q = word;
while(*q!='[=12=]') q++; /* Pointer q now points to the last character of the word*/
q--;
^^^^
如果 str
指向的字符串只包含一个符号那么你的函数 returns -1 因为循环的条件
while(p != str) {
计算结果为 false,与两个字符串是否相等无关。
这个循环
while(*s == *t) {
s--;
t--;
}
再次可以调用未定义的行为,因为可以访问字符串字之前的内存。
还有这个声明
if(t == word-1) return s-str+1;
同理也可以调用未定义的行为
函数可以定义如下面的演示程序所示。
#include <stdio.h>
int find_last( const char *str, const char *word )
{
const char *p = str;
int found = !*word;
if ( !found )
{
while ( *p ) ++p;
const char *q = word;
while ( *q ) ++q;
while ( !found && !( p - str < q - word ) )
{
const char *s = p;
const char *t = q;
while ( t != word && *( s - 1 ) == *( t - 1) )
{
--s;
--t;
}
found = t == word;
if ( found ) p = s;
else --p;
}
}
return found ? p - str : -1;
}
int main(void)
{
const char *str = "";
const char *word = "";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
word = "A";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
str = "A";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
str = "ABA";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
str = "ABAB";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
str = "ABCDEF";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
str = "ABCDEF";
word = "BC";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
return 0;
}
程序输出为
find_last( str, word ) == 0
find_last( str, word ) == -1
find_last( str, word ) == 0
find_last( str, word ) == 2
find_last( str, word ) == 2
find_last( str, word ) == 0
find_last( str, word ) == 1
我正在练习,遇到了一个练习。练习说我要手动编写一个函数来查找字符串中最后一次出现的索引。现在,我知道以前可能有人问过这个问题,但我找不到我的代码有什么问题。它适用于几乎所有情况,但当 单词的最后一次出现在字符串的开头 .
时则不然我尝试过的方法:我使用指针来存储我们要查找的句子和单词的 结尾 的地址。然后我使用 while 循环遍历字符串。如果当前字符与我们正在搜索的单词的 last 字符相匹配,我们将进入另一个比较两者的 while 循环。如果指向单词开头的指针和我们用来遍历单词的指针相等,则找到了单词。
这是一些代码:
#include <stdio.h>
int find_last( char *str, char *word)
{
char *p, *q;
char *s, *t;
p=str; /* Pointer p now points to the last character of the sentence*/
while(*p!='[=10=]') p++;
p--;
q = word;
while(*q!='[=10=]') q++; /* Pointer q now points to the last character of the word*/
q--;
while(p != str) {
if(*p == *q) {
s=p; /* if a matching character is found, "s" and "t" are used to iterate through */
/* the string and the word, respectively*/
t=q;
while(*s == *t) {
s--;
t--;
}
if(t == word-1) return s-str+1; /* if pointer "t" is equal by address to pointer word-1, we have found our match. return s-str+1. */
}
p--;
}
return -1;
}
int main()
{
char arr[] = "Today is a great day!";
printf("%d", find_last(arr, "Today"));
return 0;
}
所以,这段代码应该 return 0
但它 returns -1
.
它在我测试的所有其他实例中都有效!当在 CodeBlocks 中 运行 时,输出符合预期 (0
),但是使用任何其他在线 IDE 我发现输出仍然是 -1。
对于初学者,函数的参数应具有限定符 const,其 return 类型应为 size_t
或 ptrdiff_t
。
例如
ptrdiff_t find_last( const char *str, const char *word );
在任何情况下函数的声明至少要像
int find_last( const char *str, const char *word );
该函数应模拟标准 C 函数的行为 strstr
。也就是说,当第二个参数是空字符串时,函数应该 return 0.
如果其中一个参数是空字符串,那么由于这些语句,您的函数具有未定义的行为
p=str; /* Pointer p now points to the last character of the sentence*/
while(*p!='[=12=]') p++;
p--;
^^^^
q = word;
while(*q!='[=12=]') q++; /* Pointer q now points to the last character of the word*/
q--;
^^^^
如果 str
指向的字符串只包含一个符号那么你的函数 returns -1 因为循环的条件
while(p != str) {
计算结果为 false,与两个字符串是否相等无关。
这个循环
while(*s == *t) {
s--;
t--;
}
再次可以调用未定义的行为,因为可以访问字符串字之前的内存。
还有这个声明
if(t == word-1) return s-str+1;
同理也可以调用未定义的行为
函数可以定义如下面的演示程序所示。
#include <stdio.h>
int find_last( const char *str, const char *word )
{
const char *p = str;
int found = !*word;
if ( !found )
{
while ( *p ) ++p;
const char *q = word;
while ( *q ) ++q;
while ( !found && !( p - str < q - word ) )
{
const char *s = p;
const char *t = q;
while ( t != word && *( s - 1 ) == *( t - 1) )
{
--s;
--t;
}
found = t == word;
if ( found ) p = s;
else --p;
}
}
return found ? p - str : -1;
}
int main(void)
{
const char *str = "";
const char *word = "";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
word = "A";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
str = "A";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
str = "ABA";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
str = "ABAB";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
str = "ABCDEF";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
str = "ABCDEF";
word = "BC";
printf( "find_last( str, word ) == %d\n", find_last( str, word ) );
return 0;
}
程序输出为
find_last( str, word ) == 0
find_last( str, word ) == -1
find_last( str, word ) == 0
find_last( str, word ) == 2
find_last( str, word ) == 2
find_last( str, word ) == 0
find_last( str, word ) == 1