Thread: make a function like printf/sprintf

  1. #1
    Registered User
    Join Date
    Feb 2006
    Posts
    14

    Arrow make a function like printf/sprintf

    Hi, I am writing a small function that logs a string passed to it to a log file. Right now
    it looks like this:
    Code:
    int logData(char* logMessage);
    
    int logData(char* logMessage) {
        FILE *pFile = NULL;   
        char logMsg[1024];    
    
          /* Create a new file we can write */
          pFile = fopen(DEBUGFILE, "a+");
          if ( pFile == NULL )
          {
              syslog(LOG_ERR,"Unable to open DEBUGFILE for reading");
              return 1; 
          }
    
          fprintf(pFile, %s\n", logMessage);
          fclose(pFile); /* Close the file */
    
          return 0;
    }
    But in order to have a line like this ("We are in %s on line %s", __FUNCTION__, __LINE__);
    I have to do this:
    Code:
        sprintf(logMsg, "We are in %s on line %s", __FUNCTION__, __LINE__);
        logData(logMsg);
    I want to do this:
    Code:
        logData("We are in %s on line %s", __FUNCTION__, __LINE__);
    Sorry if this is basic, but I am still a beginner. Thanks!

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Registered User
    Join Date
    Feb 2006
    Posts
    14
    Quote Originally Posted by Dave_Sinkula
    hmm, I looked through but other than usage, I didn't see much, please let me know if I am mistaken. Also links are dead. Thanks.

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    The example wasn't of use?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    [threadjack]I decided to take my first stab at variadic macros. Am I screwing anything up here?
    Code:
    #include <stdio.h>
    #include <stdarg.h>
    #include <time.h>
    
    void mylog(const char *function, int line, const char *format, ...)
    {
       static const char filename[] = "file.txt";
       FILE *file = fopen(filename, "a+");
       if ( file )
       {
          va_list args;
          time_t now;
          if ( time(&now) != (time_t)(-1) )
          {
             struct tm *local = localtime(&now);
             if ( local )
             {
                char timestamp[20];
                if ( strftime(timestamp, sizeof timestamp, "%Y-%m-%d %X", local) )
                {
                   fprintf(file, "%s : ", timestamp);
                }
             }
          }
          fprintf(file, "[in function '%s', line %d] ", function, line);
          va_start(args, format);
          vfprintf(file, format, args);
          va_end(args);
          fputc('\n', file);
          fclose(file);
       }
       else
       {
          perror(filename);
       }
    }
    
    #ifndef NDEBUG
    #define logData(...) mylog(__func__, __LINE__, __VA_ARGS__)
    #else
    #define logData(...)
    #endif
    
    int main(void)
    {
       int i = 42;
       double d = 123.456;
       logData("%s", "ok");
       /* ... */
       logData("i = %d, d = %g", i, d);
       return 0;
    }
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  6. #6
    Registered User
    Join Date
    Feb 2006
    Posts
    14
    can anyone tell me why this isn't working?
    Code:
    #include <stdio.h>
    #include <stdarg.h>
    #include <time.h>
    
    void myLogger(int log_level, char* logMessage, const char *format, ...)
    {
        FILE *file = fopen("c:\file.txt", "a+");
        va_list args;
        time_t now;
        int debugValue = 1;
        
        if ( time(&now) != (time_t)(-1) )
        {
            struct tm *local = localtime(&now);
            if ( local )
            {
                char timestamp[20];
                if ( strftime(timestamp, sizeof timestamp, "%Y-%m-%d %X", local) )
                {
                    fprintf(file, "%s : ", timestamp);
                }
            }
        }
        
        switch (log_level)
        {
            case 0:
                if ( 0 < debugValue )
                {
                    fprintf(file, "%s, we got %d as debug_level ", debugValue, logMessage);
                    va_start(args, format);
                    vfprintf(file, format, args);
                    va_end(args);
                    fputc('\n', file);
                    fclose(file);
                }
                break;
    
            default:
                if ( log_level <= debugValue )
                {
                    fprintf(file, "%s, we got %d as debug_level ", debugValue, logMessage);
                    va_start(args, format);
                    vfprintf(file, format, args);
                    va_end(args);
                    fputc('\n', file);
                    fclose(file);
                }
                break;
        }
    }
    
    int main(void)
    {
       int i = 42;
       double d = 123.456;
    
       //myLogger(1, "This is a test: %d", debugValue);
       myLogger(1,"%s", "ok");
       myLogger(1,"i = %d, d = %g", i, d);
        
        return 0;
    }

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > FILE *file = fopen("c:\file.txt", "a+");
    Could it be that you're missing another \, as in c:\\file.txt

    Explain "isn't working" a bit better next time
    - does it compile, does it run, does it produce any answers or crash, how does that differ from what you expect?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
    myLogger(1,"%s", "ok");
       myLogger(1,"i = %d, d = %g", i, d);
    Not enough arguments - the second argument should me message, before format
    Code:
        FILE *file = fopen("c:\file.txt", "a+");
    You should check pointer before use, You sould write "c:\\file.txt"

    Code:
     fprintf(file, "%s, we got %d as debug_level ", debugValue, logMessage);
    Wrong order of arguments not complient with the format
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    Registered User
    Join Date
    Feb 2006
    Posts
    14
    Got it to work like this:

    Code:
    #include <stdio.h>
    #include <stdarg.h>
    #include <time.h>
    
    void myLogger(int log_level, const char *format, ...)
    {
        static const char filename[] = "c:\\test.txt";
        FILE *file = fopen(filename, "a+");
        va_list args;
        time_t now;
        int debugValue = 1;
        
        if ( time(&now) != (time_t)(-1) )
        {
            struct tm *local = localtime(&now);
            if ( local )
            {
                char timestamp[20];
                if ( strftime(timestamp, sizeof timestamp, "%Y-%m-%d %X", local) )
                {
                    fprintf(file, "%s : ", timestamp);
                }
            }
        }
        
        switch (log_level)
        {
            case 0:
                if ( 0 < debugValue )
                {
                    fprintf(file, "we got %d as debug_level", debugValue);
                    va_start(args, format);
                    vfprintf(file, format, args);
                    va_end(args);
                    fputc('\n', file);
                    fclose(file);
                }
                break;
    
            default:
                if ( log_level <= debugValue )
                {
                    fprintf(file, "we got %d as debug_level", debugValue);
                    va_start(args, format);
                    vfprintf(file, format, args);
                    va_end(args);
                    fputc('\n', file);
                    fclose(file);
                }
                break;
        }
    }
    
    int main(void)
    {
       int i = 42;
       double d = 123.456;
    
       myLogger(1,"i = %d, d = %g", i, d);
       return 0;
    }

  10. #10
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    you still not checking return value of fopen
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  11. #11
    Registered User
    Join Date
    Feb 2006
    Posts
    14
    Quote Originally Posted by vart
    you still not checking return value of fopen
    Right, I meant I got the function working.. I will add checks after.

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by fredanthony
    Right, I meant I got the function working.. I will add checks after.
    Leaving it in would have likely avoided this question:
    Quote Originally Posted by fredanthony
    can anyone tell me why this isn't working?
    Code:
    void mylog(const char *function, int line, const char *format, ...)
    {
       static const char filename[] = "c:\file.txt";
       FILE *file = fopen(filename, "a+");
       if ( file )
       {
          /* ... */
          fclose(file);
       }
       else
       {
          perror(filename);
       }
    }
    Code:
    c:ile.txt: Invalid argument
    The most useful place for safety checks is before you "get it working". Especially since, all too often, "working code" is not touched because it is "working".
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  3. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  4. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  5. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM