Forum: PC-Programmierung Wie oft kommt string 2 in string1 vor?


von Peter (Gast)


Lesenswert?

Hallo Leute,
ich lerne gerade für eine Klausur und soll zwecks einer Übung 
überprüfen, wie oft string 2 in string 1 vorkommt.
Dazu habe ich folgendes Programm geschrieben:
1
/* 8. Schreiben Sie eine Funktion, die feststellt, wie oft ein String in einem anderen enthalten
2
ist.*/
3
4
#define _CRT_SECURE_NO_WARNINGS
5
#define max 20
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
10
char str1[max] = "adc adc adc";
11
char str2[max] = "adc";
12
char *c;                 //Vergleich zutreffend
13
int cnt, v;
14
char strvgl(char x[], char y[]);
15
16
17
void main(void)
18
{
19
  puts("wie oft kommt str2 in str1 vor?");
20
    strvgl(str1, str2);
21
  printf("str 2 ist %d mal enthalten", v);
22
23
}
24
25
26
char strvgl(char x[], char y[])
27
{
28
  for (cnt = 0;c-str1<20; cnt++)
29
  {
30
    v = x - str1;   // Position der Übereinstimmung
31
    c = strstr(x, y);
32
    printf("%d\n", cnt);
33
34
    
35
  }
36
  return cnt;
37
38
}

Sollte soweit auch richtig sein, bis auf die funktion "strvgl".
so wird der Vergleich zwar mehrmals ausgeführt, aber immer vom Anfang 
des Strings1. Ich müsste String 1 ja um die Posiotion der gefundenen 
stelle verschieben und dann erst einen erneuten vergleich durchführen, 
also str1=stelle-str1.


Wie realisiere ich das in der Funktion? Gibt es einen einfacheren weg?
Ist die Schleifenbedingung der For-Schleife richtig?

MfG

von Peter (Gast)


Lesenswert?

Peter schrieb:
> v = x - str1;

sollte heißen:

v = c-x ;

von Alexander S. (alesi)


Lesenswert?

Peter schrieb:
> char str1[max] = "adc adc adc";

Der Test-String ist ein Spezialfall, evtl. besser so etwas nehmen:

   "abcadcf adcvbnadcc dacadcfg adc adcadc adcadca aadcc"

von Peter (Gast)


Lesenswert?

Alexander S. schrieb:
> Der Test-String ist ein Spezialfall, evtl. besser so etwas nehmen:
>
>    "abcadcf adcvbnadcc dacadcfg adc adcadc adcadca aadcc"

Danke, wurde übernommen :)

von Dirk B. (dirkb2)


Lesenswert?

Deine Funktion strvgl ist ziemlich sinnlos, da sie eigentlich nur mit 
globalen Variablen arbeitet.

Und verzichte auf die Magic Numbers (20 in strvgl)
Der richtige Wert wäre die Stringlänge.

Aber auch den brauchst du nicht.

Werte den Rückgabewert von strstr aus. Daran kannst du erkennen, ob der 
String überhaupt drin vorkommt.

von Peter (Gast)


Lesenswert?

Dirk B. schrieb:
> Deine Funktion strvgl ist ziemlich sinnlos, da sie eigentlich nur mit
> globalen Variablen arbeitet.

so lautet aber die Aufgabe, kann natürlich die globalen variablen, die 
ich nur in der Funktion brauche auch noch in die Funktion verschieben.

Dirk B. schrieb:
> Werte den Rückgabewert von strstr aus. Daran kannst du erkennen, ob der
> String überhaupt drin vorkommt.

Das wäre ja mein v. string 2 kommt an der stelle v in string 1 vor.

von Dirk B. (dirkb2)


Lesenswert?

Peter schrieb:
> Dirk B. schrieb:
>> Deine Funktion strvgl ist ziemlich sinnlos, da sie eigentlich nur mit
>> globalen Variablen arbeitet.
>
> so lautet aber die Aufgabe, kann natürlich die globalen variablen, die
> ich nur in der Funktion brauche auch noch in die Funktion verschieben.

Ach du Scheiße


Ohne Gewähr:
1
size_t strcnt(char *src, char *search)
2
{ size_t cnt = 0;
3
  size_t len = strlen(search);
4
  char *c = src;
5
  
6
  while ((c = strstr(c,search)) != NULL)
7
  { cnt++;
8
    c += len;;
9
  }
10
11
  return cnt;
12
}

von Abradolf Lincler (Gast)


Lesenswert?

Dirk B. schrieb:
> Ohne Gewähr:

Falsch.

src = "aaaaa"
search = "aaa"

von Dirk B. (dirkb2)


Lesenswert?

Abradolf Lincler schrieb:
> Falsch.
>
> src = "aaaaa"
> search = "aaa"

Wenn das so gemeint ist, dann muss len auf 1 gesetzt werden.

von Abradolf Lincler (Gast)


Lesenswert?

Dirk B. schrieb:
> Wenn das so gemeint ist, dann muss len auf 1 gesetzt werden.

Korrekt.

von Peter (Gast)


Lesenswert?

Das funktioniert bei mir leider so nicht.

von Peter (Gast)


Lesenswert?

1
char strvgl(char x[], char y[])
2
{
3
  for (cnt = 1;; cnt++, x[+v])
4
  {
5
    c = strstr(x, y);
6
    v = c - x;
7
    printf("%d position: %d\n", cnt,v);
8
    x[v] = x[v+strlen(y)];
9
    
10
  }
11
  return cnt;
12
}

hiermit findet er zumindest die richtigen Stellen.
Die Schleifenbedingung ist allerdings noch fehlerhaft, da sie zu oft 
durchlaufen wird.

von MaWin (Gast)


Lesenswert?

Peter schrieb:
> Die Schleifenbedingung ist allerdings noch fehlerhaft, da sie zu oft
> durchlaufen wird.

Es ist ja auch eine Endlosschleife.

von Peter (Gast)


Lesenswert?

Ich möchte doch aber wissen, wie oft es vorkommt und dies ausgeben

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
int substrcmp(char* string, char* substring) {
6
 int i;
7
 
8
 for (i=0; i<strlen(substring); i++) 
9
  if (string[i] != substring[i]) return 0;
10
11
 return 1;
12
}
13
14
int strvgl(char* string, char* substring) {
15
 int cnt = 0;
16
 int i;
17
 
18
 for (i = 0; i<=(strlen(string)-strlen(substring)); i++) {    
19
  if (substrcmp(&string[i], substring)) cnt++;
20
 }
21
22
 return cnt;
23
}
24
25
int main(int argc, char *argv[]) {
26
 char str1[] = "adc adb adc";
27
 char str2[] = "adc";
28
 int z;
29
  
30
 printf("wie oft kommt str2 in str1 vor?\n");
31
 z = strvgl(str1, str2);
32
 printf("str2 ist %d mal enthalten.\n", z);  
33
 
34
 system("PAUSE");  
35
 return 0;
36
}

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

strstr liefert, wenn der Substring nicht gefunden wurde, eine NULL 
zurück.
Wenn es ihn gibt, die Adresse vom ersten Zeichen.
Du musst also nicht von jeder Position aus suchen, sondern nur von den 
gefundenen.

Du willst strstr wie ein strncmp (Standardfunktion) missbrauchen. Das 
geht aber nicht.
Und wenn NULL auftaucht, kommt deine gesamte Berechnung durcheinander

Du musst auch mal mit Beispielen arbeiten, wo kein Treffer erzielt wird.

Peter schrieb:
> Ich möchte doch aber wissen, wie oft es vorkommt und dies ausgeben

Die Ausgabe erfolgt in der rufenden Funktion.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.