Zeichen im String zählen

Gast #540770
Lesenswert?

Hallo,
ich möchte ein Programm schreiben, welches herausfindet, wie viele Werte 
in einer Datei stehen. Dafür hab ich mir überlegt, das ich die Datei in 
einen String lade, um anschließend die Anzahl des Zeichens ";" zu 
zählen. Denn nach jedem Wert folgt ein Semikolon. Das Programm benötige 
ich in C.
Kann mir jemand helfen?
Danke. Carola
#540776
Lesenswert?

carola wrote:

> Kann mir jemand helfen?

Sicher.
Wobei hast du denn Schwierigkeiten:

Beim öffnen der Datei
Beim Einlesen der Zeichen
Beim Vergleich
Beim Erhöhen des Zählers
Beim Schliessen der Datei
Beim Aufbau der Schleife.


PS: Es ist unklug die ganze Datei in einem Rutsch
in einen String zu laden. Je nach Größe der Datei
brauchst du dafür
* ne Menge Speicher
* eine vernünftige Allokierungsstrategie um den String
  mit fortschreitender Dateigröße immer größer zu machen

Es ist viel einfacher die Datei Zeichen für Zeichen zu lesen.
Jedesmal wenn aus der Datei ein ';' gelesen wird, erhöhst du
deinen Zähler. Zum Schluss Zähler ausgeben, fertig.


  Datei öffnen

  if Datei nicht offen {
    Fehlermeldung ausgeben
    Programm beenden
  }

  Counter = 0;

  Solange ein Zeichen aus der Datei gelesen werden konnte {
    if Zeichen == ';'
      Counter++
  }

  Datei schliessen
  Counter ausgeben
Gast #540826
Lesenswert?

Hallo,
also im Moment hab ich das beim Vergleichen. Da meine Datei wirklich 
sehr groß ist, ist es wohl klüger jedes Zeichen einzeln zu laden. Da 
ergibt sich allerdings gleich die nächste Frage: Wie ging das nochmal?

Also geöffnet habe ich die Datei bereits mit fopen und das klappt auch.
Wenn ich dann ein einzelnes Zeichen geladen habe, muss ich das ja auf 
"," vergleichen. Da in meiner Datei mehrere Semikolons vorkommen, muss 
ich da dann mit Zeigern arbeiten? Der Vergleich muss ja für das nächste 
erneut durchgeführt werden.

Danke schonmal für die Hilfe.
Carola
Gast #540967
Lesenswert?

Hallo,
habe das Problem jetzt folgendermaßen gelöst und es funktioniert auch:-)

    do
    {
     fread(zeichen, 1, 1, fileptr_Quelldatei);
     if(*zeichen == ';')
     {
      zaehler++;
     }
    }while (!feof(fileptr_Quelldatei));

Dies ist ein Teil eines Programms, welches ich für eine 
Datteibearbeitung schreiben muss. Habe lange nicht mehr in C 
programmiert, deswegen die Nachfrage nach einfachen Dingen.

Carola
Moderator Persönliche Seite #540974
Lesenswert?

carola wrote:

>      fread(zeichen, 1, 1, fileptr_Quelldatei);

Da bliebe die Frage: wo ist der Speicherplatz reserviert, auf den
zeichen zeigt?

Außerdem wird der Rückkehrcode von fread() nicht ausgewertet.

Die lehrbuchmäßige Version einer derartigen Schleife wäre:
1
  int c;
2

3
  while ((c = getc()) != EOF) {
4
    if (c ... ) ...
5
  }
#541116
Lesenswert?

Jörg Wunsch wrote:
> Die lehrbuchmäßige Version einer derartigen Schleife wäre:
>
>
1
>   int c;
2
> 
3
>   while ((c = getc()) != EOF) {
4
>     if (c ... ) ...
5
>   }
6
>

Hab ich auch schon lange nicht mehr gemacht.
Wie verhält sich getc() (ich denke mal du meinst fgetc())
wenn es beim Lesen einen Fehler gab? Wird dann EOF
geliefert?

@Carole:

Die korrekte Form mit fread() wäre

  char zeichen;

  while( fread(&zeichen, 1, 1, fileptr_Quelldatei) ) {
     if( zeichen == ';' )
       zaehler++;
  }

  if( !feof(fileptr_Quelldatei)) {
    // Fehlermeldung: die Datei konnte nicht fehlerfrei bis
    // zum Ende gelesen werden
  }
  else
    // zaehler ausgeben

In dem Moment wo du eine der eof() Funktionen zur Steuerung
der Schleife benutzt, hast du schon einen Fehler gemacht.
Die Schleifensteuerung geschieht praktisch immer über den
Returncode der Lesefunktion. Dazu liefern alle Lesefunktionen
einen Returncode, der dazu geeignet ist. Der wird dazu
benutzt um festzustellen ob der Leseversuch erfolgreich war
oder nicht. Ein Leseversuch kann aus vielen Gründen scheitern:
* Der Benutzer hat die CD aus dem Laufwerk genommen
* Die Netzwerkverbindung ist zusammengbrochen
* Schadhafter Sektor auf der Diskette
* Ausfall des USB Stick
* Das Ende der Datei wurde erreicht.

Die eof() Funktionen sagen dir nur ob das Ende der Datei erreicht
wurde. Sie werden korrekt benutzt um nach dem Abbrechen der
Schleife rauszufinden, warum die Schleife abgebrochen wurde:
War es aufgrund EOF dann ist alles ok: die Datei konnte fehlerfrei
bis zum Ende gelesen werden.


Traurige Geschichte, ich weiss. In 70% aller Lehrbücher findet
sich das nicht sondern der Autor hat (ich behaupte mal aus
Unwissenheit) die klassische

   while( !feof( ... ) )

benutzt.
Moderator Persönliche Seite #541227
Lesenswert?

Karl heinz Buchegger wrote:

> Wie verhält sich getc() (ich denke mal du meinst fgetc())

getc() und fgetc() sind in ihrer Funktion gleich.  getc() darf aber
als Makro implementiert sein, der sein Argument mehr als einmal
bewertet, daher könnte es u. U. effektiver implementiert sein.

Was ich aber vergessen habe ist:
1
getc(fileptr_Quelldatei)

Die Funktion bekommt natürlich ein Argument.

> wenn es beim Lesen einen Fehler gab? Wird dann EOF
> geliefert?

Ja, natürlich.  Daher muss der Typ der Variablen, auf die man das
Ergebnis zuweist, auch wirklich `int' sein und nicht etwa `char':
EOF ist -1 und damit von allen Zeichen (0...255) verschieden.

Unterscheidung nach Dateiende oder Fehler wie gehabt mit feof()
oder ferror() (eine dieser beiden Funktionen muss wahr sein,
wenn getc() zuvor EOF gebracht hat).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren