beliebig langen String einlesen in c

Hallo C Freunde !

Ich habe da ein kleines Problem: Ich möchte gerne einen Sring über die Console einlesen das ganze in Array speichern und dann einen bestimmten Buchstaben der ebenfalls über die Konsole eingelesen wird suchen und ausgeben wie oft diers im Text vorkommt.

Habe das auch teilweise gelöst habe folgendes gemacht:

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

#define maxleng 200

int zaelen(char* arr, char letter)
{
    int i=0;

    int count=0;

    while(arr[i]!= '\0')
    {
    
        if(letter== arr[i])
        {
            count++;
        }
        
    i++;
    
    }

    return count;    

}

int main (void)
{
    char* eingabe=(char*)malloc(sizeof(char));
    char b= ' ';

    

    printf("Bitte geben Sie einen Text ein!\n");
    

    fgets(eingabe,maxleng,stdin);
    

    printf("Bitte geben Sie den zu suchenden Buchstaben ein\n");
    
    scanf("%c",&b);
    
    printf("%i\n",zaelen(eingabe, b));
    
    free(eingabe);    

    return 0;
    
}
So nun zwei Probleme:

1. Der String soll ja beliebig lang sein aber wie mache ich das den fgets erwartet ja eine Länge von mir ? deshalb ist er im moment noch mit maxlaeng begrenzt

2. Wenn ich free benutze wird meine Console mit Fehlermeldungen überflutet:

*** glibc detected *** ./a.out: free(): invalid next size (fast): 0x0844d008 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0xb76ff591]
/lib/tls/i686/cmov/libc.so.6(+0x6cde[0xb7700de8]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xb7703ecd]
./a.out[0x8048615]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb76aabd6]
./a.out[0x80484a1]
======= Memory map: ========

aber warum wenn ich speicher mit malloc allokiere muss ich diesen doch wieder mit free() Freigeben ?

Danke im Vorraus für eure Hilfe!
 
Also für dein erstes Problem gäbe es die Lösung, alle Zeichen selbst einzulesen und dynamisch zu allozieren. Ein Beispiel dazu hab ich im Forum schonmal gepostet, hier ein Link zum Post.

Zu deinem zweiten Problem habe ich spontan auch keine Lösung, aber es gibt bei der Fehlermeldung ein Haufen Ergebnisse bei Google, evtl. ist da etwas dabei. Einen Fehler sehe ich jedenfalls nicht. Allerdings frage ich mich, warum du fgets verwendest, statt gets, welches sowieso von STDIN liest und zudem eine Prüfung vor Pufferüberlauf drin hat.
 
Hallo lookshe!

Danke für deine Antwort allerdings habe ich probleme deinen Code zu verstehn bzw Teile davon es wäre net wenn du mir auf die Sprünge helfen könntest.

Nun ich möchte nicht das ganze nochmal Posten. Also sag ich kurz so wie ich es meine Verstanden zu haben und Poste nur die Stückchen mit dennen ich Probleme habe.

Also so wie ich das sehe allozierst (by the way: heißt das nun allokieren oder allozieren ?) du zuerst speicher mit malloc dann kommt eine fehlerbehandlung und dann überprüfst du ob ein Zeichen mit dem Wert 13 eingegeben wurde (ist glaub ich Cariage Retrun also neue Zeile) falls nicht überprüfst du ob zahlen buchstaben usw eingeben wurden dann zählst du die inputlänge hoch. Falls die länge die Maxlange übersteigt erweitertst du den speicher mit realloc bei backspace oder escape wird alles zurückgesetz also neue Eingabe. So das war jetzt das ganze in Grob ich hoffe das passt so jetzt zu meinem Fragen.

Was übergibst du mit input show_input
Code:
char* read_input(int show_input, char* input_text)
bzw für was brauchst du das ??

warum setzt du inputArray anfänglich auf NULL würde da die Fehlerprüfung nicht reichen ?

Code:
char* inputArray = NULL;
und warum setzt du bei inputArray an Stelle [0] ein EOF ?

außerdem kann ich folgenden zwei Abfragen nicht ihren Sinn entlocken
(also ich weiß Sie haben einen Sinn und ich weiß auch das das ein If ist aber ich versteh es einfach nicht )
Code:
return (inputLength?inputArray:NULL);
putchar(show_input?input:'*');
Sorry für den langen Text und sorry falls dumme Fragen bei sind aber ich bin noch nicht so Fit in C. :)

Danke für deine Hilfe!
 
Also so wie ich das sehe allozierst (by the way: heißt das nun allokieren oder allozieren ?) du zuerst speicher mit malloc dann kommt eine fehlerbehandlung und dann überprüfst du ob ein Zeichen mit dem Wert 13 eingegeben wurde (ist glaub ich Cariage Retrun also neue Zeile) falls nicht überprüfst du ob zahlen buchstaben usw eingeben wurden dann zählst du die inputlänge hoch. Falls die länge die Maxlange übersteigt erweitertst du den speicher mit realloc bei backspace oder escape wird alles zurückgesetz also neue Eingabe. So das war jetzt das ganze in Grob ich hoffe das passt so jetzt zu meinem Fragen.
Richtig, du hast also soweit den Code verstanden.

Was übergibst du mit input show_input
Code:
char* read_input(int show_input, char* input_text)
bzw für was brauchst du das ??
Das show_input wird übergeben, da diese Methode auch für Passworteingabe benutzt wurde und dort möchte man das Passwort ja nicht auf dem Bildschirm sehen.

warum setzt du inputArray anfänglich auf NULL würde da die Fehlerprüfung nicht reichen ?
Ich initialisiere meine Variablen immer, da ich sonst nicht weiss, was sie wirklich enthalten und das kann u.U. zu interessanten Fehlern zur Laufzeit führen, wo man lange sucht. (Ist mir zumindest auf Arbeit schon öfter passiert)

Code:
char* inputArray = NULL;
und warum setzt du bei inputArray an Stelle [0] ein EOF ?
Ich terminiere den String einfach nur, warum ich das genau gemacht habe, weiss ich auch nicht mehr. Zudem müsste es eigentlich nach der folgenden if-Abfrage kommen. Aber irgendeinen Grund hatte es.

außerdem kann ich folgenden zwei Abfragen nicht ihren Sinn entlocken
(also ich weiß Sie haben einen Sinn und ich weiß auch das das ein If ist aber ich versteh es einfach nicht )
Code:
return (inputLength?inputArray:NULL);
putchar(show_input?input:'*');
Gut, dass es ein if ist, hast du ja schonmal verstanden. Also machen wir auch mal eines draus:
Code:
if (inputLength) {
   return inputArray;
} else {
   return NULL;
}

if (show_input) {
   putchar(input);
} else {
   putchar('*');
}
Beide Code-Abschnitte machen genau das gleiche, spart nur ein paar Zeilen und ist für jemanden, der mit dem Ternären Operator vertraut ist schneller zu lesen.

Sorry für den langen Text und sorry falls dumme Fragen bei sind aber ich bin noch nicht so Fit in C. :)

Danke für deine Hilfe!

Für sowas braucht man sich doch nicht entschuldigen, du hast was nicht verstanden und nachgefragt ;)
Ich hoffe ich konnte helfen.


/Edith hat die Antwort auf deine Frage wegen dem allokieren oder allozieren gefunden:

http://de.wikipedia.org/wiki/Allokation_(Informatik)#Sprachliches
Allokation = Substantiv
allozieren = Verb
 
Zuletzt bearbeitet:
Hallo Lookshe!

Danke ich glaube ich habe es nun verstanden... ich werde nun zur nächsten Phase schreiten und das ganze versuchen nach zu Basteln damits auch wirklich sitzt.

Falls doch noch Probleme Auftreten sollten werde ich diesen Thread einfach um ein paar Fragen erwetiern :wink:
 
Hallo ich noch mal ;)

So das mit den Strings einlesen funzt super... Danke!

Ich wollte das ganze natürlich auch gleich praktisch Anwenden und möchte nun einen String von der Konsole einlesen und diesen Dann in eine .txt speichern.

Das einlesen und ausgeben funzt super wenn ich folgendes mache:

Code:
  char text[]={"Bitte geben Sie einen Text ein!\n"};
    
char* bla = read(text);

int i=0;

while(bla[i] != '\0')
    {
        printf("%s",bla[i]);    
        i++;

    }

So nun möchte ich das ganze aber in die .txt schreiben also kommt noch FILE usw hinzu (das lass ich mal weg weil das funzt ja )
und besagtes stück wird so geändert:

Code:
while(bla[i] != '\0')
    {
        fprintf(log,bla[i]);    
        i++;

    }

So nun ist einfach das problem das fprintf nur echte Strings animmt also nur "... " auch so etwas wie :
Code:
 fprintf(log,bla);
geht nicht! Wie kann ich also nun das was in meinem array bla steht in die .txt datei schreiben ???
 
Also meines Wissens und der Referenz von fprintf nach, arbeitet es wie printf, also sollte folgendes eigentlich richtig sein:

Code:
fprintf(log,"%s",bla);

Du kannst mit den printfs übrigens char-Arrays einfach mit %s und dem Namen des Arrays ausgeben lassen und musst nicht jeden Character einzeln machen.
 
Zurück
Oben