integers in char array - c

I want know how integers are treated in char arrays. For example when we use scanf() & printf() functions for single characters we use "%c", for string values "%s", etc. I used "%s" for printing the char array with integers. But it prints some junk characters as the output.

While working with integer variables directly, it's simple as:
int i = 7;
printf("%d", i);
and while working with an array of characters, you could create helper functions that will do the conversion between char* <-> int so that you end up with more portable solution:
int toInt(unsigned char* p) {
return *(p + 0) << 24 | *(p + 1) << 16 | *(p + 2) << 8 | *(p + 3);
}
...
unsigned char arr[4] = {0,0,0,4};
int i = toInt(&arr[0]);
printf("%d", i);
should print 4
Alternatively you might use simple cast:
unsigned char arr[4] = {0,0,0,4};
int* i = &arr[0];
printf("%d", *i);
but that solution will be depend on endianness. On ideone.com it prints 67108864.

If you know the length of each phone number will be the same, you could pad out the front of the number with zeros. e.g. to pad each number out to 10 digits, putting 0's in front when necessary:
int d = 123456789;
printf("%d\n", d); // prints 123456789
printf("%010d\n", d); // prints 0123456789
d = 12345678;
printf("%010d\n", d); // prints 0012345678 :-(
It's hard to guess more about the requirements without seeing the code. There's lots of examples of formatting with printf, eg: http://www.codingunit.com/printf-format-specifiers-format-conversions-and-formatted-output

Related

Print bits from argv

I'm sure the answer is simple but I can't get my head around so I hope you can help me :)
I'm trying to print the bits of a unsigned char, here with the value 2, the issue is that I get a wrong answer when casting from argv[1][0] and the good one when sending directly the number 2.
void print_bits(unsigned char octet)
{
int i;
unsigned char b;
i = 8;
while (i--)
{
b = (octet >> i & 1) + '0';
write(1, &b, 1);
}
}
int main(int argc, char **argv)
{
print_bits((unsigned char)argv[1][0]);
write(1, "\n", 1);
print_bits(2);
write(1, "\n", 1);
return (0);
}
gives me :
00110010
00000010
I notice when debugging that, if I print the "octet" variable at the start of print_bits, I get the ASCII value of 2 when casting from argv and the value "\002" when directly inputting the value 2.
It feels like a casting issue ?
Thank you!
char are just integers, when you input '2' from argv, it reads the character '2' (which is equal to 50 in ASCII). In your second case, you input the int 2, hence the two different outputs. Your function is correct and so is the output.

What is a problem in this code(c language)

# include <stdio.h>
int main(void)
{
char a[]="0123456789";
char b[5];
a[5]='\0';
char *c=a;
for(int i=0,j=sizeof(b)/sizeof(char);i<j;i++){
*(b+i)=*(c+(7*i));
}
printf("%d\n", sizeof(a)/sizeof(char));
printf("%s\n", a);
printf("%s\n", b);
printf("%c\n", *(b+3));
return 0;
}
There is no one output in this code
4 outputs are needed but one output is missing and I don't know why it happens and how to solve this problem
Let me walk you through what is happening.
I've modified your code slightly to make it easier to read
#include <stdio.h>
int main(void)
{
char a[]="0123456789"; //a is 11 chars long [0,1,2,3,4,5,6,7,8,9,\0]
char b[5]; //b is 5 chars long and we don't know what's in it
a[5]='\0'; //a now looks like this [0,1,2,3,4,\0,6,7,8,9,\0]
char *c=a; //c points to a
for(int i=0; i < sizeof b / sizeof(char); i++){ //j is unnecessary here
b[i] = c[7 * i]; //This is equivalent to your code and is easier to read
}
//If the program hasn't crashed, b now looks like this [0,7,?,?,?]
//(where ? means it could be anything at all)
printf("%zd\n", sizeof a /sizeof(char)); //We expect 11 to print (%zd is for size_t)
printf("%s\n", a); //Strings end at \0 so we expect "01234"
printf("%s\n", b); //We expect "07..." but we have no idea what comes next
printf("%c\n", b[3]); //This could do anything
return 0;
}
In your for loop, you initialize the 5-character array b with c[0], c[7], c[14], c[21], and c[28].
You initialized c by pointing it to a, so c[0] is the same as a[0], c[7] is the same as a[7] etc.
Since a is only 11 characters long, we can be certain that b[0] = '0' and b[1] = '7' but after that we've invoked undefined behavior and we have no idea what will happen. It is entirely possible that the program will crash after printing...
11
01234
07
or it could do something completely unexpected.

extract a character and various short ints from the same void pointer in C

I'm trying to accomplish the following:
given the function:
int f(void *p)
take the first byte of p and extract it as a character. Then based on what that character is determine which additional bytes to extract as short ints. For example if I have a certain character c then extract byte 4 and 7 as short ints and store them in separate variables; if I have a certain different character d extract bytes 3, 4, 5 and store them as separate variables. With this information execute some other irrelevant code. I've been struggling with this for hours.
I tried the following:
int f(void *p) {
char *first = &p;
short int *third = p + 2;
short int *fifth = p + 4;
short int *seventh = p + 6;
printf("%s %s %s, %s", first, third, fifth , seventh);
}
int main(int argc, char const *argv[]) {
char test[] = "*5431234567";
f(test);
}
My result:
▒▒ϲ -1295010922 -1295010920, -1295010918
Expected:
* 4 1 3
After a while I realized I was attempting to de-reference a void pointer which does not work. So I tried casting:
char* c = (char*) p;
char first = (char) (*c)
printf("%s", first);
This gave me a seg fault.
I tried similar things with short int casting to no avail. If this is a somewhat noobish question I apologize. I'm new to C and the whole concept of pointers and references is new to me. My first language was Java which is much more forgiving.
Your input is a string, and your expected output are individual characters within the string. There is nothing short int-like about this problem.
char *s = p;
printf("%c %c %c, %c", s[0], s[2], s[4] , s[6]);
If you need to store those values into short int variables, then you do not need pointers.
short int x = s[2] - '0';
short int y = s[4] - '0';
short int z = s[6] - '0';
printf("%c %hd %hd %hd\n", s[0], x, y, z);
The characters that represent the decimal digits are guaranteed to be contiguous, so you can compute the ordinal value by calculating the offset from '0'.
char *first = &p;
Get rid of the &. You don't want the address of the p variable, you want the address stored in it, which is simply p.
char *first = p;
short int *third = p + 2;
short int *fifth = p + 4;
short int *seventh = p + 6;
printf("%s %s %s, %s", first, third, fifth, seventh);
There's no reason to be using short pointers. The elements of a string are chars, not shorts. Even when they're digits, they're still chars.
Leave them as chars, switch to %c to print them, and make sure to dereference the pointers when you do.
char *third = p + 2;
char *fifth = p + 4;
char *seventh = p + 6;
printf("%c %c %c %c\n", *first, *third, *fifth, *seventh);

Store an integer in char array in C

Running the code below prints b = and i = 15.
int i = 15;
char b = (char) i;
printf("b = %c and i = %d\n", b, i);
How can I store this integer in the character? At the end I'm trying to have a char array of size 1024 which has i (15) as the first character and rest 0.
update: I tried :
int i = 15;
char buffer[1024];
snprintf(buffer, 10, "%d", i);
printf("buffer[0] = %c, buffer[1] = %c\n", buffer[0], buffer[1]);
And the result printed was:
buffer[0] = 1 , buffer[1] = 5
You did store the integer in the character, it's just that %c converts a character to its ASCII value. All ASCII values below 31 are non-printable.
If you run
printf("b = %d and i = %d\n", (int)b, i);
it will print 15.
If you want a representation of i as a string:
char buf[12]; //Maximum number of digits in i, plus one for the terminating null
snprintf(buf, 12, "%d", i);
This will store a string representation of i in buf.
A char is an 8-bit unsigned value (0 - 255) and it does indeed store 15 in it, the problem is, that in ASCII table 15 means "shift in" non-printable character, and %c interprets the value as an ascii character.
char b = (char) i;
printf("b = %d and i = %d\n", b, i);
to get
b = 15 and i = 15
if you used i = 90 in your current code, this would be printed:
b = Z and i = 90
The problem here is, variable b already has a value 15 but since this does not constitute to a printable ASCII, using %c format specifier, you won't be able to see any output.
To print the value, use %hhd format specifier.
At the end I'm trying to have a char array of size 1024 which has i (15) as the first character and rest 0.
Well, you can define an array and assign values accordingly. Something like
#define SIZE 1024
char arr [SIZE] = {0}; //initialization, fill all with 0
arr[0] = 15; //first value is 15
should do the job.
Clarification:
The range of char is -128..127.
The range of unsigned char is 0..255.
If capturing ASCII values is the goal, declaring buffer variable to unsigned char type seems to be more appropriate.
You can't store Integer datatype in Character datatype(datatype conflict).
But what you are want, can be achieved by taking 2-dimensional character array.
char b[1024][1024];
itoa(i,b[0],20); ///
for(int i = 1 ; i < 1024 ; i++)
itoa(0,b[i],20);
Function itoa converts integer into character array and stores it into the character array. Hope it helps.
click here for more info :)

shifting array element one by one

I got a homework question. I'm so close to complete program. I'm having trouble about one thing. This is the question:
Write a C program that generates and displays a character array of size 10 consisting of
random English lower-case letters. The program then asks the user how many times the array
will be right-shifted and displays the right shifted array at each right-shifting step. A sample
program execution output is given below. ( Hint: Use the ASCII codes of the English lower-case
letters which are 97, 98, ... 122 for a, b, ..., z, respectively, to generate the character array).
This is my code:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
void print_string (char *string){
int i;
for (i=0 ; i < 10 ; i ++){
printf("%c ", string[i]);
if (i == 9)
printf("\n");
}
}
void random_string(char *string, unsigned length)
{
/* Seed number for rand() */
srand((unsigned int) time(0) + getpid());
/* ASCII characters 97 to 122 */
int i;
for (i = 0; i < length; ++i)
{
string[i] = (rand() % 26)+ 97;
}
string[i] = '\0';
}
void reverse_string(char* str, int left, int right) {
char* p1 = str + left;
char* p2 = str + right;
while (p1 < p2) {
char temp = *p1;
*p1 = *p2;
*p2 = temp;
p1++;
p2--;
}
}
void rotate(char* str, int k, int n) {
reverse_string(str, 0, n-1);
reverse_string(str, 0, k-1);
reverse_string(str, k, n-1);
}
int main(void)
{
char s[11];
int i,shiftNum;
random_string(s, 11);
printf("Randomly constructed array is :\n");
print_string(s);
printf("Enter how many times array will be shifted: ");
scanf("%d",&shiftNum);
rotate(s,shiftNum,11);
print_string(s);
}
What's wrong with this code? When I execute it with 1, I couldn't get the first reverse correctly and I want to display all shifting steps.
For a start, it is atrocious that your lecturer/professor is telling you to use 97..122. C does not require that ASCII be the character set on every system, so this code is entirely non-portable, yet if you look at the history as far as Unix is concerned C is supposed to be a portable programming language. If you want to write this in a portable way, you need to store the characters in an array and select from that array:
char lowercase[] = "abcdefghijklmnopqrstuvwxyz";
string[i] = lowercase[rand() % (sizeof lowercase - 1)];
Now that we've covered that pedantic detail, Cool Guy indicated in a comment that this line of code is erroneous: string[i] = '\0';. He's correct about that.
This should also performed within main, not within random_string: srand((unsigned int) time(0) + getpid());. The reason is that calling random_string multiple times in the same second would result in the same "random string", which is very uncool.
scanf("%d",&shiftNum); can't guarantee success (that the user will input numeric data), and so can't guarantee that shiftNum will contain a sane value. You need to check the return value. For example:
if (scanf("%d", &shiftNum) != 1) {
puts("Invalid shift count!\n");
exit(0);
}
You should probably also consider using an unsigned type for shiftNum (and this will cause the corresponding format spec %d to change to something else, such as %u for unsigned int).
One more important task before I finish this task: You need to modify rotate to handle an input of 0 correctly, since some users might want to rotate/shift 0 times (as an alternative to not rotating/shifting at all). I'm confident that this should be an easy task for you.

Resources