在C语言中查找字符串中最后一次出现的字符串 [英] Finding the last occurrence of a string in a sentence in C

查看:1590
本文介绍了在C语言中查找字符串中最后一次出现的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在练习,并且遇到了一种锻炼。练习说我要手动编写一个函数,该函数可以找到字符串中最后一次出现的索引。现在,我可能已经有人问过这个问题,但是我找不到我的代码有什么问题。它适用于几乎所有情况,但是当单词的最后一次出现在字符串的开头时不是这样。

I am practicing and I came across an exercise. The exercise says I am to manually write a function that finds the index of the last occurrence in a string. Now, I get that this has maybe been asked before but I cannot find what is the problem with my code. It works for almost all instances, but not so when the last occurrence of the word is at the beginning of the string.

我所拥有的尝试过的:我使用指针来存储我们要查找的句子和单词的 ends 的地址。然后,我使用了while循环来遍历字符串。如果当前字符与我们要搜索的单词的 last 字符匹配,我们将输入另一个while循环来比较这两个字符。如果指向单词开头的指针与我们用于遍历单词的指针相等,则找到单词。

What I have tried: I used pointers to store the addresses of the ends of both the sentence and the word we are looking for. I then used a while loop to iterate through the string. If the current character matches the last character of the word we are searching for, we enter another while loop which compares the two. If the pointer that points to the beginning of the word and the one we used to iterate through the word are equal, the word is found.

这里是一些代码:


#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!='\0') p++;
    p--;

    q = word;
    while(*q!='\0') 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;
}

因此,此代码应返回 0 ,但返回 -1

So, this code should return 0 but it returns -1.

它在我测试过的所有其他实例中都有效!在CodeBlocks中运行时,输出符合预期( 0 ),但是使用任何其他在线IDE,我仍然可以找到输出-1。

It works in every other instance I tested! When ran in CodeBlocks, the output is as expected (0), but using any other online IDE I could find the output is still -1.

推荐答案

对于初学者,函数的参数应具有限定符const,其返回类型应为 size_t ptrdiff_t

For starters the parameters of the function shall have the qualifier const and its return type should be either size_t or ptrdiff_t.

例如

ptrdiff_t find_last( const char *str,  const char *word );

在任何情况下,函数至少应声明为

In any case the function shall be declared at least like

int find_last( const char *str,  const char *word );

该函数应模拟标准C函数的行为 strstr 。也就是说,当第二个参数为空字符串时,该函数应返回0。

The function should emulate the behavior of the standard C function strstr. That is when the second argument is an empty string the function should return 0.

如果其中一个参数为空字符串,则由于这些语句,您的函数具有未定义的行为

If either of the arguments is an empty string then your function has undefined behavior due to these statements

p=str;                            /* Pointer p now points to the last character of the sentence*/
while(*p!='\0') p++;
p--;
^^^^

q = word;
while(*q!='\0') q++;             /* Pointer q now points to the last character of the word*/
q--;
^^^^

如果 str指向的字符串仅包含一个符号,然后您的函数将返回-1,因为循环的条件

If the string pointed to by str contains only one symbol then your function returns -1 because the condition of the loop

while(p != str) {

评估为false,而与两个字符串是否相等无关。

evaluates to false independent on whether the both strings are equal each other or not.

此循环

        while(*s == *t) {
            s--;
            t--;
        }

再次可以调用未定义的行为,因为在

again can invoke undefined behavior because there can be an access to memory that precedes the string word.

这条语句

if(t == word-1) return s-str+1;

也可以出于相同的原因调用未定义的行为。

also can invoke the undefined behavior by the same reason.

可以按下面的演示程序所示定义该函数。

The function can be defined as it is shown in the demonstrative program below.

#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

这篇关于在C语言中查找字符串中最后一次出现的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆