How to conver single Char to Long in C? - 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.

Related

can someone please tell why " -'0' "is being done in the fifth line of following function [duplicate]

This question already has answers here:
Why does subtracting '0' in C result in the number that the char is representing?
(8 answers)
Convert char to int in C and C++
(14 answers)
Closed 4 years ago.
m=1e9 + 7;
inline ll rem(char s[],ll m)
{
ll sum=0 , i;
for(i=0;S[i]!='\0';i++)
{
if(sum>=m)
sum %= m;
sum=(sum * 10 + S[i] - '0');
}
return sum%m;
}
here S[i] is a string of integer characters. My question is
what does -'0' does here, also can a character (here S[i]) be automatically converted to integer form is the above
sum=(sum * 10 + S[i] - '0');
equation.
First, you have to remember that characters in C are represented as tiny integers corresponding to the character's value in the machine's character set, which is typically ASCII.
For example, 'A' n ASCII is 65, and '0' is 48.
So if you're converting a string of digits to an integer, you want to do something like
int digit = c - 48;
That converts '0' to 0, '1' to 1, etc.
But that magic number 48 is mystifying, and it's theoretically also wrong on a machine using a character set other than ASCII. So the easier (because you don't have to remember that value 48), self-documenting (as long as your reader understands the idiom), and more portable way is to do
int digit = c - '0';
This works because, as I said, '0' is 48 in ASCII. But, more importantly, even on a non-ASCII machine, '0' is whatever value the character '0' has in that machine's character set, so it's always the right value to subtract, no matter what kind of machine you're using.

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 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.

char array to integer array

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.

Homework about bit sequence in C

I have a homework. The question is:
Write a function that takes as parameter a single integer, int input, and returns an unsigned character
such that:
a- if input is negative or larger than 11,111,111 or contains a digit that is not 0 or 1; then the function will
print an error message (such as “invalid input”) and return 0,
b- otherwise; the function will assume that the base-10 value of input represents a bit sequence and return the magnitude-only bit model correspondent of this sequence.
For Example: If input is 1011, return value is 11 and If input is 1110, return value is 14
This is my work for a, and I am stuck on b. How can I get bit sequence for given integer input?
int main()
{
int input = 0;
printf("Please type an integer number less than 11,111,111.\n");
scanf("%d",&input);
if(input < 0 || input > 11111111)
{
printf("Invalid Input\n");
system("PAUSE");
return 0;
}
for (int i = 0; i < 8; i++)
{
int writtenInput = input;
int single_digit = writtenInput%10;
if(single_digit == 0 || single_digit == 1)
{
writtenInput /= 10;
}
else
{
printf("Your digit contains a number that does not 0 or 1. it is invalid input\n");
system("PAUSE");
return 0;
}
}
printf("Written integer is %d\n",input);
system("PAUSE");
return 0;
}
The bit that you are missing is the base conversion. To interpret a number in base B, what you need to do is multiply digit N times B^N (assuming that you start counting digits from the least significative). For example, in base 16, A108 = (10)*16^3 + 1*16^2 + 0*16^1 + 8*16^0. Where in your base is 2 (binary).
Alternatively, you can avoid the exponentiation if you rewrite the expression as:
hex A008 = ((((10*16) + 1)*16 +0)*16 + 8
Which would be simpler if your input was stated in terms of an array of possibly unknown length as it is easily convertible into a loop of only additions and multiplications.
In the particular case of binary, you can use another direct solution, for each digit that is non-zero, set the corresponding bit in an integer type large enough (in your case, unsigned char suffices), and the value of the variable at the end of the loop will be the result of the conversion.
First off, the existing part of your code needs work. It doesn't report non-binary digits correctly. The question is "Are there any digits that are neither 0 nor 1". To answer this question in the negative, you need to check every single digit. Your code can terminate early. I also suggest renaming the function to something that clearly tells you what it does. For example haveNonBinaryDigit. The term check doesn't tell you what you should expect on the return value.
As for the second part, read up on the binary representation. It is fairly similar to decimal, except that instead of each digit being weighted by 1, 10, 100, .., 10^x, they are weighted by 1, 2, 4, ..., 2^n. Also the digits can only have values 0 and 1.
Your current code has a problem: it will terminate as soon as it finds one single binary bit (at the end) and call the entire integer correct.
I would take a different approach to this problem. What you want to do is get your hands on every single digit from the integer seperately. You made a good start in doing so by using modulo. Say you had this code:
for (int i = 0; i < 8; i++)
{
char single_digit = input%10;
input /= 10;
}
This makes it easy to start working with the digits. You would be checking 8 bits because that seems to be the maximum allowed (11,111,111). Check if each digit is either 0 or 1. Then you can start pushing it in to an unsigned character using bitwise operations. Shift every digit to the left by i, then use a bitwise OR.

Resources