In C what does this line do: - c

printf("\n%12.6f%12.6f%12.6f", R[1], LS[1], LAMBDA);
The R is an array of floats, LS is also an array of floats, and LAMBDA is a single float variable.
I'm trying to convert a program over to Java but I cannot figure out what this line is trying to do (I am not experienced in C at all).

The printf() function prints to stdout, which is usually the console, and uses a particular variable-replacement syntax in strings - what you're looking at is thus a format string. Breaking it down:
\n : newline
%12.6f : next variable,
width 12 -- Padded with spaces to make the string exactly 12 characters if it's not already
precision 6 -- Six digits after the decimal point
in decimal floating point format
+2 more iterations of this
The array lookup syntax is the same as in Java, so it's looking up the second (because zero-based indexing) element in R and LS.

It just print these value to stdout, in float number format with specified format.
More details can be found at printf().

Here is a tiny test program, and its output:
#include <stdio.h>
int main(int argc, char **argv) {
float R[2] = {1./7. * 10000, 2./7. * 10000};
float LS[2] = {3./7. *10000, 4/7. * 10000};
float LAMBDA = 5/7. *10000;
printf("BEFORE");
printf("\n%12.6f%12.6f%12.6f", R[1], LS[1], LAMBDA);
printf("AFTER\n");
}
BEFORE
2857.142822 5714.285645 7142.856934AFTER
So, a newline, then all on one line, with each number taking up 12 spaces, R[1], LS[1], and LAMBDA, printed to 6 digits of accuracy. Then, no newline, so they must want something else to happen on the line line after.

Related

How to convert string representation of octal number to decimal?

I want to make a program that converts binary number to decimal, octal and hexadecimal.
While taking input I am considering their standard representation. For example: octal is "o10"
So I convert 10 into decimal, which gives 8.
Here's my code for inputting string and converting it to decimal:
int main()
{
int ch=0;
char str[1000];
printf("Enter the number\n");
scanf(" %s",str);
l=strlen(str);
for(int j=0;j<l;j++)
{
if(str[j]>=48 && str[j]<=57)
n=n*10+(str[j]-48);
}
}
But the problem is that it doesn't work for octal. How to take the input correctly?
On the post you are taking about creating Binary/Octal/Hexadecimal to Decimal converter, but you code only address Octal, My answer will try to be generic so you could implement the other cases with it, but will focus on Octal.
First of all, your code has some minor issues not related to the algorithm itself:
You call printf and strlen function, which does not come built in with C and need to be included with their respective libraries:
#include <stdio.h>
#include <string.h>
You assign l to the length of the string, but you never declare it type, so this is needed:
l = strlen(str);
Same problem for n, which is never declared. Not only that, you say n=n*10 ... so noy only not declaring it, you use it value.. what do you think n*10 will return? My guess is garbage. Since you use it in the loop, you should declare it outside the loop itself, so I would suggest:
int l = strlen(str), n = 0;
Okay not that we got this out of the way, your Octal converted code is actually almost done.
Only problem with the algorithm, is the n*10 ... part. If you multiply n by 10, you acually get decimal converted.. so Decimal to Decimal converted, if you input for example 48 you will get 48 as output. What do we need to fix it? change it to 2 for Binary converted, 8 for Octal, and 16 for Hexa. Your code only speak about octal, so if you change this line to:
n = n * 8 + (str[j] - 48);
You will get a working Octal converted. For example, if run the program and input 10, you will get 8 which is what we want.
Now as I mentioned earlier, if you want to make it more generic you should have a variable called int base = 10; which you can set according to the first character, for example:
int base = 10; // default value
if (str[0] == 'o')
{
base = 8;
}
Of course you can do the same for other bases, and it will pretty much work the same. Finally, you never did actually with the value of n after you calculated it, So someting like that would work to check the answer we got:
printf("In Decimal => %d\n", n);
This kinda works, but we still need to check digit boundaries. For example, octal number can't have a digit larger then 7, and Hexa number can have A as a digit. In the for loop, we do not check for anything like that. For example, if you input o48 in your code it will print an answer, 40, which is not correct since 48 is not an octal number.
So you in order to complete the program, you need to check if boundaries, and implement the rest of the bases check (h for hexa, b for binary), This I will leave to you.
GOOD LUCK~!

how Printf stmt perform printf("%*.*s",10,7,str); in detailed explanation

Why we used . while printing the string.
printf("%*.*s",10,7,str);
This is the actual program. how the printf statement preforms the operation in detailed explanation.
#include<stdio.h>
int main()
{
char *str="c-pointer";
printf("%*.*s",10,7,str);
return 0;
}
The .7 is a precision
Read no more the 7 characters from str.
The 10 is a minimum width
Print at least 10 characters, pad if needed.
printf("%*.*s",10,7,str);
equal to
printf("%10.7s",str);
You tell to printf to print minimum 10 Letter and first 7 characters in str, so
" c-point"
^^^^^^^^^^
The character to fill is space and default justification is right.
And you can change justify to left by
printf("%-10.7s",str);
it will print
"c-point "
and you can not add 0 to %s but you can do this in numeric conversions and you can not use both - and 0 in numeric conversions also because - will override 0.

Can someone explain to me how does this actually work (atoi)

I have written a program that takes 2 arguments from the user and adds them together so for example if the user puts ./test 12 4 it will print out the sum is: 16.
the part that is confusing me is why do I have to use the atoi and I can't just use argv[1] + argv[2]
I know that atoi is used convert a string to an integer and I found this line of code online which helped me with my program but can someone explain to me why do I need it :
sum = atoi(argv[1])+atoi(argv[2]);
code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int sum = 0;
sum = atoi(argv[1])+atoi(argv[2]);
printf("The sum is : %d \n", sum);
return 0;
}
The reason is the same thing as the difference between you and your name. The user typed "./test 12 4" so before your program ran, the command shell that the user is using prepared two sequences of numbers representing the text characters that form the names of the user's numbers and gave them to your program - the shell got those directly from the terminal where the user typed them.
In order to add the numbers that these sequences identify by name you need to use a function that converts those two names to int - a representation of the numbers that they identify for which addition is defined. This function is called 'atoi' and the two names were the sequences {49,50,0} and {52,0} (being representations of the symbol sequences {'1','2','\0'} and {'4', '\0'}). The 0 (also written '\0') is a code for a special symbol that can't be printed or typed directly (this is a lie but I don't want to get into that) and it's added to the end of the names so that atoi, as it reads the name character code by character code, knows when it reached the end. Note that these particular values depend on what platform you're using but I'm assuming it's a platform that uses ascii or utf-8 rather than something like ebcdic.
As part of printing the resulting number, printf uses the "%d" directive to accept the int way of representing the answer (which you got from adding two ints) and converts it back to to the name of the answer as character codes {49,56} ({'1','6'}) ready to send back to the terminal. I left out any possible terminating 0 ('\0') in the output codes just there because printf doesn't indicate an end here unlike the end indications you receive in the inputs from the shell - the terminal can't look for an end in the same way that atoi does and printf doesn't give you the name for further usage within the C program; it just sends the name right out of the program for display to the terminal (which is the place that the command shell hooked up to the program's output stream).
Although atoi isn't the only thing you could do with the incoming names for numbers, the C language has been designed to give the ending marker for each argv element because it will typically be needed for any alternative choices you might make for handling the incoming information.
Try this to see the codes being used explicitly (still assuming your system uses ascii or utf-8):
#include <stdio.h>
#include <stdlib.h>
char const name_of_program[] = "./test";
char const name_of_first_number[] = {49,50,0}; // {'1','2','\0'} would be the same as would "12" - with the quotes
char const name_of_second_number[] = {52,0}; // {'4','\0'} would be the same as would "4" - with the quotes
int main()
{
char const *argv[] = {
name_of_program,
name_of_first_number,
name_of_second_number,
NULL,
};
int sum = 0;
sum = atoi(argv[1])+atoi(argv[2]);
printf("The sum is : %d \n", sum);
return 0;
}
"the part that is confusing me is why do i have to use the "atoi" and i can't just use argv[1] + argv[2]"
The argv argument holds a list of strings that the program can take as input. The C language does not automatically convert strings to numbers, so you have to do that yourself. The atoi function takes a string as a parameter and returns an integer, which can then be used for the arithmetic operations you want.
In other languages such as C++, summing strings usually concatenates them, but in C you will get a compiler error.
Your argv[i] is type C string by default:
int main(int argc, char *argv[])
and sum is type int.
Even if you input a number it will be read as a char* by your compiler. atoi() makes it read as an int so you can do arithmetic calculations with it.
[Answer updated thanks to comments bellow]

Calling the 1's, 10's, 100's... columns of an integer using a string array

I'm trying to convert a long long integer to a string array with the 1's column in position 0 of the array, the 10's column in position 1, the 100's column in position 2, like this:
INPUT: 4444555566667777 -----> OUTPUT: [4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7]
To test my code, I wrote for my last line printf("%d\n",number_str[3]). I expected my program to output the value of position 4, "7". Instead, it output "52". Changing my last line to printf("%d\n",number_str[4]) yields "53" instead of "6", as I expected. Can anyone explain what's going on?
Surely 52 and 53 correspond to ASCII values, but then, how can I convert them to integers? Can I do this in line?
Where I'm headed with this part of my program is to add up all of the numbers in the 10's, 1,000's, 100,000's, 10,000,000's... columns. Every other digit in a base-10 credit card number. This is one step in my attempt at a Luhn validation.
// Libraries
#include <cs50.h>
#include <stdio.h>
#include <string.h>
// Program
int main(void)
{
// Get CC number
printf("Enter your credit card number: ");
long long number_ll = GetLongLong();
// printf("%lld\n", number_ll);
// Convert long long to string
char number_str[64];
sprintf(number_str, "%lld", number_ll);
// printf("%s\n", number_str);
// Get length of card number string
int cclength = strlen(number_str);
// Check the length of card number string
if ( ! (cclength == 13 || cclength == 15 || cclength == 16))
printf("INVALID\n");
else
printf("%d\n",number_str[3]);
To convert ascii into integer use
#include <stdlib.h>
int atoi(const char *str);
change this
printf("%d\n",number_str[3]);
to
char buf[2];
buf[0]=number_str[3];
buf[1]='\0';
printf("%d\n",atoi((const char*)buf));
Using "%d" on a char will print its ASCII code. Use "%c" to print itself.
And your string's order is reversed compared to your purpose. The rightmost digit(1's column) is at the tail of the string, and the leftmost one is in position 0.
So to print the number at position i (count from right to left), you should use:
printf("%c\n", number_str[cclength - i - 1]);
I'm going to go ahead and expand on my comment since I don't believe either of the other answers responded to your full question.
By reading the CC number into a long long, and then using sprintf to plug the number into a character array, I would say you're correctly getting the number into a form that you can use for validation. In fact, you can check the return value of sprintf to see whether or not it's a valid number (although a failure case would be unlikely since you're plugging in a long long.
Once you have the CC number in a character array, you know that each element of the array will contain one character, which corresponds to one digit in the CC number. It sounds like for your purposes, it's more useful for the values in the array to be the decimal values, rather than the ASCII values. Logically, this is the difference between the values '0' and 0. You can look up any ASCII chart to see the corresponding ASCII value for each character, but since characters can be manipulated just like integers, you can traverse the array:
for(i = 0; i < 64; i++) num_str[i] -= '0';
Note that this doesn't handle there being less than 64 characters or uninitialized values in the array after the CC number characters, so you'll need to modify it. What's important to realize is that you're just shifting the character values down by '0', which happens to have the integer value 48.
Once you do this conversion, printing out a value in the array with printf using %d as the format specifier will work like you expect; even though the array data type is char, each element may be printed as a decimal integer.
Once you've read the number into the char array and made the conversion, all you need to do is traverse the array again, performing whatever steps are involved in the CC Validation process. You may need to traverse the array in reverse if the validation method requires the digits to be in order.

Decoding printf statements in C (Printf Primer)

I'm working on bringing some old code from 1998 up to the 21st century. One of the first steps in the process is converting the printf statements to QString variables. No matter how many times I look back at printf though, I always end up forgetting one thing or the other. So, for fun, let's decode it together, for ole' times sake and in the process create the first little 'printf primer' for Stackoverflow.
In the code, I came across this little gem,
printf("%4u\t%016.1f\t%04X\t%02X\t%1c\t%1c\t%4s", a, b, c, d, e, f, g);
How will the variables a, b, c, d, e, f, g be formatted?
Danny is mostly right.
a. unsigned decimal, minimum 4 characters, space padded
b. floating point, minimum 16 digits before the decimal (0 padded), 1 digit after the decimal
c. hex, minimum 4 characters, 0 padded, letters are printed in upper case
d. same as above, but minimum 2 characters
e. e is assumed to be an int, converted to an unsigned char and printed
f. same as e
g. This is likely a typo, the 4 has no effect. If it were "%.4s", then a maximum of 4 characters from the string would be printed. It is interesting to note that in this case, the string does not need to be null terminated.
Edit: jj33 points out 2 errors in b and g above here.
#Jason Day, I think the 4 in the last %4s is significant if there are fewer than 4 characters. If there are more than 4 you are right, %4s and %s would be the same, but with fewer than 4 chars in g %s would be left justified and %4s would be right-justified in a 4 char field.
b is actually minimum 16 chars for the whole field, including the decimal and the single digit after the decimal I think (16 total chars vs 18 total chars)
Here's my printf primer:
http://www.pixelbeat.org/programming/gcc/format_specs.html
I always compile with -Wall with gcc which
will warn about any mismatches between the supplied
printf formats and variables.
#jj33, you're absolutely right, on both counts.
#include <stdio.h>
int main(int argc, char *argv[]) {
char *s = "Hello, World";
char *s2 = "he";
printf("4s: '%4s'\n", s);
printf(".4s: '%.4s'\n", s);
printf("4s2: '%4s'\n", s2);
printf(".4s2: '%.4s'\n", s2);
return 0;
}
$ gcc -o foo foo.c
$ ./foo
4s: 'Hello, World'
.4s: 'Hell'
4s2: ' he'
.4s2: 'he'
Good catch!
a. decimal, four significant digits
b. Not sure
c. hex, minimum 4 characters
d. Also hex, minimum 2 characters
e. 1 character
f. String of characters, minimum 4
What you really need is a tool which takes the format strings in printf() statements and converts them into equivalent QString based function calls.
Does anyone want to spend his Free Software Donation Time on developing such a tool?
Placeholder for URL to a Free Software hosting service holding the source code of such a tool

Resources