2010-04-12 245 views
3

我需要編寫一個程序,該程序以兩個字符串作爲參數,並檢查第二個字符串是否是第一個字符串的子字符串。我需要這樣做,而不使用任何特殊的庫函數。我創建了這個實現,但是我認爲只要兩個字符串中有一個字母是相同的,就總是返回true。你能幫我在這裏嗎?我不知道我在做什麼錯:C - 檢查字符串是否是另一個字符串的子字符串

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

int my_strstr(char const *s, char const *sub) { 
    char const *ret = sub; 

    int r = 0; 
    while (ret = strchr(ret, *sub)) { 
     if (strcmp(++ret, sub+1) == 0){ 
      r = 1; 
     } 
     else{ 
      r = 0; 
     }   
    } 
    return r; 
} 

int main(int argc, char **argv){ 

    if (argc != 3) { 
     printf ("Usage: check <string one> <string two>\n"); 
    } 
    int result = my_strstr(argv[1], argv[2]); 

    if(result == 1){ 
     printf("%s is a substring of %s\n", argv[2], argv[1]); 
    } else{ 
     printf("%s is not a substring of %s\n", argv[2], argv[1]); 
    } 
    return 0; 
} 
+4

如果您「需要不使用任何特殊的庫函數」,那麼您不應該使用strchr和strcmp。其實strcmp是你的問題無論如何。 – stmax 2010-04-12 18:50:19

+0

@stmax:這些只是_ordinary_庫函數。沒有什麼特別的:) – 2010-04-12 18:54:47

+0

@Daniel:如果'strchr()'和'strcmp()'是普通的,那麼'strstr()'... – 2010-04-12 21:03:40

回答

1

嘛,你不應該在my_strstr修改ret。並且strcmp不比較子字符串,它比較字符串。您可能想要使用strncmp

0

看起來你是在字符*子尋找字符*子:

int my_strstr(char const *s, char const *sub) { 
char const *ret = sub; 

你不應該被設定RET送?

此外strcmp比較字符串,而不是子字符串,因此strcmp(「abcde」,「abc」)返回false。你可能需要strncmp,它也需要一個指定長度的整數。

3

您的寫作方法strstr存在根本性缺陷。讓我們來看看你寫的:

所有的
char const *ret = sub; 

int r = 0; 
while (ret = strchr(ret, *sub)) { 
    if (strcmp(++ret, sub+1) == 0){ 
     r = 1; 
    } 
    else{ 
     r = 0; 
    }   
} 
return r; 

首先,既然你初始化ret指向sub,你是比較sub對自己,從不看s。但是讓我們假設你意味着ret初始化爲s ...

ret = strchr(ret, *sub)發現的sub下一個字符的位置內ret,然後前進ret,使其開始在該字符。

然後,執行strcmp(++ret, sub+1),它確定是否從ret的下一個字符開始的字符串等於從sub的下一個字符開始的字符串,然後前進ret開始與下一個字符(不管是否在測試是真的還是假的)。

很明顯,這個邏輯沒有做你想做的。它實際上要做的是確定子字符串是否等於字符串s,或者在字符串s末尾處找到,並且不包含重複的字母。

這裏有你想要的算法的大致輪廓:

  1. 查找ssub的第一個字符的位置。如果找不到,則返回false。
  2. 更新s,使得它開始在該位置
  3. 假設sub長度n,測試,如果s匹配sub(小心,不要運行過去的s的端部)的第一n字符。如果是這樣,則返回true。否則,請將s提前一個字符並循環。

請注意,除第一個以外,您不應該搜索sub中的任何字符。這個想法是使用sub的第一個字符來找到潛在的sub的起始位置s,然後檢查子字符串sub是否確實存在。如果它不在那裏,你希望放棄s到目前爲止,然後通過嘗試找到下一個潛在的起始位置重新開始。

0

當第一次遇到

ret = strchr(ret, *sub) 

ret == sub。所以,strchr(ret, *sub)正在搜索ret的第一個字符的第一個出現在ret。這將返回ret。因此,ret保持不變。

接下來,

strcmp(++ret, sub+1) == 0 

ret仍然等於sub,所以上面的語句是

而你得到1作爲回報。

0

這可能有助於將此任務向下分開。這個任務有兩個關鍵部分:1)找到可能的子字符串匹配的起始點,2)測試該起始點是否確實是匹配的子字符串。因此,將這作爲兩個功能來實現。

首先,創建一個函數,確定兩個字符串是否完全相似。這應該比較容易編碼,只需比較第一個字母與第一個字母,第二個與第二個等等。如果發現兩個不匹配,則返回false。如果您將其放到其中一個字符串的末尾,請返回true。如果允許使用strncmp,那麼這將僅僅是(strncmp(a, b, strlen(b)) == 0)(假設b始終是較短的字符串)。

其次,創建一個循環查找某個字符串的函數。每當它找到該字母時,它就會調用一個函數並將一個指針傳遞給該字符串中的那個字母。換句話說,如果您調用my_function("This is a sample string", 's'),那麼函數應該遍歷字符串,找到字母's'的所有四個實例,並使用指向字符串中該字母的指針調用函數。在這種情況下,您要調用的函數是前一段中描述的函數。

使用此細分,只要對子函數的任何調用返回「true」,就會返回「true」,否則,如果將其輸入到輸入字符串的末尾,您將返回「false」。

0
char const *ret = sub; 

int r = 0; 
while (ret = strchr(ret, *sub)) { 

RET被存儲在 子陣列的地址和while語句strchr(ret,*sub)sub存儲在ret 這是否會工作或沒有地址比較值(這個比較正確與否) 答案請人...

相關問題