C : converting binary to decimal - c

Is there any dedicated function for converting the binary values to decimal values.
such as (1111 to 15 ) , ( 0011 to 3 ) .
Thanks in Advance

Yes, the strtol function has a base parameter you can use for this purpose.
Here's an example with some basic error handling:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* input = "11001";
char* endptr;
int val = strtol(input, &endptr, 2);
if (*endptr == '\0')
{
printf("Got only the integer: %d\n", val);
}
else
{
printf("Got an integer %d\n", val);
printf("Leftover: %s\n", endptr);
}
return 0;
}
This correctly parses and prints the integer 25 (which is 11001 in binary). The error handling of strtol allows noticing when parts of the string can't be parsed as an integer in the desired base. You'd want to learn more about this by reading in the reference I've linked to above.

Parse it with strtol, then convert to a string with one of the printf functions. E.g.
char binary[] = "111";
long l = strtol(binary, 0, 2);
char *s = malloc(sizeof binary);
sprintf(s, "%ld\n", l);
This allocates more space than needed.

Related

why cant I convert a string into an int in c

Assume that we have a char array input = "12345678987654321", why cant I use atoi() to convert it into integer 12345678987654321? I have tried this and it returned some numbers that I couldn't understand.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char num[20];
scanf("%s\n", num);
printf("%d", atoi(num));
return 0;
}
The reason you get weird output is the number entered is beyond the range of values representable with the int type. The atoi() function does not necessarily perform error checking, it actually has undefined behavior if the number cannot be represented as an int. You should use strtol() instead.
Your program has another potential undefined behavior: scanf("%s\n", num) may write beyond the end of the num array with dire consequences if the user inputs more than 19 characters. You should write scanf("%19s", num) and test the return value for potential conversion errors.
Here is a modified version:
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char num[20];
if (scanf("%19s", num) != 1) {
printf("no input\n");
return 1;
}
int c = getchar();
if (c != '\n' && c != EOF) {
printf("too many characters\n");
ungetc(c, stdin);
}
char *end;
errno = 0;
long value = strtol(num, &end, 10);
if (end == num) {
printf("input is not a number: %s", num);
} else {
if (errno != 0) {
printf("number %s is too large for type long\n", num);
} else
if (value < INT_MIN || value > INT_MAX) {
printf("number %ld is too large for type int\n", value);
} else {
printf("value is %d\n", (int)value);
}
if (*end != '\0') {
printf("extra characters after the number: %s", end);
}
}
return 0;
}
“12345678987654321” is generally too large for an int, and atoi does not provide error detection.
You can use the strto… functions to convert a numeral in a string to an integer type. Below is an example using strtoimax, for the widest signed integer type a C implementation supports. There are also versions for other types, such as strtoll for long long.
The strto… functions provide error checking, so you can detect when a number is too large and report it to the user or otherwise handle it.
#include <ctype.h> // For isdigit and isspace.
#include <errno.h> // For errno.
#include <inttypes.h> // For stroimax and PRIdMAX.
#include <stdint.h> // For intmax_t.
#include <stdio.h> // For printf, fprintf, getchar, and ungetc.
#include <stdlib.h> // For exit.
int main(void)
{
// Read string.
char string[20];
int n = 0; // Number of characters read so far.
while (1)
{
int c = getchar();
// When we see the end of the input stream, leave the loop.
if (c == EOF)
break;
/* When we see a white-space character (including new-line), put it
back into the stream and leave the loop.
*/
if (isspace(c))
{
ungetc(c, stdin);
break;
}
/* If we see character that is not a space or a digit, complain, unless
it is the first character and is a sign, "+" or "-".
*/
if (!isdigit(c) && !(n == 0 && (c == '+' || c == '-')))
{
fprintf(stderr, "Error, non-digit seen: \"%c\".\n", c);
exit(EXIT_FAILURE);
}
// Record the digit.
string[n++] = c;
if (sizeof string / sizeof *string <= n)
{
fprintf(stderr, "Error, too many digits, can handle only %zu.\n",
sizeof string / sizeof *string - 1);
/* ("sizeof *string" is one for ordinary "char" arrays, but
using it allows changing to wide character types if
desired.)
*/
exit(EXIT_FAILURE);
}
};
// Finish string with a null character.
string[n] = '\0';
// Attempt to convert string to an intmax_t.
char *end;
errno = 0; // Initialize error indicator.
intmax_t number = strtoimax(string, &end, 0);
/* Test whether the string failed to match the form for a numeral, because
it was empty or was just a sign with no digits.
*/
if (end == string)
{
fprintf(stderr, "Error, numeral has no digits.\n");
exit(EXIT_FAILURE);
}
// Check for error.
if (errno != 0)
{
fprintf(stderr, "Error, number is too large for intmax_t.\n");
exit(EXIT_FAILURE);
}
/* Test whether the whole string was used in the conversion. It should have
been, considering we ensured each character was a digit, but a check
like this can be useful in other situations, where we are parsing a
numeral from a more general string.
*/
if (*end != 0)
{
fprintf(stderr, "Error, unexpected character in numeral, \"%c\".\n",
*end);
exit(EXIT_FAILURE);
}
// Print the number.
printf("The number is %" PRIdMAX ".\n", number);
}
you are giving input of "12345678987654321" atoi is in int and the range of int is from -2,147,483,648 - 2,147,483,647 so in order to fix it use atol() l-long,its just because of range or if you are using 32bit machine then you need to use long long int i.e atoll() instead of atol()
data size
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char num[20];
scanf("%s",num);
//printf("\n%s",num);
printf("\n%ld",atol(num)); //<- atoi(num) to atol(num)
return 0;
}
atol() check this for more atoi(),atol() and atoll()

How do I convert a number from the command line to an inter using strtol in C?

I started a course in C today and I am not really sure how you would use the strtol function to convert a string of an integer from command line arguments instead of using the atoi function (for some reason, I am not allowed to use the atoi function.
How would I change the following code to use the strtol function instead? If possible, please explain what the variables you create (if any) do with relevance to the strtol function.
int main( int argc, char * argv[] ) {
int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);
printf("num1 = %d, num2 = %d", num1, num2);
return 0;
}
convert a number from the command line to an integer using strtol
[Found many strtol() posts, yet not a direct good C answer to OP's question on SO.]
Good strtol() usage involves base, errno and the end pointer and testing for various outcomes.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc, char *argv[]) {
for (int a = 1; a < argc; a++) { // check command line arguments after argv[0].
int base = 10; // convert strings as encoded with decimal digits.
char *endptr; // location to store the end of conversion.
errno = 0;
long val = strtol(argv[a], &endptr, base);
printf("<%s> --> %ld:", argv[a], val);
if (argv[a] == endptr) {
printf(" No conversion.\n");
} else if (errno == ERANGE) { // ***
printf(" Out of `long` range.\n");
} else if (errno) {
printf(" Implementation specific error %d detected.\n", errno);
} else if (*endptr) {
printf(" Trailing junk <%s> after the numeric part.\n", endptr);
} else {
printf(" Success.\n");
}
}
}
*** Better code uses the value of errno promptly after strtol() to insure it reflects an error due to strtol() and not some later function.
the prototype as you may know is
long int strtol(const char *str, char **endptr, int base)
where str is the original string and endptr is the address of a pointer to the rest of the string after a number is found. base is, well, the base.
strtol() returns 0 when it finds no number. Sure it returns 0 when it finds a 0 and then you must check the remaining data and eventually start over again.
This
Original string: "2001 2002 2003 2004 0 2005"
2001 parsed string now: " 2002 2003 2004 0 2005"
2002 parsed string now: " 2003 2004 0 2005"
2003 parsed string now: " 2004 0 2005"
2004 parsed string now: " 0 2005"
0 was parsed: may be just the end of input
5 bytes remaining at the string: " 2005"
is the output of the short program below and may help you understand the mechanic
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
const char* pattern =
"2001 2002 2003 2004 0 2005";
char* input = (char*)pattern;
char* after = NULL;
long long int num1 = strtol(input, &after, 10);
printf("Original string: \"%s\"\n\n", pattern);
do
{
printf("%8lld parsed\tstring now: \"%s\"\n", num1, after);
input = after;
num1 = strtol(input, &after, 10);
} while (num1 != 0);
printf("\n0 was parsed: may be just the end of input\n");
printf("\n%ud bytes remaining at the string: \"%s\"\n",
strlen(after), after);
return 0;
};
// Compiled under MSVC 19.27

Converting Strings from a .csv file to doubles

Having trouble with the converting of strings to doubles. I've tried using strtod, but that does the same thing. It seems like this should work just find but perhaps using strtok has something to do with it. data[i].calories is a double of course.
data[i].calories = atof(strtok(NULL, ","));
It seems to assign either a positive or negative really big number to calories (a double, which means it must be reading the value wrong.
Data Expected:
12cx7,23:55:00,->0.968900025,(this could also be a double),0,74,0,2,
What it instead actually gets:
12cx7,23:55:00,->-537691972,0,0,74,0,2,
EDIT:
IM AN IDIOT I WAS DISPLAYING IT AS AN INT PFFFFFFFFFFFFFFFF.
Assuming we have an input like this,
12cx7,23:55:00,0.968900025,,0,74,0,2,
And we would like to,
"Having trouble with the converting of strings to doubles."
That is we would like to separate the alphanumeric data . And then the remaining ints and floats, we would like to print in the correct format, I would do something like the following:
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int isNumeric (const char * s)
{
if (s == NULL || *s == '\0' || isspace(*s)) {
return 0;
}
char * p;
strtod (s, &p);
return *p == '\0';
}
bool isInteger(double val)
{
int truncated = (int)val;
return (val == truncated);
}
int main() {
// If this is your input:
char input[100] = "12cx7,23:55:00,0.968900025,0,74,0,2,";
// Then step 1 -> we split the values
char *token = std::strtok(input, ",");
while (token != NULL) {
// Step 2 -> we check if the values in the string are numeric or otherwise
if (isNumeric(token)) {
// printf("%s\n", token);
char* endptr;
double v = strtod(token, &endptr);
// Step 3 -> we convert the strings containing no fractional parts to ints
if (isInteger(v)) {
int i = strtol(token, &endptr, 10);
printf("%d\n", i);
} else {
// Step 4 -> we print the remaining numeric-strings as floats
printf("%f\n", v);
}
}
else {
// What is not numeric, print as it is, like a string
printf("%s,",token);
}
token = std::strtok(NULL, ",");
}
}
For the isInteger() function, I took the idea/code from this accepted answer. The rest is quite original and probably could be refined/improved.
This produces then this output:
12cx7,23:55:00,0.968900,0,74,0,2,
which is basically the output that we want, except with the very important difference that the input was a whole single string and the output is doubles/floats, ints and strings correctly identified and printed with the correct formatting.
EDIT:
I am not any doing error-handling here. This code is just to give the OP a proof-of-concept. Check and control for any errors returned from the used strtoX functions.

Getting integer while using strtok() in string

I'm new to C and need your help.
I'm trying to get an integer from a string that has a number in it.
I have with me a code I did but the only problem is when I'm assigning years as int i think I'm getting some sort of an address. Is there a way to get my char years into an in years?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char sentence[]="trade_#_2009_#_invest_#_DEALING";
char *word=strtok(sentence, "_#_");
char *year=strtok(NULL,"_#_"); // assigning NULL for previousely where it left off
char *definition=strtok(NULL,"_#_");
char *synonyms=strtok(NULL,"_#_");
printf("%s\n", word);
printf("%s\n", year);
printf("%s\n", definition);
printf("%s\n", synonyms);
return 0;
}
int iYear = 0;
sscanf(year,"%d",&iYear);
This should be the simplest.
You might also want to look at atoi function.
Use strtol or strtoul.
Here's an example taken from the strtol page that I linked to above:
/* strtol example */
#include <stdio.h> /* printf */
#include <stdlib.h> /* strtol */
int main ()
{
char szNumbers[] = "2001 60c0c0 -1101110100110100100000 0x6fffff";
char * pEnd;
long int li1, li2, li3, li4;
li1 = strtol (szNumbers,&pEnd,10);
li2 = strtol (pEnd,&pEnd,16);
li3 = strtol (pEnd,&pEnd,2);
li4 = strtol (pEnd,NULL,0);
printf ("The decimal equivalents are: %ld, %ld, %ld and %ld.\n", li1, li2, li3, li4);
return 0;
}

How do I convert a string representation of a hex to its hex value in c?

If I have
char input[50] = "xFFFF";
int a;
How can I store the numerical value of input in a?
the language is C.
One way to do it might be:
if (sscanf(input, "x%x", &a) == 0) {
/* matching failed */
}
If your input uses a real hex specifier (like "0xFFFF") you can just use %i:
if (sscanf(input, "%i", &a) == 0) {
/* matching failed */
}
You can use strtol function
char *ptr;
long a = strtol( input, &ptr, 16 );
One way:
#include <stdlib.h>
int main()
{
char *p="xFFFF";
long lng=strtol(&p[1], (char **)0, 16);
printf("%ld\n", lng);
return 0;
}
See C++ convert hex string to signed integer and if you're in a pure C environment, make sure to scroll down.

Resources