C: Wie kann ich ein Pointer-Array anlegen, um die Fundstellen zu speichern?
/* 24_02 dynamische Speicherverwaltung
demonstriert realloc
ZUR BEACHTUNG: Dies ist ein reines Demo-Programm!
Speicher-Reallokation in 10-Byte-Blöcken ist in der Praxis nicht sinnvoll!
Speicherallokation und insbesondere Speicher-Reallokation kosten erhebliche System-Resourcen!
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRLEN 10
int Such(char* strPtr, char* Ptr2);
int main()
{
int n = 1;
char* strPtr = (char*)malloc(n * STRLEN); // kleinen Speicherblock anfordern
char* strPtr2 = (char*)malloc(n * STRLEN); // kleinen Speicherblock anfordern
printf("Bitte Text eingeben: \n");
fgets(strPtr, STRLEN, stdin); // einlesen
printf("\n");
while (strPtr[strlen(strPtr) - 1] != '\n') // Ende erreicht, letztes Zeichen '\n'?
{
n++; // Anzahl Blöcke inkrementieren
strPtr = (char*)realloc(strPtr, n * STRLEN); // größeren Speicher anfordern: n Blöcke
fgets(strPtr + strlen(strPtr), STRLEN + 1, stdin); // weiter einlesen, terminierende 0 überschreiben, STRLEN + 1 Byte stehen zur Verfügung
}
printf("Nach welcher Zeichenfolge soll gesucht werden?\n");
fgets(strPtr2, STRLEN, stdin); // einlesen
printf("\n");
while (strPtr2[strlen(strPtr2) - 1] != '\n') // Ende erreicht, letztes Zeichen '\n'?
{
n++; // Anzahl Blöcke inkrementieren
strPtr2 = (char*)realloc(strPtr2, n * STRLEN); // größeren Speicher anfordern: n Blöcke
fgets(strPtr2 + strlen(strPtr2), STRLEN + 1, stdin); // weiter einlesen, terminierende 0 überschreiben, STRLEN + 1 Byte stehen zur Verfügung
}
printf("Zeichenfolge wurde %i mal gefunden\n", Such(strPtr, strPtr2));
return 0;
}
int Such(char* strPtr, char* strPtr2)
{
int n = 0;
int p = 0;
int sip = 0;
int ltext = strlen(strPtr) - 1;
int lzfolge = strlen(strPtr2) - 1;
int lgteilt = ltext / lzfolge;
char* ptrarr[] = { NULL };
while ((lgteilt) > 0)
{
for (int i = 0; i < lzfolge; i++)
{
if (strPtr[p] == strPtr2[i])
{
sip++;
}
p++;
}
lgteilt--;
}
return (sip / lzfolge);
}
Ich verstehe leider nicht ganz, wie man ein Pointer-Array anlegen soll, um die Fundstellen zu speichern.
Ich habe zwar eine Schleife, aber diese kann z. B. "yay" nicht mit "ay" vergleichen.
Danke für die Hilfe.
1 Antwort
int vector[10]; /* Array von 10 Ints */
int *vector[10]; /* Array von 10 int Pointern */
char z[10]; /* Array von 10 Zeichen */
char s[]; /* Char Array unbekannter Länge, wird bei Aufruf */
char *s; /* zu einem char Pointer */
char *s[10]; /* 10 char ptr */
char *s[]; /* Array char prts */
char **s;
Wenn Du ein Match findest, setzt DU eben einen weiteren Pointer im Array auf die Fundstelle. Vorzugsweise initialisierst Du das Array mit NULL-Ptrs.
Hier nur ein vereinfachtes Beispiel, statisches Array, Matching auf einzelnes Zeichen, denn Deine Übungen mußt Du schon selbst erledigen:
#include <stdio.h>
int main (){
char s[]="Hallo Welt, dies ist ein einfacher kurzer String zur Demonstration";
char *matches[32];
for(int i=0;i<32;++i) matches[i]=NULL;
char *n=s;
printf("Needle: %s\n",n);
int pos=0;
while(*n){
if (*n=='e') matches[pos++]=n;
++n;
}
for(int i=0;matches[i];++i) printf("String @ %p, Match @ %p. Offset: %ld\n",s,matches[i],matches[i]-s);
}
Ausgabe:
Needle: Hallo Welt, dies ist ein einfacher kurzer String zur Demonstration
String @ 0x7ffc74749150, Match @ 0x7ffc74749157. Offset: 7
String @ 0x7ffc74749150, Match @ 0x7ffc7474915e. Offset: 14
String @ 0x7ffc74749150, Match @ 0x7ffc74749165. Offset: 21
String @ 0x7ffc74749150, Match @ 0x7ffc74749169. Offset: 25
String @ 0x7ffc74749150, Match @ 0x7ffc74749170. Offset: 32
String @ 0x7ffc74749150, Match @ 0x7ffc74749177. Offset: 39
String @ 0x7ffc74749150, Match @ 0x7ffc74749186. Offset: 54
Danke was mir auch recht unklar ist wie man ein zeichenkette so wie sie ist in einem Text vergleicht also wenn die if bedingung nur dann wahr ist wenn z.B "Hal" im Wort "Hallo" vorhanden ist also ich denke an einem Pointer der auf die 3 dreistellen "Hal" zeigt und gleichzeitig auf die ersten 3stellen von "Hallo" zeigt und 3 stellen auf einmal vergleicht und inkrementiert gibt es da eine Möglichkeit ?
Du implementierst eine naive Variante von strcmp().
[such]
[Ein viel längerer Text, der zu durchsuchen ist]
Du vergleichst die Zeichen aus such (needle) einzeln mit dem haystack. Bei Unterschied return false, sonst true.
Nun widerholst Du das ganze, indem Du such verschiebst, also anstatt bei haystack[0] bei haystack[1] anfängst. Das machst Du natürlich nur bis len(haystack) - len(such).
Wann immer Dein strcmp() also matcht, merkst Du dir den Pointer auf das Startzeichen.
------
Erste Verbesserung, anstatt true and false, lässt Du strcmp NULL und Pointer auf letztes Zeichen des Matches im Haystack zurückgeben, da du keien überlappenden Matches ersetzen kannst.
Danke könntest du das mit einem bsp. erklären weil so wirklich habe ich das nicht geblickt.