How to disable printf function?
Asked Answered
M

5

7

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?

Maureen answered 11/12, 2012 at 9:12 Comment(3)
Where are you going with all this? Is there some practical end you're pursuing, or is this purely an academic exercise?Augur
Preprocessing comes before compilation. It doesn't matter whether it's in a function or not. That function is empty to the compiler.Neisa
Rule of thumb: every printf format string should end with \n, or else you should call fflush after the printfFusee
F
10

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

Ferro answered 11/12, 2012 at 9:20 Comment(9)
Could u pls elaborate more?Maureen
There's no guarantee that this will work, or even that it will compile---close and STDOUT_FILENO are Unix specific.Precautious
there is also fclose(stdout);Ferro
@MohamedKALLEL That's guaranteed to work. On the other hand, it makes it impossible to restore the original output later.Precautious
@MohamedKALLEL: If we want to reopen then how can we do that... Do we nned to use fopen()..?Maureen
@RasmiRanjanNayak It depends on your system (Windows/Linux..) and the output device (console, screen ). example if you are using linux and console than to reopn it you have to do in this way stdout = fopen("/dev/tty","w");.Ferro
I am using Windows and my output device is both in consloe and screenMaureen
@RasmiRanjanNayak I could not help you for windows. This could be another question. BTW I see an answer in this topic wich suggest to you to redirect the output to a file and then get back to the stdout. ths could be also an alternate solution for you. and you can add to this solution the remove of file when you get back to the stdoutFerro
@RasmiRanjanNayak: It will be good fro you If you update this topic with the results you foundFerro
F
5

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.

Freiburg answered 11/12, 2012 at 9:15 Comment(6)
@KarthikT: Can I write an inline function which can disable that for me at run time?Maureen
@RasmiRanjanNayak as I said, you cannot use macros for any sort of selective control, you cannot disable at some places but enable at other places, especially not with a function, since macros dont obey function rules/syntax. You would be better off seeing if Mohamed KALLEL's solution works if you want localized control.Freiburg
Note too that doing this is undefined behavior, at least according to the standard. (I can't imagine it actually causing a problem, but you never know.)Precautious
@JamesKanze could you elabourate?Freiburg
@KarthikT What's to elaborate? You're not allowed to (re)define functions in the standard library; other standard library functions may use them (including in a template or an inline function). It's probably without risk, however, because I can't imagine anything in the standard library using printf.Precautious
@JamesKanze I see your point, as this similar post points out as well, if this were defined before <stdio.h> were included, results would be chaosFreiburg
A
2

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.

Ardra answered 11/12, 2012 at 9:27 Comment(4)
I updated the answer. Note that this is an implementation-specific solution.Ardra
This would be easy if he were using std::cout, but how can you do this from within the program for printf?Precautious
@JamesKanze My example uses printf. I cannot emphasise enough this is an implementation-specific solution, so take it with a pinch of salt. :)Ardra
I am not very comfortable providing implementation-specific solutions, but I suppose there's no harm in mentioning it at least. For all you know, the OP's program may never be used outside a specific environment.Ardra
W
0

in my similar case "printf(fmt, ...) (0)" did not compile ,but it worked like this:

#if RELEASE == 1  // no printf at release
 int printf(const char *__restrict, ...)  {  return 0; }
#endif 
Wellturned answered 8/6, 2023 at 22:23 Comment(0)
R
0

Best solution out of all should be the following:

#pragma GCC poison printf        // which disables with gcc

poisoning technique is the cleanest and most viable solution out of all of the solutions in here.
For your compiler you will have the same thing that can be achieved but most used compiler is GCC so I gave the example using that.

Rama answered 30/1, 2024 at 12:58 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.