2 Stimmen

Drucken auf dem Bildschirm und einer Textdatei

Ich muss bestimmte Dinge in eine Textdatei schreiben und diese auf dem Bildschirm anzeigen lassen. (Ich spreche von einem C-Programm-Utility) Der Menüpunkt sieht wie folgt aus,

1\. display AA parameters
2. display BB parameters
3. display CC parameters
4. dump all
5. Exit
Select option >

Wenn sie 1/2/3 auswählen, muss es nur auf dem Bildschirm angezeigt werden, oder wenn sie die Option #4 auswählen, müssen alle Parameter einzeln angezeigt werden, und dasselbe muss in einer .txt-Datei gespeichert werden.

Ich weiß, dass wir die Funktionen printf und fprintf verwenden können, um sie auf dem Bildschirm anzuzeigen bzw. in eine Textdatei zu schreiben. Das Problem ist, dass ich mehr als 20 Parameter angezeigt habe und jeder mindestens 20 Unterparameter hat.

Ich bin derzeit wie folgt implementiert,

printf (        "Starting serial number       [%ld]\n", 
        serial_info_p->start_int_idx);
fprintf(file_p, "Starting serial number       [%ld]\n", 
        serial_info_p->start_int_idx)
printf (        "Current Serial number         [%d]\n", 
        serial_info_p->current_int_idx);
fprintf(file_p, "Current Serial number         [%d]\n", 
        serial_info_p->current_int_idx);

Gibt es einen einfachsten Weg, dies zu implementieren, um die Anzahl der Codezeilen zu reduzieren?

0voto

Sean Bright Punkte 114347
#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0]))

FILE *f = fopen("somefile.txt", "a+");
FILE *fp[] = { stdout, f };
int i = 0;

for (i = 0; i < ARRAY_LEN(fp); i++) {
    fprintf(fp[i], "Starting serial number [%ld]\n", serial_info_p->start_int_idx);
    fprintf(fp[i], "Current serial number [%ld]\n", serial_info_p->start_int_idx);
}

fclose(f);

0voto

Jonathan Leffler Punkte 694013

Ich würde radikaler vorgehen als die bisherigen Vorschläge, aber vielleicht ist das zu viel für Sie. (Das 'inline'-Schlüsselwort ist C99; Sie können es ohne große Konsequenzen weglassen, wenn Sie nach C89 programmieren).

/*
** These could be omitted - unless you get still more radical and create
** the format strings at run-time, so you can adapt the %-24s to the
** longest tag you actually have.  Plus, with the strings all here, when
** you change the length from 24 to 30, you are less likely to overlook one!
*/
static const char fmt_int[]  = "%-24s [%d]\n";
static const char fmt_long[] = "%-24s [%ld]\n";
static const char fmt_str[]  = "%-24s [%s]\n";   /* Plausible extra ... */

static inline void print_long(FILE *fp, const char *tag, long value)
{
    fprintf(fp, fmt_long, tag, value);
}

static inline void print_int(FILE *fp, const char *tag, int value)
{
    fprintf(fp, fmt_int, tag, value);
}

static inline void print_str(FILE *fp, const char *tag, const char *value)
{
    fprintf(fp, fmt_str, tag, value);
}

static void dump_data(FILE *fp, const serial_info_t *info)
{
    dump_long("Starting serial number", info->start_int_idx);
    dump_int( "Current Serial number",  info->current_int_idx);
    /* ... and similar ... */
}

Dann würde der aufrufende Code Folgendes aufrufen dump_data() einmal (mit Argument stdout ) für die Optionen 1, 2, 3 und zweimal (einmal mit stdout , einmal mit Dateizeiger für die Ausgabedatei) für Option 4.

Wenn die Anzahl der Parameter wirklich sehr groß wird (mehrere hundert), würde ich sogar eine Datenstruktur in Betracht ziehen, die Typ- und Offset-Informationen kodiert ( offsetof de <stddef.h> ) und Zeigern auf Funktionen und dergleichen, so dass es nur eine Schleife in dump_data() Iteration über eine Struktur, die alle notwendigen Informationen kodiert.

Man könnte sich das Leben auch vereinfachen, indem man denselben grundlegenden Integer-Typ verwendet ( long in Ihrem Beispiel) für alle Integer-Mitglieder der Datenstruktur.

Fred Brooks sagt in "Mythical Man Month" - ein Buch, das es wert ist, gelesen zu werden, falls Sie es noch nicht getan haben, aber stellen Sie sicher, dass Sie die Ausgabe zum zwanzigsten Jahrestag lesen - in Kapitel 9:

Zeigen Sie mir Ihre Flussdiagramme [Code] und verbergen Sie Ihre Tabellen [Datenstrukturen], und ich werde weiterhin verblüfft sein. Zeigen Sie mir Ihre Tabellen, und ich brauche Ihre Flussdiagramme normalerweise nicht; sie werden offensichtlich sein.

Eine tabellengesteuerte Version dieses Codes könnte nicht nur Platz sparen, sondern auch Frustration hervorrufen, wenn hundert zusammenhängende Funktionen auf die gleiche Weise geändert werden müssen, während eine einfache Änderung der Tabellendaten das Ganze hätte beheben können.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X