I plan to make a program like this:
loop
read first character
read second character
make a two-digit hexadecimal number from the two characters
convert the hexadecimal number into decimal
display the ascii character corresponding to that number.
end loop
The problem I'm having is turning the two characters into a hexadecimal number and then turning that into a decimal number. Once I have a decimal number I can display the ascii character.
Unless you really want to write the conversion yourself, you can read the hex number with [f]scanf using the %x conversion, or you can read a string, and convert with (for one possibility) strtol.
If you do want to do the conversion yourself, you can convert individual digits something like this:
if (ixdigit(ch))
if (isdigit(ch))
value = (16 * value) + (ch - '0');
else
value = (16 * value) + (tolower(ch) - 'a' + 10);
else
fprintf(stderr, "%c is not a valid hex digit", ch);
char a, b;
...read them in however you like e.g. getch()
// validation
if (!isxdigit(a) || !isxdigit(b))
fatal_error();
a = tolower(a);
b = tolower(b);
int a_digit_value = a >= 'a' ? (a - 'a' + 10) : a - '0';
int b_digit_value = b >= 'a' ? (b - 'a' + 10) : b - '0';
int value = a_digit_value * 0x10 + b_digit_value;
put your two characters into a char array, null-terminate it, and use strtol() from '<stdlib.h>' (docs) to convert it to an integer.
char s[3];
s[0] = '2';
s[1] = 'a';
s[2] = '\0';
int i = strtol(s, null, 16);
Related
I am working on an encryption/decryption code for C.
Whilst I have the code encrypting and decrypting well enough there are still some errors.
I want the users input to be in between '!' (ASCII value 32) and '~' (ASCII value 126), However, when the user puts in a character such as '~' with a fairly highly offset/key-value the output is in the extended ASCII characters range. Is there any way that I can force the output to not be in the extended character range and still decrypt/encrypt properly?
I have messed around with changing the values for "cipher" but it hasn't helped too much.
Below is my code
void Encryption(char* OriginalText, int offset) {
int i = 0;
int cipher;
char encrypt;
printf("Encrypted string: \n");
while (OriginalText[i] != '\0') {
if (OriginalText[i] == ' ') {
encrypt = ' ';
printf("%c", encrypt);
i = i + 1;
}
cipher = ((int)OriginalText[i] + (offset % 26) % -26);
encrypt = (char)(cipher);
printf("%c", encrypt);
i = i + 1;
}
printf("\n");
}
The '%' operator has higher precedence than the '+'.
Therefore, it applies on the result of the exprssion offset % 26 first, and then added to OriginalText[i].
In order to fix this, you should add another pair of parenthesis in the assignment to cipher:
cipher = (((int)OriginalText[i] + (offset % 26)) % -26);
Moreover, when you're dealing with ASCII characters, just to walk on the safe side and prevent annoying and unwanted bugs, you should treat your I/O as unsigned char, hence:
unsigned char cipher;
unsigned char encrypt;
...
cipher = ((OriginalText[i] + (offset % 26)) % 26);
encrypt = cipher;
You should first convert your character to an index between zero and the size of the alphabet (exclusive), i.e. from 0 to 25 for the ABC. Only then do the modular addition / subtraction. Finally, convert back. The best way to do this is to simply perform character - 'a' (in case of lowercase characters of course). Do not perform modular operations on ASCII values itself.
I am trying to write a program in C to sum the value of an integer and a character. If the user enters an integer where the character should be, I am expecting my program to calculate the value of the 2 integers. My code below works with the user entering 2 integers but only calculates up to 9 (Ex: 4 5: "Character '4' represents a digit. Sum of '4' and '5' is 9"). If the user enters 5 6, the result is: "Character '5' represents a digit. Sum of '5' and '6' is ;". I have been searching for a while now and any potential solution always leads to the incorrect sum. I also expect my program to accept user input higher than '9' (Ex: 20 50), but if I change '9' to '99', I get the following warning: "warning: multi-character character constant [-Wmultichar]". Can someone please point me in the right direction to achieve these goals?
#include <stdio.h>
int sum (int m, char n){
return m+n;
}
int main(){
char ch;
int c;
printf("Enter an integer and a character separated by a blank> ");
scanf("%d %c",&c, &ch);
if((c >= '0' && c <= '9')||(ch >= '0' && ch <= '9')){
int cs = sum(c, ch - 0);
printf("Character '%d' represents a digit. Sum of '%d' and '%c' is %d" , c, c, ch - 0, cs);
}
return 0;
}
int cs = sum(c, ch - 0);
It looks like your trying to account for ASCII values by subtracting the ASCII value of 0 from whatever character the user enters. However, you used an integer literal of 0, when you'd want to use a character literal of '0'. See below:
int cs = sum(c, ch - '0');
Also, I would recommend renaming your int to i or something other than c. It's a little difficult to distinguish that the types of c and ch are different.
Also consider changing
if((c >= '0' && c <= '9')
to
if((c >= 0 && c <= 9)
c is an integer and you should compare it as such. By using ' ', you're basically doing a cast to a char variable which is unnecessary here.
Another problem is that I don't think you're going to be able to accomplish what you're trying to do using a char variable for a two-digit number. A char variable can hold a single character, where as a two-digit number is composed of, well, two characters.
Sorry I can't comment so I'm adding this answer for the problem abou t using only one digit.
You have a single char
char ch;
So it reads only one char, you need an array of chars like char ch[10]
Then you'd use int foo = atoi(ch) to converto your array to an integer
Basically, I have this really long string full of digits:
char *number = "insert really long number";
Now I want to perform math operations on individual digits contained in this string, let's say the following (summing two consecutive digits in this string aka array of chars):
sum = number[i] + number[i+1];
However, this does not produce the correct result, it returns a garbage value. I know how to extract a single value with printf for example:
printf("%c", number[i]);
But how can I get this %c to use in computations as above? I tried with atoi, but I get "error: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with &".
1) atoi accept string rather than single character
2) If you want to convert just one ACSII char 0 - 9 just use following code:
if(rChar >= '0' && rChar <= '9')
val = rChar - '0';
You probably want this:
char *number = "123";
int n = 0;
char c;
for (int i = 0; c = number[i]; i++)
{
n += number[i] - '0';
}
printf("n = %d\n", n);
For any number which is represented as a datatype char, you can subtract that number from '0' to get that number in integer type.
For example:
char a = '5';
int num = a - '0';
//num will store 5
Why this works?
Because if you check the ASCII value for '5', it is 53 and for '0' it is 48. So the difference is 5. This will work for converting any number in character form to integer.
The ASCII value for '0' is 48, for '1' it is 49 and so on. So the subtraction from '0' results in giving us the difference of ASCII values.
Here is a link to ASCII values: http://www.asciitable.com/
atoi convert string (const char*) to int, if you give it a char it will not work. A solution to convert a char to an int is to use the ASCII table:
char c = '9'
int v = c - '0'; // v == 9
I have the following function, which receives a tree* and a mathematical expression char*:
double calc(char *expr, tree *variaveis){}
I'd like to know how to run through the expression verifying each character? I can't use strtok() because there will not always be a delimiter.
I was trying something like:
double calc(char *expr, tree *variaveis){
int i;
dado_t retorno = 0;
double aux;
char c;
for(i=0; i < strlen(expr); i++){
c = expr[i];
if(isdigit(c)){
//Here i need to convert the C value to a double.
}
}
}
Also, I'm having a problem converting the value represented by the character to a double variable. When I debug the code in codeblocks and I set c to the digit 2 as a value, it shows me:
Variable Value
c 50 '2'
Then, when I do something like:
double aux = c; or
double aux = (double)c;
All I get is the 50 not the 2.
You need to do c - '0' to transform the character '2' to the numeric value 2:
double aux = c - '0';
It works because the characters '0' to '9' have consequent ASCII values:
if c == '0' then '0' - '0' == 0
if c == '1' then '1' - '0' == 1
if c == '2' then '2' - '0' == 2
etc.
The 50 here is the ASCII value of character '2'. As, all the character representation of the digits are having successive values,NOTE you can do something like
double aux = c - '0';
to get the digit as the int value.
FWIW, i'm not much convinced about the aux type being a double.
NOTE:
From C11, chapter ยง5.2.1
..... the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous. ....
I'm adding the following to my char[]
int index = 0;
char i = '5';
char q = '7';
char val = (i - '0') + (q - '0');
array[index] = val;
++index;
If I print out val once the value has been assigned it prints out the value as 2 (as it should). However, if I then print out my char array like so.. printf("%.*s\n",index,array); Nothing prints but empty space. Why is this happening?
You haven't added '0' back to the number you put into the array (nor have you added a NUL terminator), so it's being printed out as whatever character happens to have the value 12 in the character set (and possibly code page) you're using (followed by whatever other contents memory may contain up until the next byte that happens to contain a zero).
In the ASCII character set (and derivatives such as Unicode) character 12 is a Form Feed character. If you fed it to a printer that understood ASCII, it would probably eject that page so text after it was printed on the next page. On screen, however, there's usually not much meaning to give to it, so it'll typically show up as a blank (or possibly some special character like a smiley face or something).
Each ASCII character has an integer value. When printing a character, the underlaying system checks the value of char variable and prints the corresponding ASCII character. The value itself is not printed. See ASCII table for reference.
char var = '7'; // var's value is actually 55.
char other = 55; // This is same as '7'
When calculating the sum of two digit characters, in your case '5' and '7', you have to subtract character '0' from them to convert '5' and '7' to numbers 5 and 7.
char first = '5' - '0'; // Is actually 53 - 48 = 5
char second = '7' - '0'; // Is actually 55 - 48 = 7
char result = first + second; // 5 + 7 = 12
// When you print result, you will not see "12" printed. Instead you see a form feed special character.
char test = '5' + '7'; // 53 + 55 = 108, which is letter 'l'
You have to convert the value of char to string to print the actual value. You can convert with itoa().
char result = ('5' - '0') + ('7' - '0');
char buf[5];
memset(buf, 0, sizeof(buf));
itoa((int)result, buf, 10);
printf("%s\n", buf);
You are telling printf that it's a string, but values are not printable ASCII values.
Well, assuming you meant it prints out the value 12, that means you're trying to print character number 12 in the ASCII character set. That character (http://www.asciitable.com/) is a non-printable character.
(Same goes for character 2 also actually).
You are probably misunderstanding the value as a numeric value, and this value as a printable character.
For example, x has value 2:
char ch = 7 - 5;
... but ch is the non-printable character 2. If you want the value in ch to be printable, then you must add it again the value of '0'.
char ch = x + '0';
If the value goes beyond 9, then a more complex algorithm must be used, in order to convert a number to a string.
The format string "%.*s" requires two arguments. The first, an int, for the minimum width to print (which is index (zero) in your case) and the second, a char*, for the data itself.
Conclusion: the program is behaving correctly by printing zero characters.