Parsing Integer to String C - c

How does one parse an integer to string(char* || char[]) in C? Is there an equivalent to the Integer.parseInt(String) method from Java in C?

If you want to convert an integer to string, try the function snprintf().
If you want to convert a string to an integer, try the function sscanf() or atoi() or atol().

To convert an int to a string:
int x = -5;
char buffer[50];
sprintf( buffer, "%d", x );
You can also do it for doubles:
double d = 3.1415;
sprintf( buffer, "%f", d );
To convert a string to an int:
int x = atoi("-43");
See http://www.acm.uiuc.edu/webmonkeys/book/c_guide/ for the documentation of these functions.

It sounds like you have a string and want to convert it to an integer, judging by the mention of parseInt, though it's not quite clear from the question...
To do this, use strtol. This function is marginally more complicated than atoi, but in return it provides a clearer indication of error conditions, because it can fill in a pointer (that the caller provides) with the address of the first character that got it confused. The caller can then examine the offending character and decide whether the string was valid or not. atoi, by contrast, just returns 0 if it got lost, which isn't always helpful -- though if you're happy with this behaviour then you might as well use it.
An example use of strtol follows. The check for error is very simple: if the first unrecognised character wasn't the '\x0' that ends the string, then the string is considered not to contain a valid int.
int ParseInt(const char *s,int *i)
{
char *ep;
long l;
l=strtol(s,&ep,0);
if(*ep!=0)
return 0;
*i=(int)l;
return 1;
}
This function fills in *i with the integer and returns 1, if the string contained a valid integer. Otherwise, it returns 0.

This is discussed in Steve Summit's C FAQs.

The Java parseInt() function parses a string to return an integer. An equivalent C function is atoi(). However, this doesn't seem to match the first part of your question. Do you want to convert from an integer to a string, or from a string to an integer?

You can also check out the atoi() function (ascii to integer) and it's relatives, atol and atoll, etc.
Also, there are functions that do the reverse as well, namely itoa() and co.

You may want to take a look at the compliant solution on this site.

You can try:
int intval;
String stringval;
//assign a value to intval here.
stringval = String(intval);
that should do the trick.

This is not an optimal solution. This is my solution given multiple restrictions, so if you had limited resources based on your course/instructor's guidelines, this may be a good fit for you.
Also note that this is a fraction of my own project implement, and I had to read in operands as well as digits, so I used getchars. Otherwise, if you only need integers and no other type of characters, I like using this:
int k;
while (scanf("%d", &k) == 1)
The rules were no specific, "advanced" C concepts: no String variables, no structs, no pointers, no methods not covered, and the only include we were allowed was #include
So with no simple method calls like atoi() available or any String variables to use, I chose to just brute force it.
1: read chars in using getchar (fgets was banned). return 1 (exit status 1) if
there is an invalid character. For your problem based of parseInt in Java
1 11 13 is valid but 1 11 1a is invalid, so for all values we have a valid "string" iff all chars are 0-9 ignoring whitespace.
2: convert the ASCII value of a char to its integer value (eg. 48 => 0)
3: use a variable val to store an int such that for each char in a "substring" there is a corresponding integer digit. i.e. "1234" => 1234 append this to an int array and set val to 0 for reuse.
The following code demonstrates this algorithm:
int main() {
int i, c;
int size = 0;
int arr[10]; //max number of ints yours may differ
int val = 0;
int chars[1200]; //arbitrary size to fit largest "String"
int len = 0;
//Part 1: read in valid integer chars from stdin
while((c = getchar()) != EOF && (c < 58 && c > 47)) {
chars[len] = c;
len++;
}
//Part 2: Convert atoi manually. concat digits of multi digit integers and
// append to an int[]
for(i = 0; i < len; i++){
for(i = 0; i < len; i++){
if(chars[i] > 47 && chars[i] < 58){
while((chars[i] > 47 && chars[i] < 58)){
if(chars[i] == 48)
c = 0;
if(chars[i] == 49)
c = 1;
if(chars[i] == 50)
c = 2;
if(chars[i] == 51)
c = 3;
if(chars[i] == 52)
c = 4;
if(chars[i] == 53)
c = 5;
if(chars[i] == 54)
c = 6;
if(chars[i] == 55)
c = 7;
if(chars[i] ==56)
c = 8;
if(chars[i] == 57)
c = 9;
val = val*10 + c;
i++;
}
arr[size] = val;
size++;
if(size > 10) //we have a check to ensure size stays in bounds
return 1;
val = 0;
}
//Print: We'll make it a clean, organized "toString" representation
printf("[");
for(i = 0; i < size-1; i++){
printf("%d, ", arr[i]);
}
printf("%d]", arr[i];
return 0;
Again, this is the brute force method, but in cases like mine where you can't use the method concepts people use professionally or various C99 implements, this may be what you are looking for.

Related

How to use isdisit() for a character array(string)?

I am using C to develop my mini project. So here isdigit() works perfectly when I use it for a char(say char a) and get the input with a scanf("%c",&a);.But it fails when I use it for a string
(say char a[5]) and get it with a scanf("%s",a);.
I expect that ,say if I give the input as 55 isdigit() it should evaluate to true and not when I give the input as say "Wd".
isdigit() is able to receive only one character as a argument.
It cannot understand character array.
If the char a[5] located in 0x38383838 on memory, isdigit(a); virtualy is isdigit(0x38383838);.
So it'll return 0 (or false).
If you want to test whether a character array is digit or not, then you should
int isdigit_array(char *a){
int num = strlen(a);
if(num == 0) return 0;
int flag_isdigit = 1;
int i;
for(i=0; i<num; i++){
flag_isdigit = flag_isdigit && isdigit(a[i]);
}
return flag_isdigit;
}

Print a Char Array of Integers in C

For class, I am required to create a function that converts an Integer into it's corresponding Binary number. However, I am forced to use the given main and parameters for the to_binary function. The whole problem requires me to print out the 32 bit binary number, but to break it up, I am just trying to print out the Char Array, that I thought I filled with Integers (perhaps the issue). When I do compile, I receive just a blank line (from the \n) and I am wondering how I can fix this. All I want to do is to be able to print the binary number for 5 ("101") yet I can't seem to do it with my professor's restrictions. Remember: I cannot change the arguments in to_binary or the main, only the body of to_binary. Any help would be greatly appreciated.
#include<stdio.h>
void to_binary(int x, char c[]) {
int j = 0;
while (x != 0) {
c[j] x = x % 2;
j++;
}
c[33] = '\0';
}
int main() {
int i = 5;
char b[33];
to_binary(i,b);
printf("%s\n", b);
}
This is the answer to your question.
void to_binary(int x, char c[]) {
int i =0;
int j;
while(x) {
/* The operation results binary in reverse order.
* so right-shift the entire array and add new value in left side*/
for(j = i; j > 0; j--) {
c[j] = c[j-1];
}
c[0] = (x%2) + '0';
x = x/2;
i++;
}
c[i]=0;
}
the problem is in the code below:
while (x != 0) {
c[j] = x % 2; // origin: c[j] x = x % 2; a typo?
j++;
}
the result of x % 2 is a integer, but you assigned it to a character c[j] —— integer 1 is not equal to character '1'.
If you want to convert a integer(0-9) to a character form, for example: integer 7 to character '7', you can do this:
int integer = 7;
char ch = '0' + integer;
One of the previous answers has already discussed the issue with c[j] x = x % 2; and the lack of proper character conversion. That being said, I'll instead be pointing out a different issue. Note that this isn't a specific solution to your problem, rather, consider it to be a recommendation.
Hard-coding the placement of the null-terminator is not a good idea. In fact, it can result in some undesired behavior. Imagine I create an automatic char array of length 5. In memory, it might look something like this:
Values = _ _ _ _ _
Index = 0 1 2 3 4
If I were to populate the first three indexes with '1', '0', and '1', the array might look like so:
Values = 1 0 1 _ _
Index = 0 1 2 3 4
Let's say I set index 4 to contain the null-terminator. The array now looks like so:
Values = 1 0 1 _ \0
Index = 0 1 2 3 4
Notice how index three is an open slot? This is bad. In C/C++ automatic arrays contain garbage values by default. Furthermore, strings are usually printed by iterating from character to character until a null-terminator is encountered.
If the array were to look like it does in the previous example, printing it would yield a weird result. It would print 1, 0, 1, followed by an odd garbage value.
The solution is to set the null-terminator directly after the string ends. In this case, you want your array to look like this:
Values = 1 0 1 \0 _
Index = 0 1 2 3 4
The value of index 4 is irrelevant, as the print function will terminate upon reading index 3.
Here's a code example for reference:
#include <stdio.h>
int main() {
const size_t length = 4;
char binary[length];
size_t i = 0;
while (i < length - 1) {
char c = getchar();
if (c == '0' || c == '1')
binary[i++] = c;
}
binary[i] = '\0';
puts(binary);
return 0;
}
#include<stdio.h>
int binary(int x)
{
int y,i,b,a[100];
if(x<16)
{
if(x%2==1)
a[3]=1;
if(x/2==1||x/2==3 || x/2==5 || x/2==7)
a[2]=1;
if(x>4 && x<8)
a[1]=1;
else if(x>12 && x<16)
a[1]=1;
if(x>=8)
a[0]=1;
}
for(i=0;i<4;i++)
printf("\t%d",a[i]);
printf("\n");
}
int main()
{
int c;
printf("Enter the decimal number (less than 16 ):\n");
scanf("%d",&c);
binary(c);
}
this code might help it will simply convert the decimal number less than 16 into the 4 digit binary number.if it contains any error than let me know

Accessing elements in a string?

I have to convert a given binary input (e.g. 1101) to decimal, but the input isn't a string array or an integer (the passed argument is const char *binstr). How am I supposed to access each individual digit of the binary number so I can do pow(x,y) on each and add them together to get the decimal number?
const char * usually refers to a C string. You can just use strtol(3):
int x = strtol(binstr, NULL, 2);
You could try with this program which converts from Binary to Decimal
char *binstr = "1011011";
int num = 0, sum = 0, ctr = 0;
ctr = strlen(binstr) - 1;
do{
sum += ((binstr[ctr] & 0x1) << num);
ctr--;
num ++;
}while(ctr >= 0);
binstr[0];
binstr[1];
binstr[2];
etc
or you can do it through a pointer
char* s = binstr;
unsigned long x =0;
while(*s) { x = x << 1; x |= (*s == '1' ? 1:0); s++;}
printf("the decimal of %s is %ul", binstr, x);
You've made a c string and you can get each character the way similar to arrays:
input[i]
Here's an example of splitting the binary string into individual bits (characters) and printing them out: http://cfiddle.net/wYtKJv
You can use loops:
while(i<100){
if(binstr[i]== '\0'){
break;
}
printf("First Bit:\n%c\n\n",binstr[i]);
i++;
}
Since C-strings are null terminated you can check to see if a character if we hit is '\0' to break the loop.
In the loop you can also convert the chars to ints and store them someplace (array probably) where you can access them for calculations.

Questions about a Kernighan and Ritchie Excercise 2-3

I'm trying to write a program in C that converts hexadecimal numbers to integers. I've written successfully a program that converts octals to integers. However, the problems begin once I start using the letters (a-f). My idea for the program is ads follows:
The parameter must be a string that starts with 0x or 0X.
The parameter hexadecimal number is stored in a char string s[].
The integer n is initialized to 0 and then converted as per the rules.
My code is as follows (I've only read up to p37 of K & R so don't know much about pointers) :
/*Write a function htoi(s), which converts a string of hexadecimal digits (including an optional 0x or 0X) into its equivalent integer value. The allowable digits are 0 through 9, a through f, and A through F.*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
int htoi(const char s[]) { //why do I need this to be constant??
int i;
int n = 0;
int l = strlen(s);
while (s[i] != '\0') {
if ((s[0] == '0' && s[1] == 'X') || (s[0] == '0' && s[1] == 'x')) {
for (i = 2; i < (l - 1); ++i) {
if (isdigit(s[i])) {
n += (s[i] - '0') * pow(16, l - i - 1);
} else if ((s[i] == 'a') || (s[i] == 'A')) {
n += 10 * pow(16, l - i - 1);
} else if ((s[i] == 'b') || (s[i] == 'B')) {
n += 11 * pow(16, l - i - 1);
} else if ((s[i] == 'c') || (s[i] == 'C')) {
n += 12 * pow(16, l - i - 1);
} else if ((s[i] == 'd') || (s[i] == 'D')) {
n += 13 * pow(16, l - i - 1);
} else if ((s[i] == 'e') || (s[i] == 'E')) {
n += 14 * pow(16, l - i - 1);
} else if ((s[i] == 'f') || (s[i] == 'F')) {
n += 15 * pow(16, l - i - 1);
} else {
;
}
}
}
}
return n;
}
int main(void) {
int a = htoi("0x66");
printf("%d\n", a);
int b = htoi("0x5A55");
printf("%d\n", b);
int c = htoi("0x1CA");
printf("%d\n", c);
int d = htoi("0x1ca");
printf("%d\n", d);
}
My questions are:
1. If I don't use const in the argument for htoi(s), i get the following warnings from the g++ compiler :
2-3.c: In function ‘int main()’: 2-3.c:93:20: warning: deprecated
conversion from string constant to ‘char*’ [-Wwrite-strings]
2-3.c:97:22: warning: deprecated conversion from string constant to
‘char*’ [-Wwrite-strings] 2-3.c:101:21: warning: deprecated conversion
from string constant to ‘char*’ [-Wwrite-strings] 2-3.c:105:21:
warning: deprecated conversion from string constant to ‘char*’
[-Wwrite-strings]
Why is this?
2.Why is my program taking so much time to run? I haven't seen the results yet.
3.Why is it that when I type in cc 2-3.c instead of g++ 2-3.c in the terminal, I get the following error message:
"undefined reference to `pow'"
on every line that I've used the power function?
4. Please do point out other errors/ potential improvements in my program.
If I don't use const in the argument for htoi(s), i get the following warnings from the g++ compiler
The const parameter should be there, because it is regarded as good and proper programming to never typecast away const from a pointer. String literals "..." should be treated as constants, so if you don't have const as parameter, the compiler thinks you are casting away the const qualifier.
Furthermore, you should declare all pointer parameters that you don't intend to modify the contents of as const, Google the term const correctness.
Why is my program taking so much time to run? I haven't seen the results yet.
I think mainly because you have made an initialization goof-up. int i; i contains rubbish. Then while (s[rubbish_value] != '\0'). This function can be written a whole lot better too. Start by checking for the 0x in the start of the string, if they aren't there, signal some error (return NULL?), otherwise discard them. Then start one single loop after that, you don't need 2 loops.
Note that the pow() function deals with float numbers, which will make your program a slight bit slower. You could consider using an integer-only version. Unfortunately there is no such function in standard C, so you will have to found one elsewhere.
Also consider the function isxdigit(), a standard function in ctype.h, which checks for digits 0-9 as well as hex letters A-F or a-f. It may however not help with performance, as you will need to perform different calculations for digits and letters.
For what it is worth, here is a snippet showing how you can convert a single char to a hexadecimal int. It is not the most optimized version possible, but it takes advantage of available standard functions, for increased readability and portability:
#include <ctype.h>
uint8_t hexchar_to_int (char ch)
{
uint8_t result;
if(isdigit(ch))
{
result = ch - '0';
}
else if (isxdigit(ch))
{
result = toupper(ch) - 'A' + 0xA;
}
else
{
// error
}
return result;
}
Don't use a C++ compiler to compile a C program. That's my first advice to you.
Secondly const in a function parameter for a char * ensures that the programmer doesn't accidentally modify the string.
Thirdly you need to include the math library with -lm as stated above.
a const char[] means that you cannot change it in the function. Casting from a const to not-const gives a warning. There is much to be said about const. Check out its Wikipedia page.
--
Probably, cc doesn't link the right libraries. Try the following build command: cc 2-3.c -lm
Improvements:
Don't use pow(), it is quite expensive in terms of processing time.
Use the same trick with the letters as you do with the numbers to get the value, instead of using fixed 'magic' numbers.
You don't need the last else part. Just leave it empty (or put an error message there, because those characters aren't allowed).
Good luck!
About my remark about the pow() call (with the use of the hexchar_to_int() function described above, this is how I'd implement this (without error checking):
const char *t = "0x12ab";
int i = 0, n = 0;
int result = 0;
for (i = 2; i < strlen(t); i++) {
n = hexchar_to_int(t[i]);
result |= n;
result <<= 4;
}
/* undo the last shift */
result >>= 4;
I just worked through this exercise myself, and I think one of the main ideas was to use the knowledge that chars can be compared as integers (they talk about this in chapter 2).
Here's my function for reference. Thought it may be useful as the book doesn't contain answers to exercises.
int htoi(char s[]) {
int i = 0;
if(s[i] == '0') {
++i;
if(s[i] == 'x' || s[i] == 'X') {
++i;
}
}
int val = 0;
while (s[i] != '\0') {
val = 16 * val;
if (s[i] >= '0' && s[i] <= '9')
val += (s[i] - '0');
else if (s[i] >= 'A' && s[i] <= 'F')
val += (s[i] - 'A') + 10;
else if (s[i] >= 'a' && s[i] <= 'f')
val += (s[i] - 'a') + 10;
else {
printf("Error: number supplied not valid hexadecimal.\n");
return -1;
}
++i;
}
return val;
}
Always init your variables int i=0, otherwise i will contain a garbage value, could be any number, not necessary 0 as you expect. You're running the while statement in an infinite loop, that's why it takes forever to get the results, print i to see why. Also, add a break if the string doesn't start with 0x, will avoid the same loop issue when the user is used on a random string. As others mention you need to import the library containing pow function and declare your string with const to get rid of the warning.
This is my version of program for the question above. It converts the string of hex into decimal digits irrespective of optional prefix(0x or 0X).
4 important library functions used are strlen(s), isdigit(c), isupper(c), isxdigit(c), pow(m,n)
Suggestions to improve the code are welcome :)
/*Program - 5d Function that converts hex(s)into dec -*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h> //Declares mathematical functions and macros
#include<string.h> //Refer appendix in Page 249 (very useful)
#define HEX_LIMIT 10
int hex_to_dec(char hex[]) //Function created by me :)
{
int dec = 0; //Initialization of decimal value
int size = strlen(hex); //To find the size of hex array
int temp = size-1 ; //Pointer pointing the right element in array
int loop_limit = 0; //To exclude '0x' or 'OX' prefix in input
if(hex[0]=='0' && ((hex[1]=='x') || (hex[1]=='X')))
loop_limit = 2;
while(temp>=loop_limit)
{
int hex_value = 0; //Temporary value to hold the equivalent hex digit in decimal
if(isdigit(hex[temp]))
hex_value = (hex[(temp)]-'0') ;
else if(isxdigit(hex[temp]))
hex_value = (toupper(hex[temp])-'A' + 10);
else{
printf("Error: No supplied is not a valid hex\n\n");
return -1;
}
dec += hex_value * pow(16,(size-temp-1)); //Computes equivalent dec from hex
temp--; //Moves the pointer to the left of the array
}
return dec;
}
int main()
{
char hex[HEX_LIMIT];
printf("Enter the hex no you want to convert: ");
scanf("%s",hex);
printf("Converted no in decimal: %d\n", hex_to_dec(hex));
return 0;
}

How can I add a thousands separator to a double in C on Windows?

I use the MPFR library to do calculations on big numbers, but also return a double with 8 digits after the decimal point.
I mpfr_sprintf the number to a char array so precision or anything isn't lost.
Everything is fine except that I didn't find any thousand separator option in the documentation(or I missed it).
Given a number such as 20043.95381376 I would like to represent it like 20,043.95381376 for better readability.
Or the number 164992818.48075795 as 164,992,818.48075795
I read about an apostrophe that should be added to printf/sprintf, but that seems to be a UNIX/POSIX thing and I am a Windows user.
Since internally I print the number as a string, I thought what I could do is write a custom implementation that would automatically add the comma depending on the number(>1000>10000>100000 and so forth) but then I realized that functions like strncpy or strcpy will essentially replace, not add the comma to the desired position. And here is how I am back to square one on how to do it.
How can I do it?
You need your implementation to convert the double value to string and examine each character of that string, then copy it to an output string along with the separators.
Something like this:
#include <stdio.h>
#include <string.h>
int thousandsep(double in, char* out_str, size_t out_len, unsigned int precision) {
char in_str[128], int_str[128], format[32];
size_t dlen, mod, i, j;
int c;
snprintf(format, sizeof format, "%%.%df", precision);
snprintf(in_str, sizeof in_str, format, in);
snprintf(int_str, sizeof int_str, "%d", (int)in);
dlen = strlen(in_str);
mod = strlen(int_str) % 3;
c = (mod == 0) ? 3 : mod;
for (i=0, j=0; i<dlen; i++, j++, c--) {
if (j >= out_len - 1) {
/* out_str is too small */
return -1;
}
if (in_str[i] == '.') {
c = -1;
} else if (c == 0) {
out_str[j++] = ',';
c = 3;
}
out_str[j] = in_str[i];
}
out_str[j] = '\0';
return 0;
}
Then use it like so:
char out_str[64];
if (thousandsep(20043.95381376, out_str, sizeof out_str, 8) == 0)
printf("%s\n", out_str); /* 20,043.95381376 */
if (thousandsep(164992818.48075795, out_str, sizeof out_str, 8) == 0)
printf("%s\n", out_str); /* 164,992,818.48075795 */
if (thousandsep(1234567.0, out_str, sizeof out_str, 0) == 0)
printf("%s\n", out_str); /* 1,234,567 */
Note: I assumed that if you're on Windows, you may be using MSVC so this solution should be working on C89 compilers.
GetNumberFormatEx will take the plain string version of the number and format it with the grouping separators, appropriate decimal point, etc. Pass LOCALE_NAME_USER_DEFAULT as the locale, and it will be in the format that the user prefers.
If you need to override one of the settings (like the precision), you can populate a NUMBERFMT struct with the defaults and then change the fields you need to control.
There does not appear to be a formatting directive that can be used.
Here is a quick and dirty way of taking a string containing a floating point number and inserting commas into the appropriate places.
This uses a couple of temp buffers. The thousands separator symbol will depend on locale as does the decimal point symbol. However for this example a comma is hard coded.
This basically just takes the string representation of the floating point number and then steps through copying the digits to another buffer and inserting commas at the appropriate places.
You could also take a look at doing this with fewer buffers as like I said, this is quick and dirty and not terribly efficient.
{
double dFloat = 123456789012.567890;
char xBuff[128];
sprintf (xBuff, "%f", dFloat);
char xBuff2[128];
int iLen = strlen(xBuff);
int iPoint = iLen;
for (iLen--; iLen >= 0; iLen--) {
if (xBuff[iLen] == '.' || xBuff[iLen] == ',') {
// found the decimal point. depends on locale.
iPoint = iLen;
break;
}
}
strcpy (xBuff2, xBuff + iPoint); // save the decimal portion
char xBuff3[128], xBuff4[128];
xBuff3[127] = 0; // set an end of string
int iCount, jLen;
for (iCount = 1, jLen = 126, iLen--; iLen >= 0; jLen--, iLen--) {
if ((iCount % 4) == 0) {
xBuff3[jLen] = ',';
jLen--;
iCount = 1;
}
xBuff3[jLen] = xBuff[iLen];
iCount++;
}
strcpy (xBuff4, xBuff3 + jLen + 1);
strcat (xBuff4, xBuff2);
}
#include <stdio.h>
#include <locale.h>
int main(void)
{
setlocale(LC_NUMERIC, "");
printf("%'.8lf\n", 164992818.48075795);
return 0;
}

Resources