可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have three files as below
Test.cpp
void helloworld() { disable pf; pf.Disable(); printf("No statement \n"); } int main() { disable dis; helloworld(); printf("Hello World"); system("pause"); return 0; }
disable.cpp
#include "StdAfx.h" #include "disable.h" disable::disable(void) {#define printf(fmt, ...) (0)} disable::~disable(void) {} void disable::Disable() { #define printf(fmt, ...) (0) }
disable.h
#pragma once class disable { public: disable(void); ~disable(void); void Disable(); };
After executing, I am getting output as No Statement
Hello World
. But I would like to disable these two printf statements
by calling Disable function
and disable constructor
.. Please help me why it is not working and how to solve this. Please help.
But things works fine if I do like
main() { #define printf(fmt, ...) (0) printf("Hello World"); }
But why not if I am calling it from a function?
回答1:
A macro doesnt obey scope rules, c++ syntax rules, or anything. It is a text replacement engine, only.
When you say #define printf(fmt, ...) (0)
in disable.cpp
, it is defined ONLY in disable.cpp. If you were to write that in disable.h
, it would be defined in all files that include from disable.h
.
The only way to control a macro is with a macro (#if and #ifdef and their ilk). So what you want to to can be achieved by the following.
#define DISABLE_PRINTF #ifdef DISABLE_PRINTF #define printf(fmt, ...) (0) #endif
But this will be a global disable and can only be undone by commenting out the first #define
and recompiling the code. There is no way to do selective/scope based control of disabling using macros.
Edit: Instead of redefining printf
itself, it is recommended to write a wrapper which is defined in terms of printf
for this purpose.
回答2:
You can disable the printf ouput by:
close(STDOUT_FILENO);
or you can use also:
fclose(stdout);
This will disable all output to the stdout
Example:
#include<stdio.h> #include<stdlib.h> int main(){ printf ("This message will be displayed\n"); fclose(stdout); printf ("This message will not be displayed\n"); // to reopen the stdout, this is another question return 0; }
Note
If you are using sockets in your program, than you have to be careful here because the close of stout will cause the redirection of the output to the sockets
回答3:
On implementations that support it, you could redirect the stdout
buffer to "disable" the console, and restore it when you want to "enable" it again. Here's a code sample which works (at least) on Linux with gcc.
NOTE This is a implementation-specific solution and uses dup()
and dup2()
from unistd.h
. It is not guaranteed by the standard to work everywhere.
#include <cstdio> #include <unistd.h> int main() { printf("Hello world.\n"); fpos_t pos; fgetpos(stdout, &pos); // save the position in the file stream int fd = dup(fileno(stdout)); // use the dup() function to create a copy of stdout freopen("dummy.txt", "w", stdout); // redirect stdout printf("Hello nobody.\n"); // this is not printed to the "usual" stdout fflush(stdout); dup2(fd, fileno(stdout)); // restore the stdout close(fd); clearerr(stdout); fsetpos(stdout, &pos); // move to the correct position printf("Hello world again.\n"); // this is printed back to the "usual" stdout }
You could put that logic into enable()
and disable()
functions. Let me emphasise, this is an implementation-specific solution. I am not aware of any standard-conforming solution to restore the standard streams after they have been redirected.