char array to integer array - c

I got a set of characters as input using scanf which is actually like this "1854?156X".
(using scanf("%c",&input[i]) , input is an array of 10 characters);
In further processing of code I want to multiply the (first digit *10) & (second digit *9) and so on.
So, while multiplying it is taking the ASCII value of 1 which is actually (49 *10), instead of (1*10).
input[i]*counter;
where counter is
int counter=10;
How can I convert the char array to integer array where the exact digit should be multiplied instead of ascii value of that character?

If you know ahead of time that you value is ascii then simply subtract the value of '0' from it. E.g. '9' - '0' = 9'

Definitely use atoi(). It spares you a lot of manual character checking.
int input_val = atoi(input);
int temp = input_val;
while(temp)
{
int digit = temp % 10;
temp /= 10;
}
This gives you each digit from right to left in "digit". You can construct your number using addition and multiplying by powers of 10.

Take the ascii value and subtract 48.
That is input[i] - '0'
...or rather use atoi(). It returns zero if it fails on conversion, so you don't need to bother with '?' and such characters in your array while you traverse it.

Use strtol to convert these character strings into integral types.
It's superior to atoi because the failure modes are not ambiguous.

Related

Creating a calculator in c that can ONLY use the functions printf and putchar, and can take very large large integers

Usage: ./calculator.c <operand one> <operator> <operand two>
Operand one and two must be positive integers greater than or equal to zero. They can each have a maximum of 999 digits, and their sum can thus have a maximum of 1000 digits. We can assume that no operands will start with 0, for example stuff like 0009738 will not be passed. We only want to deal with addition for this calculator. No other functions other than printf and putchar can be used for this.
I have dealt with most of this but I am having trouble with the last part. Checking to see if the operator was '+' was straight forward. I checked the initial argument to see if they are positive integers by running while loops on each of the operands like this:
while (argv[1][i] != '\0'){
if(argv[1][i]>57 || argv[1][i]<48){
.....Printing appropriate error messaage
return;
}
}
I ran the above code on each of the operands and also included a counter for each of them that would tell me how many digits each one is. At this point I have int max, which I have gotten from comparing the counters. I have an idea of the algorithm to add the numbers (using mod 10 to get the digit that will be placed, and divide by 10 to get the carry). I initialized three arrays as follows:
char first [max +1];
char second [max + 1];
char sum [max + 1];
I just don't know how to implement this/move forward from here. Could someone help me out? Again I must remind you that the only functions that can be used are printf and putchar, which makes this different than the over questions I went through here on SO.
Assuming that you have calculated already the number of digits for the two operands, you can loop from the end of the two arrays of characters for op1 and op2, convert each char ascii to int do the addition digit by digit then convert back to ascii and store in the output array while keeping the remainder. I would handle the case if the output size equals to the maximum possible size in a separate if condition as shown below:
//f_d num of digits of 1st operand
//s_d num of digits of 2nd operand
int sum=0,ind=0,max=0;
max=(f_d>s_d)?f_d:s_d;
while(ind<max){
sum=sum/10; //Remainder
if(f_d!=0) {sum+=argv[1][(f_d--)-1]-48};
if(s_d!=0) {sum+=argv[3][(s_d--)-1]-48};
output[max-1-ind++]=(sum%10)+48;
}
output[max]='\0';
if (sum/10!=0){
int ind=max+1;
while(ind!=0){
output[ind--]=output[ind-1];
}
output[0]=sum/10+48;
}

Why are my ASCII integer values becoming negative?

I am trying to do a very basic form of encryption and decryption by using operations on ASCII characters in C. I have the following code:
char* myEncrypt(char* stringToEncrypt)
{
char *encryptedString = malloc(256);
strcpy(encryptedString, stringToEncrypt);
int publicKey = 50;
for (int i = 0; encryptedString[i] && encryptedString[i] != '\n'; ++i)
encryptedString[i] = (encryptedString[i] + publicKey) % 256;
return encryptedString;
}
My issue is that when I run this code I am every so often getting negative values for my integer values of the ASCII characters assigned to encryptedString[i]. This is causing the decryption to fail. Looking at the code there should be no way for me to get negative values since I am using the modulo operation. Am I missing something simple here?
Many implementations use signed characters for plain chars. If you need the characters to be unsigned, then you'll need to use unsigned char.
For example, if you have a char value of 100, and you add 50, you get 150. If CHAR_MAX value is 127 (typical), then you end up with an implementation-defined value being assigned back to your character -- most likely wrapping around to -106.
Also, in C, a negative value will still be negative after a modulo operation. For example: -50 % 256 is -50. So if your original string had characters that were less than -50, you would end up with negative values after adding 50 and taking modulo 256 as well.

How to conver single Char to Long in C?

I want to convert the single char to long, this is the code:
scanf("%s",&a);
length = strlen(a);
for(j = 0; j < length; j++){
if(isdigit(a[j])){
int temp = a[j];
val = (long)temp;
printf("number: %ld\n",temp);
Push(&S, val);
}
}
but it's not working as i need, help me guys.
Your computer is most likely using the ASCII alphabet, which means that the character '1' (for example) is encoded as the number 49.
Fortunately it's easy to convert a character into its corresponding digit, by just subtracting the character '0', like in
val = a[j] - '0';
This works because the value for the character '0' equals 48, and when you do '1' - '0' it's the same as doing 49 - 48 which of course equals 1.
Even if your system isn't using the ASCII alphabet (highly unlikely) the C specification says that digits have to be encoded in a consecutive manner, so this "trick" will work no matter the actual encoding used on your system.
This "trick" is also often used to get a letter ordinal, since in ASCII the letters A to Z and a to z follows the same pattern (as you can see from the linked table). However, this is not guaranteed by the C specification, and there are character encoding schemes that are still in use that doesn't follow that (for example EBCDIC)). These encodings are not common, but might still be found on some systems.
To convert an ASCII character to an integer, you need to do val = a[j] - '0'.
The temp variable is superfluous.
As wrote in all other answers you must use a[j] - 0x30 or a[j]-'0' or a[j]-48 to have the int value of an ASCII digit.
BTW your code has another little thing to correct: %ld is not the format for int. If you compile your code with -Wall you'll get:
warning: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘int’ [-Wformat=]
Use %d instead.
Try using int temp = a[j] - '0'; instead of int temp = a[j];
This should work because the character code for numbers (digits) are continuous.
N1256 5.2.1 Character sets
In both the source and execution basic character sets, the
value of each character after 0 in the above list of decimal digits shall be one greater than
the value of the previous.
You can try this....
scanf("%s",&a);
length = strlen(a);
for(j = 0; j < length; j++){
if(isdigit(a[j])){
int temp = a[j] - 48;
val = (long)temp;
printf("number: %ld\n",temp);
Push(&S, val);
}
}
To convert into digit you have to subtract 48 from that character, which is ACII value of '0'. When you are printing only a[j] as an integer, it is printing it's ACII value, which can be from 48 to 57 for '0' to '9' respectively. So you have to subtract it to get the actual integer.

How to change a char to an integer?

I would like to copy the contents of a char array to int variables or an array. For example, the first five values have to go to an int array (int x):
char a[] = "123456";
I saw in other threads that to change a char to an int, I need to do this:
int x = a[0] - '0';
Is there other ways of doing it?
What if I wanted to the values in groups of two or more, such as 12, 34 and 56?
And what if I didn't what to save them as ints, but floats or other types instead?
Copy properly sized portions of the string to a separate buffer and use strtol() or strtod().
You are on write track, however if you want to convert into integer array then you
should use something like
int x[MAX_ELEM];
for(int i =0; i<sizeof(a)/sizeof(char); i++)
{
x[i] = a[i] -'0';
}
For other cases you will need to deal separately.
The reason you have to do int x = a[0] - '0'; is because of the character encoding in C. What is happening is you are subtracting the encoding offset from the character. Here is a table with all the encoding values: UTF-8 encodings. So int x = a[0] - '0'; is equivalent in your case to int x = 49 - 48; which has the correct value you were looking for. By using '0' instead of 0 you are using the char value of 0.
There are other ways of doing it, but this way works well. To use other types, just do type casting after you create the int.
John's way of getting two digit numbers works well. Reposted here, it was number = 10 * digit1 + digit2.
To answer your questions:
Sure, there are other ways of doing it. The way you've shown converts the ASCII value to the digit it represents, but there are other ways.
Read in the number of characters you want, convert each character to a digit, and construct the integer from those digits like number = 10 * digit1 + digit2.
Do type casting after you construct the integers.

What does the condition "if (n/10)" with integral n specify?

I am looking at the following piece of code:
void printd(int n)
{
if (n < 0) {
putchar('-');
n = -n;
}
if (n / 10)
printd(n / 10);
putchar(n % 10 + '0');
}
I understand the first if statement fine, but the second one has me confused on a couple of points.
By itself, since "n" is an integer, I understand that n/10 will shift the decimal point to the left once - effectively removing the last digit of the number; however, I am having a little trouble understanding how this can be a condition by itself without the result being equal to something. Why isn't the condition if ((n/10) >= 0) or something?
Also, why is the '0' passed into the putchar() call?
Can someone tell me how it would read if you were to read it aloud in English?
Thanks!
The n / 10 will evaluate to false if the result is 0, true otherwise. Essentially it's checking if n > 10 && n < -10 (the -10 doesn't come into play here due to the n = -n code)
The + '0' is for character offset, as characters '0'-'9' are not represented by numbers 0-9, but rather at an offset (48-57 with ascii).
Can someone tell me how it would read if you were to read it aloud in English?
If you're talking about the conditional, then I would say "if integer n divided by 10 is not zero"
n/10 will not shift the decimal number since n is an integer. The division will produce the result like this: if n = 25, then n/10 would be 2 (without any decimal points), similarly if n = 9, then n/10 would be 0 in which case if condition would not be satisfied.
Regarding the +'0', since n%10 produces an integer result and in putchar you are printing a char , you need to convert the integer to a char. This is done by adding the ascii value of 0 to the integer.
In C, there is no separate boolean type; an expression like a > b evaluates to zero if false, non-zero if true. Sometimes you can take advantage of this when testing for zero or non-zero in an int.
As for the '0', that just performs character arithmetic so that the right character is printed. The zero character has an ASCII encoding value which isn't zero, so the n value is used as an offset from that encoding to get the right numeric digit printed out.

Resources