Char shifting in C - c

I am trying to find the function in the library that shifts chars back and forward as I want
for instance:
if this function consumes 'a' and a number to shift forward 3 , it will be shifted 3 times and the output will be 'd'.
if it this function consumes '5' and a number to shift forward 3 , it will be shifted 3 times and the output will be '8'.
how can I achieve this?

You don't need to call a function to do this. Just add the number to the character directly.
For example:
'a' + 3
evaluates to
'd'

Given what you've asked for, this does that:
char char_shift(char c, int n) {
return (char)(c + n);
}
If you meant something else (perhaps intending that 'Z' + 1 = 'A'), then rewrite your question...

In C, a char is an integer type (like int, and long long int).
It functions just like the other integer types, except the range of values it can store is typically limited to -128 to 127, or 0 to 255, although this depends on implementation.
For example:
char x = 3;
char y = 6;
int z;
z = x + y;
printf("z = %d\n", z); //prints z = 9
The char type (usually as part of an array) is most often used to store text, where each character is encoded as a number.
Character and string constants are a convenience. If we assume the machine uses the ASCII character set (which is almost ubiquitous today), in which case capital A is encoded as 65, then:
char x = 'A';
char str[] = "AAA";
is equivalent to
char x = 65;
char str[] = {65, 65, 65, 0};
Therefore, something like 'X' + 6 makes perfect sense - what the result will be depends on the character encoding. In ASCII, it's equivalent to 88 + 6 which is 94 which is '^'.

Related

Is it possible to store a character in an array which is defined as an integer?

How could the array defined as int store the string values? Just look at the code, arri[] is defined as an integer but storing string values? And also the array defined as a character is storing integer values. How is this possible?
int main(void) {
int arri[] = {'1' , '2', 'a'};
int *ptri = arri;
char arrc[] = {11, 21 , 31 };
char *ptrc = arrc;
printf("%d" , *arri);
printf("%d" , *ptri);
printf("%d" , *arrc );
printf("%d" , *ptrc);
return 0;
}
How could the array defined as int store the string values?
There are no strings in the code snippets you provided.
In this declaration
int arri[] = {'1' , '2', 'a'};
the initializers that represent integer character constants having the type int are used to initialize elements of the array. These character constants are stored internally as their codes. For example in the ASCII character table the integer character constants internally have correspondingly values 49, 50, and 97.
Here is a demonstrative program
#include <stdio.h>
int main(void)
{
int arri[] = {'1' , '2', 'a'};
const size_t N = sizeof( arri ) / sizeof( *arri );
for ( size_t i = 0; i < N; i++ )
{
printf( "'%c' = %d ", arri[i], arri[i] );
}
putchar( '\n' );
return 0;
}
The program output is
'1' = 49 '2' = 50 'a' = 97
When the conversion specifier %c is used the function printf tries to output them as (graphical) symbols.
Pay attention to that when the conversion specifier %d is used to output an object of the type char then there is performed the integer promotion that promotes the object of the type char to an expression of the type int.
In this declaration
char arrc[] = {11, 21 , 31 };
the integer constants have values that fit into the range of values that can be stored in an object of the type char.
In the both cases there is no truncation or overflow.
The first thing to make clear is that don't actual store a character like 'a' anywhere inside the computer. You actually store a number. For 'a' that number is decimal 97. The computer itself has no knowledge about this being an 'a'. The computer only sees it as a number. It's only when you send that number to a device expecting characters (e.g. a terminal, a printer, etc) that some device driver changes the number to display of the character 'a'.
See https://en.wikipedia.org/wiki/ASCII for a description of the mapping between charcters and numbers.
The C standard allows you to use characters just as-if they were numbers. The compiler automatically converts the character to the corresponding number. Therefore
int x = 'a';
is exactly the same as
int x = 97;
and your line
int arri[] = {'1' , '2', 'a'};
is the same as
int arri[] = {49 , 50, 97};
As already mentioned the type char is just storing numbers - just like the type int. The difference is just the range of numbers that can be stored. Typically a char is 1 byte of memory and int is 4 bytes (but it's system dependant).
So this code
char arrc[] = {11, 21 , 31 };
simply stores those 3 decimal numbers. Typically using 1 byte for each number.
The interresting part is this line:
printf("%d" , *arrc );
Here *arrc is the number 11 stored in 1 byte (typically). So how can it be printed using %d which expects an int ?
The answer is "Default argument promotions". For variadic functions (like printf) this means that integer types "smaller" than int shall be converted to int before the function call. Note that char is considered an integer type so this also applies for char.
So in your case the number 11 stored in char (1 byte) will automatically be converted to the number 11 stored in int (4 bytes). Consequently the printf function will receive an int and will be able to print is as such.
In the statement
int foo = 3.14159;
the double value is automatically converted to int (to 3) [implicit conversion]. There is nothing that prohibits the conversion, so the assigment ("of a double to an int") is ok.
Same thing with your example
char foo = 65; // the int value is implicitly converted to type char
char bar[] = { 66, 67, 0 }; // 3 conversions ok
char baz = 20210914; // possibly erroneous conversion from int to char
// in this case the compiler will, probably, warn you
// 20210914 is beyond the range of char, so this is, technically, UB
Note that
int a = 'b';
the 'b' above is a value of int type, so there really is no conversion.
char b = 'c'; // implicit conversion from int to char ok
int c = b; // implicit conversion from char to int ok

Issue with turning a character into an integer in C

I am having issues with converting character variables into integer variables. This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char string[] = "A2";
char letter = string[0];
char number = string[1];
char numbers[] = "12345678";
char letters[] = "ABCDEFGH";
int row;
int column;
for(int i = 0; i < 8; i++){
if(number == numbers[i]){
row = number;
}
}
}
When I try to convert the variable row into the integer value of the variable number, instead of 2 I get 50. The goal so far is to convert the variable row into the accurate value of the character variable number, which in this case is 2. I'm a little confused as to why the variable row is 50 and not 2. Can any one explain to me why it is not converting accurately?
'2' != 2. The '2' character, in ASCII, is 50 in decimal (0x32 in hex). See http://www.asciitable.com/
If you're sure they're really numbers you can just use (numbers[i] - '0') to get the value you're looking for.
2 in your case is a character, and that character's value is 50 because that's the decimal version of the byte value that represents the character 2 in ASCII. Remember, c is very low level and characters are essentially the same thing as any other value: a sequence of bytes. Just like letters are represented as bytes, so are the character representation of their value in our base 10 system. It might seem that 2 should have been represented with the value 2, but it wasn't.
If you use the atoi function, it will look at the string and compute the decimal value represented by the characters in your string.
However, if you're only converting one character to the decimal value it represents , you can take a short cut. subtract the digit from the value of '0'. Though the digits are not represented by the base 10 value they have for us humans, they are ordered sequentially in the ASCII code. And since in C the characters are simply byte values, the difference between a numeric character 0-9 and 0 is the value of the character.
char c = '2';
int i = c - '0';
If you understand why that would work, you get what I'm saying.

K&R 1.6 Arrays // Digit representation in an array construct

I found this example code on using arrays in the C language.
#include <stdio.h>
main () {
int c, i;
int ndigit[10];
for (i = 0; i < 10; ++i)
ndigit[i]=0;
while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c - '0'];
printf("digits =");
for (i = 0; i < 10; ++i)
printf(" %d", ndigit[i]);
}
I never saw arrays before, but I think I got it.
Still, I'm not sure on why the digit values have to be inserted in '..' nor why the assignement of i has to be expressed as c-'0'.
This is a passage of the book that should clarify my doubts:
This particolar program relies on the properties of the character representation of the digits. For example the text if (c >= '0' && c <= '9') determines whether the characters in c is a digit. If it is, the numeric value if that digit is c - '0'.
I don't understand how can these values be used in arithmetical expressions if they are characters, is it because they are mapped to numerical values?
Then why the whole program just doesn't work if they are written as numbers as in if (c >= 0 && c <= 9) nor it works if c isn't written in that way (which to my understanding is just "whatever number c is minus 0).
TL;DR: a "char" is just a one-byte-long integer.
I don't understand how can these values be used in arithmetical expressions if they are characters, is it because they are mapped to numerical values?
In C, a char is the "smallest addressable unit of the machine that can contain basic character set. It is an integer type." [1]. Normally, char is equivalent to "a one-byte-long integer", so they can hold values from 0 to (2^8)-1, or [0,255].
That being said, when you write
char c = '9';
You are saying "c is a one-byte-long integer whose value is the character-set representation of the character 9". By looking at the most common character set, the ASCII table [2], we see that the character 9 has an integer value of 57, so the above expression is equivalent to
char c = 57;
To convert a digit's character-set value to the digit itself (e.g. '9' to 9, or 57 to 9), you can rely on a property of character sets that digits are always stored sequentially and increasingly, and just subtract by the value of '0', which in ASCII is 48, so:
char c;
c = '9' - '0'; /* = 9 In any character set */
c = 57 - 48; /* = 9 */
c = '9' - 48; /* = 9 In ASCII */
c = 57 - '0'; /* = 9 In ASCII */
Keep in mind that while ASCII is the most common character set, this is actually machine-dependent.
[1] http://en.wikipedia.org/wiki/C_data_types#Basic_types
[2] http://www.asciitable.com/
if you see the man page of getchar() it says
....reads the next character from stdin and returns it as an unsigned char cast to an int....
So, an input of a digit [example, 9] is treated as a char input and the corresponding encoded [Usually ASCII] value is returned by getchar().
Now coming to your question(s),
why the digit values have to be inserted in '..'
A digit [or any other character, for that matter], written as '.', represents the corresponding ASCII value of the same. Check the ASCII table here.
For understanding, a 9 is a 9 whereas a '9' represents the correcsponding ASCII 57.
why the assignment of i has to be expressed as c-'0'.
If you notice the ASCII table closely, you can see, the corresponding values of 0 to 9 are in sequence. So, to get the particular digit as an int value, we can do c - '0' which is same as c - 48 which will give us the digit as an int.
I don't understand how can these values be used in arithmetical
expressions if they are characters, is it because they are mapped to
numerical values?
getchar() returns the character read.Prototype for it is
int getchar(void)
When a character is read getchar() returns the ASCII value of the char read.
The ASCII value for char's 0 to 9 are contiguous. So just making use of it if we have
char ch = '5';
int i = ch - '0'; /* 53 - 48 = 5 */
will give you the integer value 5. Converting character to integer. The arithmetic is performed by implicit conversion.
If you have a character '8' then this doesn't give you the integer value 8 but retuns ASCII value 56. So during arithmetic ch - '0' since both are char's the respective ASCII values are used and the arithmetic operation is performed

How do I get an int from a string in C with no whitespace?

So I have a string like this: "MULTR12"
I want to get '1' and '2' as two seperate integers. How do I go about doing that? Before, I had it simply as:
char *string = "MULTR12";
val = string[5];
But I get a really weird value for val instead of 1, like I want. Can anyone help? Thanks!
This is how you convert a char to int ..
int x = string[5] - '0';
Here's some explanation.. Every character is represented as an ASCII character in memory, A will be 65 and simliar. This also applies to numbers, so 0 in ASCII is 48, 1 is 49 etc.
Now, when we subtract 0 from any number's ASCII representation. Let's say the number is 5, this is what we are actually doing..
int x = 53 - 48
which gives us 5 as an integer. In other words, we are calculating the displacement of that numbers ASCII representation from 0's ASCII representation.
A bit hackish but try
val = string[5] - '0';
Shamelessly stolen from here
What you are trying to do above, is basically take the ASCII representation of the char '1' and convert it to an int, yielding 49. (probably not what you expected)
You can do something like this:
int num = string[ 5 ] - '0';
Actually you are getting a weird value because you are trying to change the value of a string that is fixed.
First take a new array as char str[]="Multr12";
Now you can access str[5]...try this

ASCII and printf

I have a little (big, dumb?) question about int and chars in C. I rememeber from my studies that "chars are little integers and viceversa," and that's okay to me. If I need to use small numbers, the best way is to use a char type.
But in a code like this:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int i= atoi(argv[1]);
printf("%d -> %c\n",i,i);
return 0;
}
I can use as argument every number I want. So with 0-127 I obtain the expected results (the standard ASCII table) but even with bigger or negative numbers it seems to work...
Here is some example:
-181 -> K
-182 -> J
300 -> ,
301 -> -
Why? It seems to me that it's cycling around the ascii table, but I don't understand how.
When you pass an int corresponding to the "%c" conversion specifier, the int is converted to an unsigned char and then written.
The values you pass are being converted to different values when they are outside the range of an unsigned (0 to UCHAR_MAX). The system you are working on probably has UCHAR_MAX == 255.
When converting an int to an unsigned char:
If the value is larger than
UCHAR_MAX, (UCHAR_MAX+1) is
subtracted from the value as many
times as needed to bring it into the
range 0 to UCHAR_MAX.
Likewise, if the
value is less than zero, (UCHAR_MAX+1)
is added to the value as many times
as needed to bring it into the range
0 to UCHAR_MAX.
Therefore:
(unsigned char)-181 == (-181 + (255+1)) == 75 == 'K'
(unsigned char)-182 == (-182 + (255+1)) == 74 == 'J'
(unsigned char)300 == (300 - (255+1)) == 44 == ','
(unsigned char)301 == (301 - (255+1)) == 45 == '-'
The %c format parameter interprets the corresponding value as a character, not as an integer. However, when you lie to printf and pass an int in what you tell it is a char, its internal manipulation of the value (to get a char back, as a char is normally passed as an int anyway, with varargs) happens to yield the values you see.
My guess is that %c takes the first byte of the value provided and formats that as a character. On a little-endian system such as a PC running Windows, that byte would represent the least-significant byte of any value passed in, so consecutive numbers would always be shown as different characters.
You told it the number is a char, so it's going to try every way it can to treat it as one, despite being far too big.
Looking at what you got, since J and K are in that order, I'd say it's using the integer % 128 to make sure it fits in the legal range.
Edit: Please disregard this "answer".
Because you are on a little-endian machine :)
Serously, this is an undefined behavior. Try changing the code to printf("%d -> %c, %c\n",i,i,'4'); and see what happens then...
When we use the %c in printf statement, it can access only the first byte of the integer.
Hence anything greater than 256 is treated as n % 256.
For example
i/p = 321 yields op=A
What atoi does is converting the string to numerical values, so that "1234" gets 1234 and not just a sequence of the ordinal numbers of the string.
Example:
char *x = "1234"; // x[0] = 49, x[1] = 50, x[2] = 51, x[3] = 52 (see the ASCII table)
int y = atoi(x); // y = 1234
int z = (int)x[0]; // z = 49 which is not what one would want

Resources