Dateiverarbeitung (fopen); Strings (gets)

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
DANrulz81
Beiträge: 53
Registriert: Fr Dez 23, 2011 9:40 pm

Dateiverarbeitung (fopen); Strings (gets)

Beitrag von DANrulz81 » Mo Jan 16, 2012 4:25 pm

Hallo zusammen,

ich bin jetzt mittlerweile bei der Dateiverarbeitung angekommen, nun hab ich ein paar Fragen dazu. Doch zunächst mal der Code:

Code: Alles auswählen

#include <stdio.h>
#define TITEL printf("\n\nvon Dennis Brenzel,2012\n\n");

int main(void)
{
    char string[]="Das ist ein Test.";
    int size=0, search=0 ,i=0 ,zaehler=0;

    FILE *file = fopen("datei2.txt", "w");

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

    for(size=0;string[size]!='\0';size++)
    {};

    for(search=0;string[search]!='\0';search++)
    {
        if(string[search]=='e')
        {
            zaehler++;
        }
    }

    printf("\n\nDer String ist %i Bytes lang.\n",size);
    printf("\nEs gibt in diesem String %i 'e'.\n\n",zaehler);

    for(i=0; i<size; i++)
    {
		fputc(string[i], file);
	}

	fclose(file);

    TITEL;

    return 0;
}
Meine Fragen:
- Kann ich das mit dem Datei öffnen so machen, wie oben beschrieben, oder ist das stylistisch nicht in Ordnung? Also das ich lieber die Datei erst öffne, wenn diese auch gebraucht wird?
- Da ich mich zusätzlich noch mit der dynamischen Speicherverwaltung beschäftige, wollte ich fragen, ob es Sinn macht, hier vorher einen Speicher für den String zu reservieren?

Danke im vorraus

Edit by Xin: Betreff geändert von 'Kleine Frage zur Dateiverarbeitung'

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Kleine Frage zur Dateiverarbeitung

Beitrag von cloidnerux » Mo Jan 16, 2012 4:42 pm

- Kann ich das mit dem Datei öffnen so machen, wie oben beschrieben, oder ist das stylistisch nicht in Ordnung? Also das ich lieber die Datei erst öffne, wenn diese auch gebraucht wird?
Bei der Programmgröße spielt das noch keine rolle, Aber um Fehler vorzubeugen ist es sinnvoll das Öffnen der Datei und das verarbeiten nahe beieinander zu halten, um dann alles auf einen blick zu haben.
- Da ich mich zusätzlich noch mit der dynamischen Speicherverwaltung beschäftige, wollte ich fragen, ob es Sinn macht, hier vorher einen Speicher für den String zu reservieren?
Für statische Strings wie es bei dir der Fall ist, ist es sinnlos, da du dir so nur mehr Fehlerquellen für ein triviales Problem einhandelst. Sinnvoll wird es erst, wenn du den String aus der Datei auslesen würdest oder erst zur Laufzeit durch den Nutzer eingeben lässt.

MfG cloidnerux.
Redundanz macht wiederholen unnötig.
quod erat expectandum

DANrulz81
Beiträge: 53
Registriert: Fr Dez 23, 2011 9:40 pm

Re: Kleine Frage zur Dateiverarbeitung

Beitrag von DANrulz81 » Mo Jan 16, 2012 4:50 pm

Für statische Strings wie es bei dir der Fall ist, ist es sinnlos, da du dir so nur mehr Fehlerquellen für ein triviales Problem einhandelst. Sinnvoll wird es erst, wenn du den String aus der Datei auslesen würdest oder erst zur Laufzeit durch den Nutzer eingeben lässt.
Ja, das hab ich mir fast gedacht :D . Klar, hier steht ja die Größe vor dem compilieren schon fest. Bei einer Eingabe würde das natürlich mehr Sinn machen. Gibt es irgendwie eine Art "Regel" bei der man sagt, man sollte ab der und der Größe Speicher reservieren, oder hält man das im Allgemeinen so, dass man, sobald ein String variabel wird, sowieso immer Speicher (dynamisch) reserviert? Oder was wäre gescheiter?

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Kleine Frage zur Dateiverarbeitung

Beitrag von cloidnerux » Mo Jan 16, 2012 5:51 pm

Gibt es irgendwie eine Art "Regel" bei der man sagt, man sollte ab der und der Größe Speicher reservieren, oder hält man das im Allgemeinen so, dass man, sobald ein String variabel wird, sowieso immer Speicher (dynamisch) reserviert? Oder was wäre gescheiter?
Es gibt keine festen Programmierregeln, alles ist Relativ.
Das gilt auch für strings. Hast du einen feststehenden Text, den du nur ausgeben willst -> Direkt eingeben.
Aber in dem Moment, wo du gar nicht mehr genau sagen kannst, wie groß das ganze wird, musst du zwangsläufig auf dynamische Konzepte Umsteigen und musst daher auch Speicher allozieren. Anders sähe es aber z.B aus, wenn du Einträge fester Größe verarbeitest, da könntest du dir z.B ein Array mit der Größe direkt anlegen.
Fazit: Wenn du dir nicht sicher bist, überlege logisch und du wirst die richtige Lösung finden.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Kleine Frage zur Dateiverarbeitung

Beitrag von Xin » Mo Jan 16, 2012 5:56 pm

DANrulz81 hat geschrieben:Gibt es irgendwie eine Art "Regel" bei der man sagt, man sollte ab der und der Größe Speicher reservieren, oder hält man das im Allgemeinen so, dass man, sobald ein String variabel wird, sowieso immer Speicher (dynamisch) reserviert? Oder was wäre gescheiter?
Wenn ich einen Zahl in einen String umwandle:

Code: Alles auswählen

unsigned int zahl = ...;

char buffer[11];
sprintf( "%d", zahl );
dann ist die Zahl in der Länge nicht festgelegt und damit der String auch nicht. Es gibt aber eine maximal Länge für ein unsigned int und die ist 10 (11 mit Nullbyte).

Wenn Du Daten nur kurz brauchst und die (maximale) Länge kennst und diese Länge keine gigantischen Ausmaße annimmt, dann arbeite auf dem Stack mit einer lokalen Variablen. Ansonsten organisiere Dir Speicher.
Auf dem Stack zu arbeiten ist sicherer als Speicher anzufordern. Das kann man im Design seiner Programme berücksichtigen. Du darfst Zeiger auf den Stack an Funktionen weitergeben:

Code: Alles auswählen

puts( buffer );
Aber NIEMALS zurückgeben:

Code: Alles auswählen

return buffer;   // <- VER-BO-TEN-!
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

DANrulz81
Beiträge: 53
Registriert: Fr Dez 23, 2011 9:40 pm

Re: Kleine Frage zur Dateiverarbeitung

Beitrag von DANrulz81 » Mo Jan 16, 2012 6:41 pm

O.k. Vielen dank schonmal. Jetzt wollte ich natürlich gleich mal was ausprobieren, irgendwie klappt das so nicht. Wie soll ich denn einen String definieren, ohne zu wissen, wie groß dieser wird.
Hier mal ein kleines Beispiel:

Code: Alles auswählen

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

int main(void)
{
    char eingabe[10];
    int zaehler=0;

    printf("\nBitte geben Sie einen String ein: ");

    gets(eingabe);

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

    for(zaehler=0;eingabe[zaehler]!='\0';zaehler++)
    {
    };

    printf("\nDer String ist %i Zeichen lang.",zaehler);

    return 0;
}
Wenn ich jetzt natürlich mehr als 10 Zeichen eingebe, wird er mir immer als Länge des Strings 11 angeben. Ich kann ja schlecht eingabe erst nachher definieren, da ich sonst ja keine Variable habe, in die ich mit gets() schreiben kann. Wie mach ich das?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Kleine Frage zur Dateiverarbeitung

Beitrag von Xin » Mo Jan 16, 2012 6:55 pm

DANrulz81 hat geschrieben:Wenn ich jetzt natürlich mehr als 10 Zeichen eingebe, wird er mir immer als Länge des Strings 11 angeben. Ich kann ja schlecht eingabe erst nachher definieren, da ich sonst ja keine Variable habe, in die ich mit gets() schreiben kann. Wie mach ich das?
Mit gets() gar nicht.

Mir fällt gerade auf, dass in der Std-Lib genau dazu noch ein Artikel fehlt, der bei gets() verlinkt ist. Wo sind die Leute, die mir Resourcen abgeben wollen? ;-)

Du kannst Dich an fread() versuchen.
Ansonsten geh einfach mal davon aus, dass Du als anständiger Programmierer niemals diese Funktion mehr verwenden willst. Für die Eingabe bei einem Testprogramm - kein Problem. Im echten Leben wirst Du sie nie mehr verwenden.

Also pack Dir im Testprogramm einen Buffer hin, der groß genug ist und im echten Leben verwendest Du diese Funktion auf gar keinen Fall, weil sie sich hervorragend für Buffer-Overflow-Angriffe eignet und deswegen auf keinen Fall mehr in echter Software benutzt wird.

Später nimmst Du eine GUI oder NCurses. Für jetzt kannst Du Programm-Parameter verwenden.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

DANrulz81
Beiträge: 53
Registriert: Fr Dez 23, 2011 9:40 pm

Re: Dateiverarbeitung (fopen); Strings (gets)

Beitrag von DANrulz81 » Mo Jan 16, 2012 7:05 pm

Vergessen wir kurz mal das mit der Dateiverarbeitung

Wie kann ich denn sonst noch einen String einlesen, dessen größe noch nicht bekannt ist? Ich kann ja schlecht hingehen, und Millionen von Bytes vorher reservieren und dann kopiert einer "Herr der Ringe" Band 1-3 als String :o

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Dateiverarbeitung (fopen); Strings (gets)

Beitrag von Xin » Mo Jan 16, 2012 9:08 pm

DANrulz81 hat geschrieben:Wie kann ich denn sonst noch einen String einlesen, dessen größe noch nicht bekannt ist?
Das habe ich Dir aufgezählt. Beim Einstieg nimmst Du im Idealfall Programmparameter

Code: Alles auswählen

meinprogramm.exe "Dies ist ein Parameter" "Das ist Parameter 2" Parameter3
DANrulz81 hat geschrieben:Ich kann ja schlecht hingehen, und Millionen von Bytes vorher reservieren und dann kopiert einer "Herr der Ringe" Band 1-3 als String :o
Herzlich Willkommen in der Anwendungsentwicklung.

Du kannst das nicht, sonst steht der Rechner, der User kann Dir soviel Daten um die Ohren hauen. Und Du musst damit klarkommen. Notfalls musst Du teilweise einlesen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

DANrulz81
Beiträge: 53
Registriert: Fr Dez 23, 2011 9:40 pm

Re: Dateiverarbeitung (fopen); Strings (gets)

Beitrag von DANrulz81 » Di Jan 17, 2012 9:10 pm

Also jetzt das ganze nochmal ohne das böse gets():

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char eingabe[100000];
    int zaehler=0,size=0;

    printf("\nBitte geben Sie einen String ein: ");
    fgets(eingabe,100000,stdin);
    printf("\n%s",eingabe);

    for(zaehler=0;eingabe[zaehler]!='\0';zaehler++){};

    printf("\nDer String ist %i Zeichen lang.",zaehler);

    size = strlen(eingabe);
    printf("\nDer String ist %i (wegen Stringende \\0) Zeichen lang.\n\n",size);

    return 0;
}
Ist das so besser?

Antworten