Periksa substring ada dalam string di C

169

Saya mencoba memeriksa apakah string berisi substring dalam C seperti:

char *sent = "this is my sample example";
char *word = "sample";
if (/* sentence contains word */) {
    /* .. */
}

Apa itu sesuatu untuk digunakan, bukan string::finddi C ++?

tidak ada
sumber
7
Anda ingin: char * strstr (const char * s1, const char * s2) - menempatkan kemunculan pertama dari string s2 dalam string s1.
JonH
@ Jon Saya pikir itu hanya berfungsi untuk karakter. Saya akan menerima salah satu jawaban di bawah ini, terima kasih ..
tidak ada
Anda mencampurnya dengan strchr.
JonH
@ JonH ahh benar, masuk akal sekarang. Anda hebat, terima kasih lagi ..
tidak ada

Jawaban:

272
if(strstr(sent, word) != NULL) {
    /* ... */
}

Perhatikan bahwa strstrmengembalikan penunjuk ke awal kata sentjika kata worditu ditemukan.

nneonneo
sumber
1
Anda juga dapat menghapus "! = NULL", saya pikir strstr mengembalikan 0 atau 1
Simon MILHAU
44
strstrmengembalikan pointer; Saya suka menjadi eksplisit ketika saya menguji pointer.
nneonneo
3
... dan falseini0
Jack
8
Komentar untuk referensi saya di masa depan; strcasestrmelakukan hal yang sama tetapi mengabaikan kasus.
amonett
2
@NgoThanhNhan Anda dapat melihat implementasi strstrdi glibc di sini: github.com/lattera/glibc/blob/master/string/strstr.c . Ini jauh lebih dioptimalkan daripada implementasi naif - dan mungkin lebih cepat daripada fungsi mandiri yang jelas. Kendati demikian, saat ragu, patokan.
nneonneo
12

Coba gunakan pointer ...

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

int main()
{

  char str[] = "String1 subString1 Strinstrnd subStr ing1subString";
  char sub[] = "subString";

  char *p1, *p2, *p3;
  int i=0,j=0,flag=0;

  p1 = str;
  p2 = sub;

  for(i = 0; i<strlen(str); i++)
  {
    if(*p1 == *p2)
      {
          p3 = p1;
          for(j = 0;j<strlen(sub);j++)
          {
            if(*p3 == *p2)
            {
              p3++;p2++;
            } 
            else
              break;
          }
          p2 = sub;
          if(j == strlen(sub))
          {
             flag = 1;
            printf("\nSubstring found at index : %d\n",i);
          }
      }
    p1++; 
  }
  if(flag==0)
  {
       printf("Substring NOT found");
  }
return (0);
}
Biasanya
sumber
8

Anda dapat mencoba yang ini untuk menemukan keberadaan substring dan untuk mengekstrak dan mencetaknya:

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

int main(void)
{
    char mainstring[]="The quick brown fox jumps over the lazy dog";
    char substring[20], *ret;
    int i=0;
    puts("enter the sub string to find");
    fgets(substring, sizeof(substring), stdin);
    substring[strlen(substring)-1]='\0';
    ret=strstr(mainstring,substring);
    if(strcmp((ret=strstr(mainstring,substring)),substring))
    {
        printf("substring is present\t");
    }
    printf("and the sub string is:::");

    for(i=0;i<strlen(substring);i++)
    {
            printf("%c",*(ret+i));

    }
    puts("\n");
    return 0;
}
Astaga
sumber
Tes if(strcmp((ret=strstr(mainstring,substring)),substring))ini salah: hanya cocok substringjika sufiks mainstring. Sisa fungsi adalah cara berbelit-belit untuk menulis printf("and the sub string is:::%s\n", substring);.
chqrlie
5

Kode ini mengimplementasikan logika bagaimana pencarian bekerja (salah satu cara) tanpa menggunakan fungsi yang sudah jadi:

public int findSubString(char[] original, char[] searchString)
{
    int returnCode = 0; //0-not found, -1 -error in imput, 1-found
    int counter = 0;
    int ctr = 0;
    if (original.Length < 1 || (original.Length)<searchString.Length || searchString.Length<1)
    {
        returnCode = -1;
    }

    while (ctr <= (original.Length - searchString.Length) && searchString.Length > 0)
    {
        if ((original[ctr]) == searchString[0])
        {
            counter = 0;
            for (int count = ctr; count < (ctr + searchString.Length); count++)
            {
                if (original[count] == searchString[counter])
                {
                    counter++;
                }
                else
                {
                    counter = 0;
                    break;
                }
            }
            if (counter == (searchString.Length))
            {
                returnCode = 1;
            }
        }
        ctr++;
    }
    return returnCode;
}
Ashok Mazumder
sumber
Sementara kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang mengapa dan / atau bagaimana kode ini menjawab pertanyaan meningkatkan nilai jangka panjangnya.
JAL
3

Dan berikut ini cara melaporkan posisi karakter pertama dari substring yang ditemukan:

Ganti baris ini dalam kode di atas:

printf("%s",substring,"\n");

dengan:

printf("substring %s was found at position %d \n", substring,((int) (substring - mainstring)));
derlo
sumber
3

Solusi saya yang rendah hati (peka huruf besar kecil):

uint8_t strContains(char* string, char* toFind)
{
    uint8_t slen = strlen(string);
    uint8_t tFlen = strlen(toFind);
    uint8_t found = 0;

    if( slen >= tFlen )
    {
        for(uint8_t s=0, t=0; s<slen; s++)
        {
            do{

                if( string[s] == toFind[t] )
                {
                    if( ++found == tFlen ) return 1;
                    s++;
                    t++;
                }
                else { s -= found; found=0; t=0; }

              }while(found);
        }
        return 0;
    }
    else return -1;
}

Hasil

strContains("this is my sample example", "th") // 1
strContains("this is my sample example", "sample") // 1
strContains("this is my sample example", "xam") // 1
strContains("this is my sample example", "ple") // 1
strContains("this is my sample example", "ssample") // 0
strContains("this is my sample example", "samplee") // 0
strContains("this is my sample example", "") // 0
strContains("str", "longer sentence") // -1
strContains("ssssssample", "sample") // 1
strContains("sample", "sample") // 1

Diuji pada ATmega328P (avr8-gnu-toolchain-3.5.4.1709);)

Damian K.
sumber
1

Hal yang sama akan tercapai dengan kode sederhana ini: Mengapa menggunakan ini:

int main(void)
{

    char mainstring[]="The quick brown fox jumps over the lazy dog";
    char substring[20];
    int i=0;
    puts("enter the sub stirng to find");
    fgets(substring, sizeof(substring), stdin);
    substring[strlen(substring)-1]='\0';
    if (strstr(mainstring,substring))
    {
            printf("substring is present\t");
    }
    printf("and the sub string is:::");
    printf("%s",substring,"\n");
   return 0;
}

Tetapi bagian yang sulit adalah untuk melaporkan di mana posisi dalam string asli substring dimulai ...

derlo
sumber
1
My code to find out if substring is exist in string or not 
// input ( first line -->> string , 2nd lin ->>> no. of queries for substring
following n lines -->> string to check if substring or not..

#include <stdio.h>
int len,len1;
int isSubstring(char *s, char *sub,int i,int j)
{

        int ans =0;
         for(;i<len,j<len1;i++,j++)
        {
                if(s[i] != sub[j])
                {
                    ans =1;
                    break;
                }
        }
        if(j == len1 && ans ==0)
        {
            return 1;
        }
        else if(ans==1)
            return 0;
return 0;
}
int main(){
    char s[100001];
    char sub[100001];
    scanf("%s", &s);// Reading input from STDIN
    int no;
    scanf("%d",&no);
    int i ,j;
    i=0;
    j=0;
    int ans =0;
    len = strlen(s);
    while(no--)
    {
        i=0;
        j=0;
        ans=0;
        scanf("%s",&sub);
        len1=strlen(sub);
        int value;
        for(i=0;i<len;i++)
        {
                if(s[i]==sub[j])
                {
                    value = isSubstring(s,sub,i,j);
                    if(value)
                    {
                        printf("Yes\n");
                        ans = 1;
                        break;
                    }
                }
        }
        if(ans==0)
            printf("No\n");

    }
}
Neetesh Singh
sumber
1

Saya percaya bahwa saya memiliki jawaban yang paling sederhana. Anda tidak memerlukan pustaka string.h dalam program ini, atau pustaka stdbool.h. Cukup menggunakan pointer dan pointer aritmatika akan membantu Anda menjadi programmer C yang lebih baik.

Cukup kembalikan 0 untuk False (tidak ada substring yang ditemukan), atau 1 untuk Benar (ya, "sub" substring ditemukan dalam keseluruhan string "str"):

#include <stdlib.h>

int is_substr(char *str, char *sub)
{
  int num_matches = 0;
  int sub_size = 0;
  // If there are as many matches as there are characters in sub, then a substring exists.
  while (*sub != '\0') {
    sub_size++;
    sub++;
  }

  sub = sub - sub_size;  // Reset pointer to original place.
  while (*str != '\0') {
    while (*sub == *str && *sub != '\0') {
      num_matches++;
      sub++;
      str++;
    }
    if (num_matches == sub_size) {
      return 1;
    }
    num_matches = 0;  // Reset counter to 0 whenever a difference is found. 
    str++;
  }
  return 0;
}
pengguna9679882
sumber
1
Bagaimana dengan buffer overrun?
Cacahuete Frito
Bagaimana buffer overflow terjadi di sini?
user9679882
Untuk memulai, Anda tidak tahu ukuran buffer. Bayangkan kode 'sederhana' ini: char a[3] = "asd"; char b[2] = "as"; is_substr(a, b);String input tidak diakhiri dengan NUL, jadi Anda membanjiri array.
Cacahuete Frito
Jika salah satu buffer berukuran 0 (array ukuran 0 tidak ada, tetapi ini mungkin, dan juga legal dari sudut pandang pengguna fungsi):char a[4] = "asd"; char b[3]= "as"; is_substr(a+4, b);
Cacahuete Frito
Dan itulah alasannya strnstr()ada (setidaknya di libbsd)
Cacahuete Frito
1

Menggunakan C - Tidak ada fungsi bawaan

string_contains () melakukan semua pengangkatan berat dan mengembalikan 1 indeks berbasis. Sisanya adalah kode pengemudi dan penolong.

Tetapkan penunjuk ke string utama dan penunjuk substring, penambah substring saat mencocokkan, berhenti looping ketika penunjuk substring sama dengan panjang substring.

read_line () - Kode bonus kecil untuk membaca input pengguna tanpa menentukan ukuran input yang harus disediakan pengguna.

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

int string_len(char * string){
  int len = 0;
  while(*string!='\0'){
    len++;
    string++;
  }
  return len;
}

int string_contains(char *string, char *substring){
  int start_index = 0;
  int string_index=0, substring_index=0;
  int substring_len =string_len(substring);
  int s_len = string_len(string);
  while(substring_index<substring_len && string_index<s_len){
    if(*(string+string_index)==*(substring+substring_index)){
      substring_index++;
    }
    string_index++;
    if(substring_index==substring_len){
      return string_index-substring_len+1;
    }
  }

  return 0;

}

#define INPUT_BUFFER 64
char *read_line(){
  int buffer_len = INPUT_BUFFER;
  char *input = malloc(buffer_len*sizeof(char));
  int c, count=0;

  while(1){
    c = getchar();

    if(c==EOF||c=='\n'){
      input[count]='\0';
      return input;
    }else{
      input[count]=c;
      count++;
    }

    if(count==buffer_len){
      buffer_len+=INPUT_BUFFER;
      input = realloc(input, buffer_len*sizeof(char));
    }

  }
}

int main(void) {
  while(1){
    printf("\nEnter the string: ");
    char *string = read_line();
    printf("Enter the sub-string: ");
    char *substring = read_line(); 
    int position = string_contains(string,substring);
    if(position){ 
      printf("Found at position: %d\n", position);
    }else{
      printf("Not Found\n");
    }
  }
  return 0;
}
Rakshith Murukannappa
sumber
-1
#include <stdio.h>
#include <string.h>

int findSubstr(char *inpText, char *pattern);
int main()
{
    printf("Hello, World!\n");
    char *Text = "This is my sample program";
    char *pattern = "sample";
    int pos = findSubstr(Text, pattern);
    if (pos > -1) {
        printf("Found the substring at position %d \n", pos);
    }
    else
        printf("No match found \n");

    return 0;
}

int findSubstr(char *inpText, char *pattern) {
    int inplen = strlen(inpText);
    while (inpText != NULL) {

        char *remTxt = inpText;
        char *remPat = pattern;

        if (strlen(remTxt) < strlen(remPat)) {
            /* printf ("length issue remTxt %s \nremPath %s \n", remTxt, remPat); */
            return -1;
        }

        while (*remTxt++ == *remPat++) {
            printf("remTxt %s \nremPath %s \n", remTxt, remPat);
            if (*remPat == '\0') {
                printf ("match found \n");
                return inplen - strlen(inpText+1);
            }
            if (remTxt == NULL) {
                return -1;
            }
        }
        remPat = pattern;

        inpText++;
    }
}
Srijit Nair
sumber