How to Right Pad a Hexadecimal in C - c

So I know (after a lot of confusing google searching) that to right pad a string, one would use fprintf("%-10s", string), or something like that to pad with spaces up to 10 length.
So I have two questions:
I know that left-pad is similar, but what would the syntax for it be? (I'm sorry, I did google, but got confused by conflicting answers...)
And more importantly, how would I right-pad a hexidecimal? Say I have an int i want to convert to hex with %02X. Could I still use %-1002X ? Wouldn't that screw it up?

printf conversion formats allow you to either left-pad or right-pad the conversion result, but not both at the same time. Right-padding an integer conversion is the same as right padding anything else - just specify the negative field width, like %-10x. You cannot both left-pad and right-pad at the same time: you can only specify only one width in the format. Your original %02x is already explicitly using left padding. You cannot add right-padding on top of that.
However, it looks like the purpose of your %02x is to produce zero-padded output that has at least 2 digits. This can be achieved through using precision component of the format instead of using width. Format like %.2x will also successfully produce 2 digit hex conversion.
By using precision instead of width, you leave width available for padding purposes. E.g. format like %-10.2x will produce 2-digit conversions (padded with zeros) that are right padded with spaces to 10 characters.

try
printf("Hex %8.8x", someInt);
Or use fprintf(), sprintf(), snprintf(), whatever... If you're starting with a hex string, use snprintf() with the %-8s format specifier to capture the translation into a char * buffer, and then use a for loop or to substitute spaces with '0' characters.

Related

How can I print "%#s" where # represent the spaces, but this spaces amount have to change depending on the input? [duplicate]

In order to determine the size of the column in C language we use %<number>d.
For instance, I can type %3d and it will give me a column of width=3.
My problem is that my number after the % is a variable that I receive, so I need something like %xd (where x is the integer variable I received sometime before in my program).
But it's not working.
Is there any other way to do this?
You can do this as follows:
printf("%*d", width, value);
From Lee's comment:
You can also use a * for the precision:
printf("%*.*f", width, precision, value);
Note that both width and precision must have type int as expected by printf for the * arguments, type size_t is inappropriate as it may have a different size and representation on the target platform.
Just for completeness, wanted to mention that with POSIX-compliant versions of printf() you can also put the actual field width (or precision) value somewhere else in the parameter list and refer to it using the 1-based parameter number followed by a dollar sign:
A field width or precision, or both, may be indicated by an asterisk ‘∗’ or an asterisk followed by one or more decimal digits and a ‘$’ instead of a digit string. In this case, an int argument supplies the field width or precision. A negative field width is treated as a left adjustment flag followed by a positive field width; a negative precision is treated as though it were missing. If a single format directive mixes positional (nn$) and non-positional arguments, the results are undefined.
E.g., printf ( "%1$*d", width, value );

Variable affected by type conversion

I have always thought that when a variable is typecast, a copy of it results and any changes affect that temporary variable. But, the screenshot below indicates otherwise. Apparently, the original variable is what changes. Why? I am curious because I have never seen anything similar.
sprintf nul-terminates the string it outputs into the provided buffer. As the %010lu format specifier requests a number padded to be at least 10 digits long, you are consistently overflowing crc_buf and triggering UB. In your specific case, the least significant byte of crc gets trampled.
Make crc_buf 11 characters or more, and use snprintf instead of sprintf to catch this class of errors. For maximal portability, you could also use the PRIu32 format macro instead of casting:
snprintf(crc_buf, sizeof crc_buf, "%10" PRIu32, crc);

About printf format string in C

Let's take the following program:
#include <stdio.h>
int main()
{
long t =57 ;
printf("[%+03ld]", t);
}
and it's output:
[+57]
I am somehow confused: I told him to pad the output to width 3 (03ld), with zeroes, however it seems that if I force the output to put a plus sign before the number (+) it will not add the required zeroes if the length of the number is already 2 digits (as in 57). For numbers <10 it pads with 1 zero.
From http://www.cplusplus.com/reference/cstdio/printf/
(0) -> Left-pads the number with zeroes (0) instead of spaces when padding is specified (see width sub-specifier).
(+) -> Forces to preceed the result with a plus or minus sign (+ or -) even for positive numbers. By default, only negative numbers are preceded with a - sign.
(width) -> Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.
So I just need a clarification ... The (width) specifier from the quote above refers to the full length of the output string (ie: the characters that will be printed) controlled by this format specifier ("%+03ld") or the full length of the characters of the number that is going to be printed?
Yes, the width specifier refers to the width of the entire formatted result, +57 in your case. This makes it useful for printing columnar text for easy reading on screen (important if you're using C to write an old-school text utility!).
C standard is rather precise that converted value is taken a whole. From C11 §7.21.6/2 (emphasis mine):
The fprintf function writes output to the stream pointed to by stream,
under control of the string pointed to by format that specifies how
subsequent arguments are converted for output.
along with §7.21.6/4:
An optional minimum field width. If the converted value has fewer
characters than the field width, it is padded with spaces (by default)
on the left (or right, if the left adjustment flag, described later,
has been given) to the field width. The field width
takes the form of an asterisk * (described later) or a nonnegative decimal integer.
As you quoted "Minimum number of characters to be printed.", so "+" is just another character for printf. Btw the zeros "0" are just characters aswell and have nothing to do with numbers. It could be any character.
Yes, the field width refers to the complete, converted value including decimal dots, signs etc.
You asked for a 3 characters length format and get 3 characters +57. If you want the 0 to be present, just use printf("[%+04ld]", t); and you'll get +057.

Meaning of "." in printf

I was just reading the classic K&R and encountered the following syntax:
printf("%.*s",max,s);
What is the meaning of "." here?When I don't apply a "." here,then whole string is printed,but when we don't apply a "." ,atmost max characters are printed.I will be really thankful if anyone could explain this.
In %.*s, the .* limits the number of bytes that will be written. If this were written with a numeral included, such as %.34s, then the numeral would be the limit. When an asterisk is used, the limit is taken from the corresponding argument to printf.
From C 2011 (N1570) 7.21.6.1 4, describing conversion specifications for fprintf et al:
An optional precision that gives … the maximum number of bytes to be written for s conversions. The precision takes the form of a period (.) followed either by an asterisk * (described later) or by an optional decimal integer; if only the period is specified, the precision is taken as zero.
It specifies the "Character String Maximum field width"
The precision within a string format specifies the maximum field width:
%2.6s
specifies a minimum width of 2 and a maximum width of 6 characters. If the string is greater than 6 characters, it will be truncated.
A printf format string allows specifying width and precision.
Width, such as %25s, tells printf to pad the string to the width of 25 characters, inserting spaces before the string. (If the string is wider than 25 characters, it is still printed in its entirety.)
A "precision" applied to a string format, such as %.25s, limits the length of the printed string to 25 characters. A string of 3 characters will be printed fully (with no padding), and a string of 30 characters will be missing its last five characters.
%.*s avoids hardcoding the precision in the format, specifying it instead as an integer argument to printf, in your case max.
First of all, K&R is the original implementation of C, which is different from the current specification. If you want specific information about K&R C, then consult specific documentation.
From the current C standard:
An optional precision that gives (...) the maximum number of bytes to be written for s conversions. The precision takes the form of a period (.) followed either by an asterisk * (described later) or by an optional decimal integer.
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
Similar documentation is available everywhere online for multiple standards or implementations:
glibc
http://www.gnu.org/software/libc/manual/html_node/Output-Conversion-Syntax.html#Output-Conversion-Syntax
POSIX
http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html
Microsoft C runtime
http://msdn.microsoft.com/en-us/library/56e442dc.aspx
Dot has different meaning with different format strings . If you use a.b with %f , then b gives length . a gives number of decimal points . if you use a.b with %s , a will give minimum length of the string . whereas b gives maximum length of the string that will be printed .
It actually print the character in limited number and commanded format based on the function passed to printf,in this case it should print the specific of "max"

Scanf syntax - %6d and %-6d and %0d

What are the differences between using scanf with the following format specifiers, when the input being scanned is 123456 versus when it's 123:
%6d
%-6d
%0d
What are the differences in the output?
I ended up just trying it with GCC 4.3.4, and got the following:
%6d: Works fine; only reads 6 characters (so if you try to read 123456789 it will only read 123456)
%-6d: Emits the warning:
warning: unknown conversion type character '-' in format
Doesn't read anything, and the int being written to is unmodified
%0d: Emits the warning:
warning: zero width in scanf format
Reads as though there were no width in the format specifier (%d)
I haven't checked the spec to see if those results are mandated or just how GCC handles it (EDIT: AndreyT found it)
The %-6d is an invalid format specifier. There are no format specifiers with - in them in scanf.
In %6d the 6 part is called maximum field width. It works with all format specifiers (not only with d) and specifies the maximum number of characters to read before any format-specific conversion is performed. For example, if input sequence is 1234567, then %3d will read and convert 123 and %6d will read and convert 123456.
The %0d is an invalid format specifier. Maximum field width in scanf must be a non-zero integer (see 7.19.6.2/3 in the language specification).
So, that leaves us with %6d as the only meaningful format specifier among the three you provided. Under these circumstances the question about differences in output (in results?) makes little sense.
EDIT: One can probably argue that in %-6d the -6 part is the maximum field width, which satisfies the standard requirement of being non-zero decimal integer. However, in C language terminology a decimal integer as a lexical element is a sequence of digits and digits only. It is not allowed to include a sign. I.e. neither -6 nor +6 are decimal integers. Every time you use -6 or +6 as integers in your program it is actually unary - and + operator lexeme followed by decimal integer lexeme. So, since the specification of scanf requires a non-zero decimal integer as maximum field width, it must be a sign-less integer.
Here's what I think will happen: %6d will get you the first 6 digits of the number, %-6d will probably not work as you expect, since - is more of an output alignment specifier. %0d would mean you want only 0 characters, which would probably not work as expected.
Both %-6d and %0d are invalid conversion specifications for scanf, so the behavior for those cases will be undefined. See the language standard, § 7.19.6.2, ¶ 3.
I'll assume, like Arkadiy, that you really meant printf-style formatting, since you refer to "output". I'll also assume that you're using C (as the tag suggests).
If you run:
printf("%6d %-6d %0d", num1, num2);
...you'll end up with compiler errors (or, worse still, runtime bugs), as you haven't supplied enough arguments for three formats.
I've a feeling that that's not what you were asking, though. Let's assume that you actually run:
// (I've added some extra stuff to show how the formatting works.)
printf("'%6d'/'%-6d'/'%0d'", num2, num2, num2);
...you'll get:
' 123'/'123 '/'123'
Normally, if the field width (6 in this case) is wide enough, numbers are right-aligned, space-padded. If you put a '-' before the field width, they will be right-aligned, space-padded.
The subtlety here is in the "%0d" format. You might think you're specifying a zero-width field...and you'd be wrong. The first thing after the '%' is an option flag, and '0' is a valid flag. It means, "If the field width is wider than the content, left-pad with zeroes." In this case, you haven't supplied a field width (the '0' is a flag, remember?), so the '0' flag has no effect: the field will be as wide as the content requires.
There's an even worse subtlety, though. If you specified "%-06d", you'd get right-padding with zeroes, right? Um, no. The '-' flag overrides the '0' flag, whichever order they're supplied. You'd get '123 '.

Resources