Comment faire pour rediriger la sortie de retour à l'écran après freopen(“out.txt”, “a”, stdout)
#include <stdio.h>
int main() {
printf("This goes to screen\n");
freopen("out.txt", "a", stdout);
printf("This goes to out.txt");
freopen("/dev/stdout", "a", stdout);
printf("This should go to screen too, but doesn't\n");
return 0;
}
J'appelle freopen pour rediriger le stdout à out.txt puis-je imprimer quelque chose sur le fichier, maintenant, je veux rediriger le dos à l'écran, mais freopen("/dev/stdout", "a", stdout); ne fonctionne pas. Est-il possible de le faire à l'aide de la norme ANSI C ou POSIX appels système?
Vous devez vous connecter pour publier un commentaire.
Je ne peux pas penser à un moyen de le faire dans une croix-plate-forme, mais sur les systèmes GNU/Linux (et peut-être d'autres POSIX ceux, aussi), vous pouvez
freopen ("/dev/tty", "a", stdout)
. Est-ce que vous étiez en train de faire?Malheureusement, il ne semble pas être une bonne façon:
http://c-faq.com/stdio/undofreopen.html
La meilleure recommandation est de ne pas utiliser freopen dans cette circonstance.
Utilisation
fdopen()
etdup()
ainsi quefreopen()
.Je ne suis pas sûr de savoir si vous pouvez faire l'affectation de manière fiable ailleurs.
Douteux code qui fait réellement le travail
Le code ci-dessous travaillé sur Solaris 10 et MacOS X 10.6.2 - mais je ne suis pas sûr que c'est fiable. La structure de l'affectation peut ou peut ne pas fonctionner avec Linux glibc.
Vous ne pouvez pas dire que vous n'étiez pas prévenu — c'est jouer avec le feu!
Si vous êtes sur un système avec le
/dev/fd
système de fichiers, vous pouvez créer le nom du fichier implicite par le descripteur de fichier retourné à partir dedup()
avecsprintf(buffer, "/dev/fd/%d", old_stdout)
et ensuite utiliserfreopen()
avec ce nom. Ce serait beaucoup plus fiable que la cession utilisé dans le présent code.La meilleure solution soit de faire le code à utiliser des 'fprintf(fp, ...)" partout, ou de l'utilisation d'un couvercle de fonction qui vous permet de définir votre propre défaut pointeur de fichier:
mprintf.c
mprintf.h
Clairement, vous pouvez créer un mvprintf() et autres fonctions au besoin.
Exemple de l'utilisation de mprintf()
Alors, à la place du code d'origine, vous pouvez utiliser:
(Attention: le code non testé - un niveau de confiance de trop haut. Aussi, tout le code écrit en supposant que vous utilisez un compilateur C99, principalement parce que je déclarer des variables quand j'ai besoin d'eux, et non pas au début de la fonction.)
Attention:
Noter que si le programme original est invoqué comme
./original_program > file
ou./original_program | grep something
(avec redirigé sortie) ou s'il est exécuté à partir d'uncron
emploi, puis en ouvrant/dev/tty
n'est généralement pas approprié, comme un moyen de rouvrir la sortie standard, parce que le standard de sortie n'a pas été le terminal.Notez également que, si la redirection de la sortie standard est utilisé avant de bifurquer et execing un programme enfant et l'original de la sortie standard est réintégré dans la société mère, la séquence des opérations est faux. Vous devez fourche et ensuite ajuster les I/O de l'enfant (uniquement), sans modification de la mère I/O à tous.
error: incomplete type 'FILE' (aka 'struct __sFILE') is not assignable
FILE *
(les pointeurs de fichiers). Comment avez-vous modifier afin que votre version est l'affectation d'une complèteFILE
, qui est habituellement un type de structure, et qu'il est parfois incomplète, ce type de structure et par conséquent ne peuvent pas être affectés. (Exemple de fragment de vous rencontrer ce problème? Je ne pense pas que c'est lemprintf()
exemple. Si vous faites allusion à la douteuse exemple, ce que vous allez rencontrer est l'une des nombreuses raisons qu'il est plus que douteux. [...suite...]FILE
objet utilisé pour le contrôle d'un cours d'eau peut être importante; une copie d'unFILE
objet n'a pas besoin de servir à la place de l'original. Vous avez été averti que le fragment est douteuse; maintenant, vous savez pourquoi.En règle générale, vous ne pouvez pas. Vous avez fermé le fichier, ce qui peut avoir été pipe ou quoi que ce soit. Ce n'est pas reopenable. Vous avez enregistré
stdout
valeur, alors affecter certains fopen et puis fermez-le et copie de l'ancienne valeur de retour. Exemple:Mike Weller est proposée ci-dessous dans les commentaires que stdout peut ne pas toujours être accessible en écriture. Dans ce cas, quelque chose comme ça pourrait aider:
Un autre edit: si vous l'utilisez pour rediriger la sortie de l'enfant du processus comme votre commentaire ailleurs suggèrent, vous pouvez le rediriger après la fourche.
Sur Windows, vous pouvez ouvrir "CONOUT$".
C'est probablement ce qui ne fonctionne pas si la sortie standard est redirigée pour commencer.
Le code suivant (SwapIOB) est utilisé dans Testbenches que voulez stocker
le flux stdout pour la comparaison à un fichier de résultats.
Arrière-plan: le flux de Fichiers sont gérés à l'aide d'un _IOB structure qui est stocké dans un tableau de 20 _IOB entrées. Cela inclut les flux stdout. L'IOBs sont stockées dans un tableau. Lorsqu'un fichier est créé le code de l'application reçoit un pointeur vers un élément de ce tableau. Le code de l'application passe alors que le ptr pour le système d'exploitation pour le traitement des appels d'e/S. Ainsi, le système d'exploitation ne contient elle-même ou de s'appuyer sur ses propres pointeurs de l'application de l'IOB.
Exigence: Lors de l'exécution d'un testbench la sortie standard (stdout) les messages émis par une application doit être re-dirigé vers un fichier. Cependant, après le module de test est terminée, la sortie standard les messages doivent être de nouveau redirigé vers la console.
Cette routine a été testé et est actuellement utilisé sur Windows XP/Pro système.
Le code de l'Application utilise SwapIOB() similaire à:
sizeof(struct _iobuf)
au lieu desizeof(FILE)
?