Überprüfen Sie, ob in einer Zeichenfolge in C Teilzeichenfolgen vorhanden sind

169

Ich versuche zu überprüfen, ob eine Zeichenfolge eine Teilzeichenfolge in C enthält, wie:

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

Was kann anstelle von string::findC ++ verwendet werden?

keiner
quelle
7
Sie möchten: char * strstr (const char * s1, const char * s2) - Lokalisiert das erste Vorkommen des Strings s2 in String s1.
JonH
@ JonH Ich dachte, das funktioniert nur für Zeichen. Ich werde eine der Antworten unten akzeptieren, danke ..
keine
Sie verwechseln das mit strchr.
JonH
@ JonH ahh richtig, es macht jetzt Sinn. du bist großartig, nochmals
keine

Antworten:

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

Beachten Sie, dass strstrein Zeiger auf den Wortanfang in zurückgegeben wird, sentwenn das Wort wordgefunden wird.

nneonneo
quelle
1
Sie können auch das "! = NULL" entfernen, ich denke, strstr gibt 0 oder 1 zurück
Simon MILHAU
44
strstrgibt einen Zeiger zurück; Ich mag es explizit zu sein, wenn ich auf Zeiger teste.
Nneonneo
3
... und falseist0
Jack
8
Kommentar für meine zukünftige Referenz; strcasestrmacht das Gleiche, ignoriert aber den Fall.
Amonett
2
@NgoThanhNhan Sie können die Implementierung von strstrin glibc hier sehen: github.com/lattera/glibc/blob/master/string/strstr.c . Es ist viel optimierter als eine naive Implementierung - und wahrscheinlich schneller als eine einfache selbst definierte Funktion. Trotzdem im Zweifelsfall Benchmark.
Nneonneo
12

Versuchen Sie, Zeiger zu verwenden ...

#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);
}
Nur virtuell
quelle
8

Sie können dies versuchen, um das Vorhandensein des Teilstrings zu ermitteln und ihn zu extrahieren und zu drucken:

#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;
}
Jeevan
quelle
Der Test if(strcmp((ret=strstr(mainstring,substring)),substring))ist falsch: Er stimmt nur überein, substringwenn es sich um ein Suffix von handelt mainstring. Der Rest der Funktion ist eine verschlungene Schreibweise printf("and the sub string is:::%s\n", substring);.
Chqrlie
5

Dieser Code implementiert die Logik, wie die Suche funktioniert (eine der Möglichkeiten), ohne eine vorgefertigte Funktion zu verwenden:

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
quelle
Während dieser Code die Frage möglicherweise beantwortet, verbessert die Bereitstellung eines zusätzlichen Kontexts darüber, warum und / oder wie dieser Code die Frage beantwortet, ihren langfristigen Wert.
JAL
3

Und so melden Sie die Position des ersten Zeichens von der gefundenen Teilzeichenfolge:

Ersetzen Sie diese Zeile im obigen Code:

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

mit:

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

Meine eigene bescheidene (Groß- und Kleinschreibung beachtende) Lösung:

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;
}

Ergebnisse

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

Getestet auf ATmega328P (avr8-gnu-toolchain-3.5.4.1709);)

Damian K.
quelle
1

Dasselbe wird mit diesem einfacheren Code erreicht: Warum diese verwenden:

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;
}

Der schwierige Teil wäre jedoch zu melden, an welcher Position in der ursprünglichen Zeichenfolge der Teilstring beginnt ...

derlo
quelle
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
quelle
1

Ich glaube, dass ich die einfachste Antwort habe. Sie benötigen weder die Bibliothek string.h in diesem Programm noch die Bibliothek stdbool.h. Die einfache Verwendung von Zeigern und Zeigerarithmetik hilft Ihnen, ein besserer C-Programmierer zu werden.

Geben Sie einfach 0 für False (kein Teilstring gefunden) oder 1 für True (ja, ein Teilstring "sub" befindet sich in der Gesamtzeichenfolge "str") zurück:

#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;
}
user9679882
quelle
1
Was ist mit Pufferüberlauf?
Cacahuete Frito
Wie würde hier ein Pufferüberlauf auftreten?
user9679882
Zu Beginn kennen Sie die Größe des Puffers nicht. Stellen Sie sich diesen 'einfachen' Code vor: char a[3] = "asd"; char b[2] = "as"; is_substr(a, b);Eingabezeichenfolgen sind nicht NUL-terminiert, sodass Sie das Array überlaufen.
Cacahuete Frito
Wenn einer der Puffer die Größe 0 hat (Arrays der Größe 0 existieren nicht, aber dies ist möglich und auch aus Sicht des Benutzers der Funktion char a[4] = "asd"; char b[3]= "as"; is_substr(a+4, b);
legal
Und das ist der Grund strnstr(), warum es existiert (zumindest auf libbsd)
Cacahuete Frito
1

Verwenden von C - Keine integrierten Funktionen

string_contains () erledigt das ganze schwere Heben und gibt 1 basierten Index zurück. Rest sind Fahrer- und Helfercodes.

Weisen Sie der Hauptzeichenfolge und dem Teilstring einen Zeiger zu, erhöhen Sie den Teilstringzeiger beim Abgleich und beenden Sie die Schleife, wenn der Teilstringzeiger der Teilstringlänge entspricht.

read_line () - Ein kleiner Bonuscode zum Lesen der Benutzereingaben, ohne die Größe der Eingabe festzulegen, die der Benutzer bereitstellen sollte.

#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
quelle
-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
quelle