Addition using printf in C [duplicate] - c

This question already has answers here:
Adding two numbers without using operators
(3 answers)
Closed 9 years ago.
on net: using printf to add two numbers(without using any operator) like following:
main()
{
printf("Summ = %d",add(10,20))
return 0;
}
int add(int x,int y)
{
return printf("%*d%*d",x,' ',y,' ');
}
Could anyone please explain, how this works:
return printf("%*d%*d",x,' ',y,' ');
Note: This fails when i call "sum" like following:
sum(1,1) or sum(3,-1)

There are two central concepts here:
printf() returns the number of characters printed.
The %*d format specifier causes printf() to read two integers from its arguments, and use the first to set the field width used to format the second (as a decimal number).
So in effect the values being added are used as field widths, and printf() then returns the sum.
I'm not sure about the actual d formatting of the space character, at the moment. That looks weird, I would have gone with an empty string instead:
static int sum(unsigned int a, unsigned int b)
{
return printf("%*s%*s", a, "", b, "");
}
int main(void)
{
unsigned int a = 13, b = 6;
int apb = sum(a, b);
printf("%d + %d = %d?\n", a, b, apb);
return 0;
}
The above works and properly computes the sum as 19.

printf returns the number of printed characters.
Here, it is used in the add function to generate a string only composed of 10 + 20 spaces, by using the format string.
So the printf in the add function will return 30.
Then, this result is simply printed with printf (his main purpose).
Note: it might be evident, but this printf usage has to be avoided. It's very dirty as it generates useless outputs. Imagine: add(10000,10000)...

First, printf returns the number of characters it prints.
Second, in the format specifier %*d, * means the minimum number of characters to be printed, but the width is not from the format string itself, but from the additional argument.
With all together, the job is done, but it won't work well on small numbers like 1 because of %d in the format specifier, a better solution could be :
("%*c%*c", a, ' ', b,' ');

Related

How to print a char repeatedly using format specifier instead of loop? [duplicate]

This question already has answers here:
How to repeat a char using printf?
(12 answers)
Closed 2 years ago.
I want to print a char '*' repeatedly where I give the no. of times the asterisk should be repeated.
Example: count = 20 and I want to print ******************** using printf() and format specifiers.
There is certainly no way to achieve that using only format specifier. You could hide your loop in a macro maybe but you'll definitely need a loop somewhere.
You cannot do that with standard format specifiers provided by printf(). However, there's a hacky solution (assuming the maximum padding length is reasonable), if you are willing to waste some space to store a filler string in your program.
#include <stdio.h>
int main(void) {
const char *fill = "********************"; // 20 chars
printf("%.*s\n", 10, fill);
printf("%.*s\n", 15, fill);
int n = 20;
printf("%.*s\n", n, fill);
return 0;
}
This works using .* to provide the maximum length of the string to print as first parameter.
Output:
**********
***************
********************
NOTE: you will only get up to strlen(fill) characters of padding (20 in the above example), anything more and printf will stop at the \0 terminator of fill.
I hope this is what you are looking for:
#include <stdio.h>
int main()
{
printf("%.*s", 20, "********************************");;
return 0;
}

Weird result from random character generator in C

I am trying to write a program in C that spits out random characters. Following instructions I found here, I wrote this program.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srandom((unsigned) time(NULL));
printf("Tests various aspects of random\n");
char misc;
int num, index;
printf("Enter number of chars: ");
scanf("%d", &num);
printf("\n");
for (int i = 0; i < num; i++) {
index = random() % 26;
misc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[index];
printf("%d:%s\n", index, &misc);
}
}
However, it doesn't behave as I expect. When entering a small number of characters for it to generate, like 10, it makes the expected output.
My expected output is a set of
rand_int:char
pairs printed to the screen.
Here is an example of normal operation
Tests various aspects of random
Enter number of chars:
7:H
4:E
23:X
2:C
4:E
17:R
22:W
11:L
9:J
4:E
However, if I input a large value such as 100, it outputs very strange things like:
Tests various aspects of random
Enter number of chars:
18:Sd
3:Dd
21:Vd
10:Kd
19:Td
19:Td
14:Od
7:Hd
15:Pd
22:Wd
24:Yd
22:Wd
12:Md
[rest omitted for brevity...]
So the question is, why does it behave this way?
What might be a better approach to avoid this?
The comments made by Jabberwocky and Federico klez Culloca got it right.
I was trying to print the character as a string. This was wrong and did weird things.
I needed to use:
printf("%d:%c\n", index, misc);
instead of
printf("%d:%s\n", index, &misc);
All is very simple. The program has undefined behavior. You are using the format string %s that is used to output strings.
printf("%d:%s\n", index, &misc);
However the variable misc is not a character array that contains a string. It is just a single character. So the function printf outputs all characters beyond the variable misc until a zero-terminating character is encountered.
And it seems that the variable num is allocated next to the variable misc. So the printf call outputs also bytes of the variable num that contains the value 100. If to output this value stored in a byte as an ASCII character then you will get the character 'd'.
Here is a demonstrative program.
#include <stdio.h>
int main(void)
{
char c = 100;
putchar( c );
putchar( '\n' );
return 0;
}
Its output is
d
Instead of the format %s use the format %c in the printf call. For example
printf("%d:%c\n", index, misc);

Confusion regarding a printf statement

So I was running this code
#include<stdio.h>
int add(int x, int y)
{
return printf("%*c%*c",x ,' ',y,' ');
}
int main()
{
printf("Sum = %d", add(3,4));
return 0;
}
And can't seem to understand how does the following statement works
return printf("%*c%*c",x ,' ',y,' ');
So I tried writing a simple code
int x=3;
printf("%*c",x);
and I got a weird special character (some spaces before it) as output
printf("%*c",x,' ');
I am getting no output. I have no idea what is happening? Please Help. Thank you.
This code
int x=3;
printf("%*c",x,'a');
makes use of the minimum character width that can be set for each input parameter to printf.
What the above does is print out the a character, but specifies that the minimum width will be x characters - so the output will be the a character preceded by 2 spaces.
The * specifier tells printf that the width of the part of the output string formed from this input parameter will be x characters minimum width where x must be passed as additional argument prior to the variable that is to be printed. The extra width (if required) is formed from blank spaces output before the variable to be printed. In this case the width is 3 and so the output string is (excluding the quotes which are just there to illustrate the spaces)
" a"
With your code here
printf("%*c",x);
you have passed the length value, but forgotten to actually pass the variable that you want printed.
So this code
return printf("%*c%*c",x ,' ',y,' ');
is basically saying to print the space character but with a minimum width of x characters (with your code x = 3), then print the space character with a minimum of y characters (in your code y = 4).
The result is that you are printing out 7 blank space characters. This length is the return value of printf (and hence your add function) which is confirmed by the output of
Sum = 7
from the printf inside main().
If you change your code to
return printf("%*c%*c",x ,'a',y,'b');
you would see the string (obviously excluding the quotes)
" a b"
printed which would make what is happening more clear.
Try to print that in the correct way. %d is for printing integer, %c is for printing char.
In your code:
int x=3;
printf("%*c",x);
The x is how much spaces the char will get, you write 3. But you didn't put the char you want to print, so it print garbage.
When you write:
printf("%*c",x,' ');
You printing space ' ' char inside 3 chars space.
Same thing when you do
printf("%*c",x, ' ',y,' '); - just 7 blank spaces. The result is correct because printf returns how many characters it writes.
Look here for extra printf formats.

Defining value of scanf string letters to be read with a variable value

With printf it is perfectly normal to do:
int dec = 3;
float n = 4.3232;
printf("%.*f", dec, n);
But in scanf() I want to replace 100
scanf(%100[^~], string)
with something like:
int a = 100;
scanf(%[***somtehing goes here***][^~], a, string);
But I didn't manage to do it.
Not sure if it is duplicate, I will delete the question if it is.
Edit: replaced '\n' with ~.
For your stated purpose it's probably better to do this:
fgets(string, a, stdin);
http://linux.die.net/man/3/fgets
Just do a first "pass" using sprintf() where you construct the format string that you then use with scanf():
char fmt[64];
const int a = 100;
sprintf(fmt, "%%%d[^\n]", a);
The first two % signs are parsed as a unit by sprintf(); they cause it to emit a single % into the destination string.
The second %d is just the regular code to format a (decimal) integer, it will emit 100.
So the result will be that fmt contains the string "%100[^\n]" (where the \n really means an embedded newline).
Then use fmt with scanf():
const int got = scanf(fmt, string);
As usual, be sure to check the value of got after the call, if it's not 1 then that means scanf() failed to do the requested conversion.

How does calling printf() add numbers here?

I don't understand how this printf() call is working to add together two numbers. Does the %*c have something to do with it?
//function that returns the value of adding two number
int add(int x, int y)
{
NSLog(#"%*c",x, '\r');
NSLog(#"%*c",y, '\r');
return printf("%*c%*c", x, '\r', y, '\r'); // need to know detail view how its working
}
for calling
printf("Sum = %d", add(3, 4));
Output
Sum=7
When passed to printf (or similar functions), %*c means you're passing two parameters instead of one. The first parameter specifies a field width, and the second a character (or string, int, etc.) to write out in that width of field.
printf returns the total number of characters written to the output stream.
A number after % specifies the field width; so %5c will print 4 spaces, followed by the character argument, giving a total of 5 characters.
* specifies that the field width is provided as an argument to printf. So this will print one field of x characters, followed by another of y characters. Each field consists of spaces followed by a carriage-return ('\r'), so there shouldn't be any visible output. printf returns the total number of characters printed - in this case, x+y.
i agree with leeduhem, it is extremely clever,
printf() return the number of character it printed.
For the argument, I think it is more easy to understand with an example:(Also you can see the width trick in here:
#include <iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int main() {
// your code goes here
int x = printf("%*c", 100, '\r');
printf("%d\n", x);
return 0;
}
x is whatever value you set to specific the width (in the eg, it's 100)
That means the width you specific is actually counted and return by the printf()
But I think this add() can only duel with positive numbers, if one of the number is <= 0, the method should fail, you may try add(-3,-4), in my own machine it still print 7...
Oh, this is clever.
return printf("%*c%*c", x, '\r', y, '\r');
On success, printf() will return how many character it printed, and "%*c", x, '\r' tell it to print x characters (x-1 spaces followed by one \r). Therefore, printf("%*c%*c", x, '\r', y, '\r') will return how many characters are printed, which is x+y.
See printf(3) for further details.
Note:
As pointed out by #shole, this int add(int x, int y) works only for both x and y are nonnegative integers. For example:
add(-1, 1) // gives 2 instead of 0
add(0, 1) // gives 2 instead of 1

Resources