簡體   English   中英

strstr()的字符串問題

[英]string issue with strstr()

我需要計算一個較小的字符串在strstr()的較大字符串中的次數,並且我知道當使用strstr()時它會將指針放在較大字符串中找到較小字符串的位置。 但是我不知道我應該寫什么樣的循環來檢查這個較大的字符串在這個較大的字符串中出現多少次? 所以在這種情況下,正確的答案是3。

我的代碼:

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

int count_substr(const char *str, const char *sub) {
    int i = 0;
    int res;
    res = strstr(str, sub);
    if (res) {
        i++;
    }
    else {
        i = i;
    }
    return i;

}
int main(void) {
    char lol[] = "one two one twotwo three";
    char asd[] = "two";
    int ret;
    ret = count_substr(lol, asd);
    printf("%d", ret);


}

您可以像這樣使用while循環:

int count_substr(const char *str, const char *sub) {
    int cnt = 0;
    char *found;

    while(found = strstr(str, sub))
    {
        cnt++;
        str = found + 1;
    }

    return cnt;
}

有趣的是這個:

str = found + 1;

因為你對找到的子字符串之前的字符不感興趣,你可以放心地忽略它們並將str推進到找到的子字符串之后的下一個字符。 strstr最終將在沒有找到子字符串時返回NULL ,或者在str[0] == 0到達字符串結尾后返回NULL

編輯

我把它放在答案中,因為評論部分遠遠限制了更長的評論。

found了一個指向char的指針。 它是指向單個char對象還是指向字節序列的開頭或字符串的開頭,取決於上下文。 這里的上下文是found了函數strstr的返回值。

男人strstr

 #include <string.h> char *strstr(const char *haystack, const char *needle); 

描述

strstr()函數在字符串haystack查找第一次出現的子串needle 不比較終止空字節( '\\0' )。

返回值

[此函數返回]指向所定位子字符串開頭的指針,如果未找到子字符串,則返回NULL

成功時, strstr返回指向找到子字符串的源位置的指針。 所以found將返回指向"two one twotwo three"的指針。

found + 1是指針算術,它與執行&(found[1]) ,它將返回指向序列中下一個char的指針。 found + 1將指向"wo one twotwo three"並將此指針指定給str ,以便str指向找到的子字符串后面的下一個字符。

如果我不這樣做,我會創建一個無限循環,因為strstr將一遍又一遍地返回相同的子字符串。

因此,下次執行strstr(str, sub)found將指向"twotwo three" ,並且found + 1將返回指向"wotwo three"的指針,依此類推。

如果找不到子字符串,它將返回NULL ,循環結束。 此時, found也指向NULL並不重要。

函數strstr()返回一個char指針,而不是一個int ,因此要賦予其返回值的變量應該是char *類型。 您可以使用此值循環一個字符串並查找其中的子字符串數量; 一個while循環就足夠了:

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

int count_substr(const char *str, const char *sub)
{
    int i = 0;
    size_t sub_len = strlen(sub);
    const char *res = strstr(str, sub);
    while (res)
    {
        i++;
        str = res + sub_len;
        res = strstr(str, sub);
    }
    return i;
}

int main(void) 
{
    char lol[] = "one two one twotwo three";
    char asd[] = "two";
    int ret = count_substr(lol, asd);
    printf("ret: %d\n", ret);
    return 0;
}
res = strstr(str, sub);

變量res應聲明為char *res; 而不是int res; 因為函數: strstr()返回一個char*而不是一個int 此錯誤導致編譯器輸出警告消息。 您應該在發布問題之前看到該警告並進行了更正。

這是什么:

i = i;

應該完成?

以下提議的代碼:

  1. 記錄為什么要包含每個頭文件
  2. 正確計算字符串中包含子字符串的次數,包括任何重疊的子字符串。
  3. 適當地包括縮進,水平間距,垂直間距等,以便於閱讀和理解
  4. 使用有意義的變量名

現在,建議的代碼:

#include <stdio.h>   // printf()
#include <string.h>  // strstr()

// prototypes
int count_substr( const char *str, const char *sub );


int main(void)
{
    char lol[] = "one two one twotwo three";
    char asd[] = "two";

    int ret = count_substr( lol, asd );
    printf( "%d\n", ret );   // '\n' so immediately displayed on terminal
}


int count_substr( const char *str, const char *sub )
{
    int count = 0;
    int index = 0;
    char *oldres = NULL;
    char *newres = NULL;

    do
    {
        newres = strstr( &str[index], sub );
        index++;

        if( newres != oldres && newres )
            count++;

        oldres = newres;
    } while( oldres );

    return count;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM