Finding substrings in c(问题 8.16 来自 C how to program)

Finding substrings in c(Question 8.16 from C how to program)

我正在尝试实现 C 如何编程中的问题 8.16。问题如下:

(Searching for Substrings) Write a program that inputs a line of text and a search string from the keyboard. Using function strstr, locate the first occurrence of the search string in the line of text, and assign the location to variable searchPtr of type char *. If the search string is found, print the remainder of the line of text beginning with the search string. Then, use strstr again to locate the next occurrence of the search string in the line of text. If a second occurrence is found, print the remainder of the line of text beginning with the second occurrence. [Hint: The second call to strstr should contain searchPtr + 1 as its first argument.].

这是我的代码:

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

#define SIZE 128

int main(void){
    char s[SIZE], search_string[SIZE];
    char *searchPtr;
    fgets(s, SIZE, stdin);
    fgets(search_string, SIZE, stdin);
    
    searchPtr = strstr(s, search_string);
    //printf("%s", searchPtr);

    if(searchPtr){
        printf("%s%s\n", "The text line beginning with the first occurrence of: ", search_string);
        searchPtr = strstr(searchPtr+1, search_string);
        if(searchPtr){
            printf("%s%s\n","The text line beginning with the second occurrence of: ", search_string);  
        } else{
            printf("%s", "The string to be searched just appeared once.\n"); 
        }
    } else {
        printf("Search string is not found in the string.");
    }
}

这是我对字符串 s 的输入:

hello world world

这是我对 search_string 的输入:

world

这是我的输出

The text line beginning with the first occurrence of: world The string to be searched just appeared once.

但输出应该是

The text line beginning with the first occurrence of: world

The text line beginning with the first occurrence of: world

完成fgets后,我们必须去掉换行符(\n)。

否则,search_string 会将其放在末尾并且搜索将失败 [除非该字符串出现在要搜索的字符串的 结尾 ]。

line/buffer 中 [最多] 两个匹配项的代码是“固定”的。这可以概括为使用循环计算任意数量的匹配项。

这需要将searchPtr初始化为s并传递给strstr


请注意,原始代码将 searchPtr 递增 1 以查找后续匹配项。

这比增加 search_string 的长度

但是,如果(例如)要搜索的字符串是:

,则按字符串长度递增会产生不同的结果
aa

并且,要在其中搜索的字符串是(例如):

aaaaaa
  1. 增加字符串长度将产生 3 个匹配项。
  2. 增加一个字符将产生 5 个匹配项。

这是重构后的代码。

我添加了代码以允许 多个 搜索字符串和要搜索的行。它们之间用空行分隔。

我已经注释了它:

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

#define SIZE        1000

// dosearch -- perform a single search
// RETURNS: 1=more to do, 0=EOF
int
dosearch(void)
{
    char s[SIZE];
    char search_string[SIZE];
    char *searchPtr;
    int match;
    int moreflg;

    do {
        // get search string -- stop on EOF
        moreflg = (fgets(search_string, SIZE, stdin) != NULL);
        if (! moreflg)
            break;

        // strip newline and get string length
        size_t len = strcspn(search_string,"\n");
        search_string[len] = 0;

        // show the [small] string we wish to search for
        printf("\n");
        printf("String to search for is: %s\n",search_string);

        // skipping by one char is slow -- we could skip by the length
        // of the search string but this would work differently with:
        //   search string: aa
        //   buffer: aaaaaa
        // skipping by string length would produce 3 matches
        // skipping by one char would produce 5 matches
        // so, better to use 1
#if 1
        len = 1;
#endif

        while (1) {
            // get line to search -- stop on EOF
            moreflg = (fgets(s, SIZE, stdin) != NULL);
            if (! moreflg)
                break;

            // strip newline
            s[strcspn(s,"\n")] = 0;

            // blank line means start new search -- caller will loop for us
            if (s[0] == 0)
                break;

            printf("String to search within is: %s\n",s);

            match = 0;

            // point to start of line buffer
            searchPtr = s;

            while (1) {
                // search for next occurence of string
                searchPtr = strstr(searchPtr,search_string);
                if (searchPtr == NULL)
                    break;

                // increase the number of matches
                ++match;

                printf("Match #%d found at: %s\n",match,searchPtr);

                // skip over the match we just made
                searchPtr += len;
            }

            printf("A match occurred %d times\n",match);
        }
    } while (0);

    return moreflg;
}

int
main(void)
{

    while (1) {
        if (! dosearch())
            break;
    }
}

这是一些示例输入数据:

world
hello world world
world is not enough
world

quick
the quick brown fox jumped over lazy dogs quickly

aa
aaaaaa

程序输出如下:


String to search for is: world
String to search within is: hello world world
Match #1 found at: world world
Match #2 found at: world
A match occurred 2 times
String to search within is: world is not enough
Match #1 found at: world is not enough
A match occurred 1 times
String to search within is: world
Match #1 found at: world
A match occurred 1 times

String to search for is: quick
String to search within is: the quick brown fox jumped over lazy dogs quickly
Match #1 found at: quick brown fox jumped over lazy dogs quickly
Match #2 found at: quickly
A match occurred 2 times

String to search for is: aa
String to search within is: aaaaaa
Match #1 found at: aaaaaa
Match #2 found at: aaaaa
Match #3 found at: aaaa
Match #4 found at: aaa
Match #5 found at: aa
A match occurred 5 times