tags:

views:

102

answers:

4

I have a function call in a program that I'm maintaining has 28 arguments for a printf call. It's printing a lot of data in a CSV file. I have problems following finding where what goes and I have some mismatches in the parameters types. I enabled -Wall in gcc and I get warnings like:

n.c:495: warning: int format, pointer arg (arg 15)
n.c:495: warning: format argument is not a pointer (arg 16)
n.c:495: warning: double format, pointer arg (arg 23)

The function is like this:

fprintf (ConvFilePtr, "\"FORMAT3\"%s%04d%s%04d%s%s%s%d%s%c%s%d%c%s%s%s%s%s%s%s%11.lf%s%11.lf%s%11.lf%s%d\n", some_28_arguments_go_here);

I would like to know if there is a vim plugin that highlights the printf format specifier when i go with the cursor over a variable.

Other solutions? How to better reformat the code to make it more readable?

+3  A: 

split the format string and the call into several fprintf calls

Gregory Pakosz
This fprintf call in a loop. Other ways that wouldn't affect performance?
Costi
The performance impact would be negligible.
torak
@Costi: if you have bug/error you should worry about fixing that before you worry about performance. You can always recombine the calls after you figure it out.
nategoose
+2  A: 

From the warning you know the argument number in question, e.g. 15. In normal mode:

  • Go to the start of the line.
  • Type '15f%' to find the 15. occurrence of '%' inside the format string.
fgm
Thanks I used that + breaking printf into multiple lines, escaping the newline with \, and then putting them back together afterwards. I should note that 15 is the argument the 13th printed variable. The first two variables in fprintf are the file handle and the format string.
Costi
+1  A: 

You can split it up and keeping only one fprintfcall. I do often something like that:

fprintf (ConvFilePtr,"\"FORMAT3"
                     "%s"
                     "%04d%s"
                     "%04d"
                     "%s%s%s"
                     "%d"
                     "%s%c"
                     "%s%d%d"
                     "%c%s"
                     "%s%s%s"
                     "%s%s"
                     "%s%11.lf"
                     "%s%11.lf"
                     "%s%11.lf"
                     "%s%d\n", str1,
                               int1, str2,
                               int2,
                               etc...);

You get the point, you still have only one call (which is important as I/O is often order of magnitude slower than pushing varaibles on the stack), and you can arrange your variables so that they are grouped logically, making it easier to spot a problem.

tristopia
+5  A: 

Not sure I know a good vim trick off the top of my head, but I know a good C macro to make it a little easier:

#define last( f, a, ft, ... ) f ft, a, __VA_ARGS__
#define pair( f, a, ftat ) last( f, a, ftat )
// ...
printf( pair( "%s", "hello",
        pair( "%s", "world",
        pair( "%c", '\n',
        last( "%4x", 0xfeed,
              "%f\n", 3.14159 )))));
rampion
This is very nifty, but I'm not the only programmer on the project and I better keep it as close to "familiar C" as possible.
Costi
+1 wow, using the preprocessor as a lisp interpreter ;-) It's really a pity I can not use __VA_ARGS__ macros on my project (I can use some C99 constructs but Oracle Pro*C preprocessor does not know about variable args macros).
tristopia