Problem in c

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
penthesilea
Beiträge: 147
Registriert: 19.02.2003 23:51:24
Wohnort: Ulm

Problem in c

Beitrag von penthesilea » 02.02.2004 13:36:49

Hallo,
erstmal den code,

Code: Alles auswählen

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

int main() {
    /*
     * nun lenken wir die Standardausgabe in die Datei stdout.txt um:
     *
     * erst schliessen wir den Filedeskriptor 1; dann ist dieser der
     * kleinste freie; nun oeffnen wir die Datei stdout.txt zum schreiben
     * (wobei sie evtl. angelegt bzw. auf Laenge 0 verkuerzt wird);
     * beim Oeffnen wird im Erfolgsfall der kleinste freie FD geliefert
     * und das ist hier 1, also die Standardausgabe
     *
     * => so haben wir als stdout in die Datei stdout.txt umgelenkt
     *
     * Bem.: Gleiche Wirkung wie wenn man das Programm umlenkung_stdout1.c
     * auf der Kommandozeile mit "> stdout.txt" aufgerufen haette!
     */
    close(1);
    if (open("stdout.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666) < 0)
	perror("stdout.txt"), exit(1);

    /* Ausgabe auf die Standardausgabe  und somit in die Datei stdout.txt*/
    puts("Hallo Welt!");
    printf("Integer: %d\n", 4711);	/* usw.... */

    return 0;
}
Wie ihr seht möchte ich die Standartausgabe in die Datei stdout.txt umlenken. Gut das funktioniert. Jetzt möchte ich aber wieder, dass er mir z.B.

Code: Alles auswählen

 puts("hallo");
ganz normal aufs Terminal ausgibt. Ein fcloseall() hat nichts gebracht und auch sonst habe ich nichts gefunden, was mich weiterbringen würde. Und naja das mit den File Descriptoren habe ich auch nicht so ganz verstanden. :(

gruss penthesilea

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 02.02.2004 15:19:12

Du kannst den Originaldeskriptor vorher kopieren. s.u.

(Bei manchen C-Compilern ist stdout übrigens ein Makro, das du deshalb nicht ändern kannst, in dem Falle wird es wohl nicht funktionieren...)

Code: Alles auswählen

#include <stdio.h>
#include <unistd.h>

main()
{
    int Orig_STDOUT;
    /* Kopie machen */
    Orig_STDOUT = dup(1);
  
    /* stdout umleiten */
    freopen("test.txt", "wt", stdout);
    printf("In test");
  
    /* und wieder zurueck */
    fclose(stdout);
    dup2(Orig_STDOUT, 1);
    stdout = fdopen(1, "wt");

    /* jetzt noch die Kopie schliessen */
    fclose(fdopen(Orig_STDOUT, "w"));

    printf("in stdout");
}

Benutzeravatar
eC
Beiträge: 354
Registriert: 24.07.2002 13:34:13
Wohnort: karlsruhe

Re: Problem in c

Beitrag von eC » 02.02.2004 15:43:30

penthesilea hat geschrieben: Jetzt möchte ich aber wieder, dass er mir z.B.

Code: Alles auswählen

 puts("hallo");
ganz normal aufs Terminal ausgibt.
Hi,

müßte da nicht

Code: Alles auswählen

fprintf(stderr, "hallo");
das machen was Du möchtest?
Allerdings ist das natürlich kein Output nach stdout,
wie man sieht :)

gruss

eC

Benutzeravatar
penthesilea
Beiträge: 147
Registriert: 19.02.2003 23:51:24
Wohnort: Ulm

Beitrag von penthesilea » 03.02.2004 01:12:46

Vielen Dank für eure Mühen.

Aber was ich noch loswerden muss: ich hasse C!!!!!

Wieso stürzt mein Programm ab, wenn ich eine einfache Ausgabe (Kontrollausgabe für mich) weggmache? Wenn ich sie wieder hinmache geht das Programm.

Wieso funktionieren meine Methoden nicht , wenn ich als Rückgabewert ein Array haben will. Wieso funktioniert es dann, wenn ich das gleiche Array über Seiteneffekte zurückgebe???

Ich könnte immer noch so weiter machen. Sorry aber ich bin gerade sehr frustriert.

Gruss penthesilea

Benutzeravatar
spiffi
Beiträge: 1128
Registriert: 09.08.2003 19:02:27

Beitrag von spiffi » 03.02.2004 02:05:54

penthesilea hat geschrieben:Aber was ich noch loswerden muss: ich hasse C!!!!!
C ist cool! Aber es gibt wohl kaum eine Sprache, in der man sich so leicht selbst in den Fuß schießen kann. *ggg*
Kleiner Tipp: Kompiliere mit -Wall und beachte die Warnungen. Die geben gute Hinweise auf möglicherweise fehlerhaften Code.
penthesilea hat geschrieben:Wieso stürzt mein Programm ab, wenn ich eine einfache Ausgabe (Kontrollausgabe für mich) weggmache? Wenn ich sie wieder hinmache geht das Programm.
Das ist ein Klassiker! Wenn so etwas passiert hast Du höchstwahrscheinlich vorher irgendwo einen Bufferoverflow produziert.
Was danach passiert, ist das, was der C-Standard so schön als undefiniertes Verhalten bezeichnet.
penthesilea hat geschrieben:Wieso funktionieren meine Methoden nicht , wenn ich als Rückgabewert ein Array haben will. Wieso funktioniert es dann, wenn ich das gleiche Array über Seiteneffekte zurückgebe???
Es gibt keine Methoden in C, nur Funktionen.
Du kannst statt dem Array einen Pointer zurückgeben. Und von was für Seiteneffekten redest Du hier?

Benutzeravatar
Bert
Beiträge: 3751
Registriert: 16.07.2002 14:06:52
Wohnort: Dresden
Kontaktdaten:

Beitrag von Bert » 03.02.2004 08:19:15

penthesilea meint sicherlich die Übergabe / Rückgabe über Pointeradressen.

Im Prinzip hast Du schon Recht Spiffi. Man hat so viele Freiheiten, das man schon mächtig aufpassen muß.
Ich muß aber gestehen, das ich mittlerweiel auch so meine Probleme mit C hab. Nach 2-3 Jahren C++ (und dort bewußt versucht einen C/C++ Mischmasch zu umgehen) fehlt mir in C vieles (STL,...) Ganz schlimm ist dieses Gefühl nach dem Kennenlernen von Java geworden. Was mich dort begeistert ist der Umfang der vorhandenen Libs. In C fange ich ja doch jedesmal mit den Schraubenfeilen an, wenn ich eigentlich ein Auto bauen will.
Programmer: A biological machine designed to convert caffeine into code.
xmpp:bert@debianforum.de

Benutzeravatar
penthesilea
Beiträge: 147
Registriert: 19.02.2003 23:51:24
Wohnort: Ulm

Beitrag von penthesilea » 03.02.2004 10:28:19

Hallo,

Genau das ist mein Problem, ich habe zuerst Java kennen gelernt und nu lerne ich c. Anders rum wäre es echt besser gewesen.
Und ja ich habe diese Array pointer zurück gegeben und es funktionierte trotzdem nicht.
Und unter Seiteneffekten verstehe ich sowas :

Code: Alles auswählen

 int main() {
    int a[2];
    funktion(a);
}
void funktion(int* array) {
   int i;
   for(i=0; i<2;i++) {
      a[i]=i;
    }
}
das Array a im Hauptprogramm wird verändert. Viel schöner ist es wie ich finde, das Array zurückzugeben mit return array. Aber sowas funktioniert ja nicht bei mir.


Kennt eigentlich jemand ein c-Tutorial, welches mir ganz genau erklärt wie das mit den Funktionen funktioniert.
Gruss penthesilea

Benutzeravatar
Bert
Beiträge: 3751
Registriert: 16.07.2002 14:06:52
Wohnort: Dresden
Kontaktdaten:

Beitrag von Bert » 03.02.2004 12:15:52

Wie Spiffi schon sagte, das mit dem Pointer des Arrays zurückgeben geht natürlich auch C.

Du mußt dann natürlch das Array nicht auf dem Stack anlegen, sondern auf dem Heap. (also per malloc()). Denn der Speicher auf dem Stack ist ja bereits ungültig, wenn Du aus der Funktion zurückkehrst. Sowas gibt schöne Effekte ;-)

Wenn Du mit dem Array - Rückgeben noch Probleme hast, dann schreib doch mal den Code- Schnippsel und die Fehlermeldung
Programmer: A biological machine designed to convert caffeine into code.
xmpp:bert@debianforum.de

Benutzeravatar
bitbieger
Beiträge: 179
Registriert: 23.10.2003 08:26:00
Kontaktdaten:

Beitrag von bitbieger » 03.02.2004 14:23:02

Code: Alles auswählen

int main() {
    int* a;
    a = funktion(2);

    /* blablabla */
    free((void*)a);
}

int* funktion(int size) {
    int* pResult = (int*)malloc(sizeof(int) * size);
    int i;
    for(i=0; pResult && i<size;i++) {
        pResult[i]=i;
    }

    return pResult;
}
Rückgabe geht doch :)

Benutzeravatar
penthesilea
Beiträge: 147
Registriert: 19.02.2003 23:51:24
Wohnort: Ulm

Beitrag von penthesilea » 03.02.2004 15:13:03

vielen lieben Dank
dass das so funktioniert wusste ich nicht. Wieso bekommt man das auch nicht erklärt?
nochmals vielen lieben Dank.
Ich denke das löst so einige meiner Probleme.

Benutzeravatar
bitbieger
Beiträge: 179
Registriert: 23.10.2003 08:26:00
Kontaktdaten:

Beitrag von bitbieger » 03.02.2004 16:15:53

da nicht für... :D
Wenn du Startprobleme in C hast, kannst du mich auch direkt per ICQ anpiepen.

cu

Antworten