how to make format in {} form?

I'm trying to change the format into a curly brace form so I can call the first argument by {0} and a second argument by {1} in string form.

void write( const char * format, ... )
{
va_list args;
va_start (args, format);
vprintf (format, args);
va_end (args);
}

int main ()
{

write ("Call with %d variable argument.\n",1);
write ("Call with %d variable.\n",2);

return 0;
}
If I understand you correctly, that really can't be done without some heavy meta-template programming. Some libraries exist, but I'm not so sure you are doing what you want to do the right way.

What exactly is your end goal?

C2. Functions with variable number of arguments
Write a function write with variable number of arguments that takes a string first argument followed by any number of arguments of type double and prints on the screen a string formatted by the rules described below. The first argument may contain formats in curly braces of the form {index[:specifier]}, where the square brackets show optional parts (this is :specifier may be missing), and index is the sequence number of an argument of type double (starting from sequence number 0).
Rules for formatting: In the printed string the curly brackets and their content will be replaced by the argument with the given index, formatted according to the given format specifier. If the format specifier is missing, the argument will be printed with its default format. For example:
write("The number {0} is greater than {1}.", 5, -3);
will print
The number 5 is greater than -3.
write("There are no format specifiers here.");
will print
There are no format specifiers here.


The format specifiers and their meanings are listed in the following table



Specifier

Meaning

Format

Output for 1.62

Output for 2.0

none

default

{0}

1.62

2

c

currency

{0:c}

$1.62

$2.00

e

scientific

{0:e}

1.620000e+000

2.000000e+000

f

fixed point

{0:f}

1.620000

2.000000

i

round to int

{0:i}

2

2

Note: an overview of the C++ ios flags is available at http://www.cplusplus.com/reference/ios/ios_base/fmtflags/
Limitations: You may limit the maximum number of arguments your function can process to a certain value, for example 10.

[25 points]

Extra Credit Extensions (3 points each):

• add an optional alignment specification in the format , e.g., make the format of the form {index[,alignment][:specifier]}, where alignment is an integer specifying the width of the field in which the corresponding argument will be printed. If alignment is positive, align to the right, if it is negative, align to the left.
• Accept an optional integer after the specifier letter, specifying the required precision in the output. For example, {0:f2} will print the number 1.6234 as 1.62, but {0:f5} will print it as 1.62340.
Sorry for the weird format. I copy pasted from my iPhone, this is a project due tomorrow for my summer course. I've spent the last 2 days trying to figure this out!
Ah, the curly braces are in the format string.

Typically, format specifiers are of the form "%f" -- a percent sign delineates the format specifier.
In your case, the format specifier is delineated by curly braces: "{0}".

The tricky part is that your function can do something like this:

write( "swapped: {1}, {0}\n", 7, 9 );
and get
swapped: 9, 7


The very first thing you should do is scan your format string to see how many arguments there are. In the example I just gave, the largest number in {curly braces} is 1, so there are two double arguments.

Next, since you are using C++, and you know all the arguments are (supposed to be) doubles, create a std::vector and get all the arguments into that vector. (This is where you'll use the va_list:

1
2
3
4
5
6
std::vector<double> args( number_of_args );
va_list vargs;
va_start( vargs, format );
for (auto& arg: args)
  arg = va_arg( vargs, double );
va_end( vargs );

Now you have an indexable list of the argument values.

The last thing to do is scan through your format string (again), printing every character that isn't in {curly braces}. So:

write( "I have {0:i} hamburgers at {1:c} each.\n", 4, 2.99 );

would print in pieces:
    "I have "           (printed character-by-character)
    "4"                 
(formatted)
    " hamburgers at "   
(printed character-by-character)
    "$", "2.99"         
(formatted)
    " each.\n"          
(printed character-by-character)

The code to print formatted stuff is not too difficult. For example, for the fourth part (currency):

std::cout << "$" << std::fixed << std::setprecision( 2 ) << args[ n ];

You'll need a switch statement to choose from among the specifiers ('c', 'e', 'f', and 'i').

Don't worry about the extra credit until you get everything else working. Once you do that, the extra credit is pretty easy to add, but until then, don't.

Hope this helps.
Topic archived. No new replies allowed.