C ,help me in understanding this ASCII prob - c

This code will print:
s = 1, i = 65537, f = 65537.000000, c = 1
I need help in understanding why is it printing c=1.
The code:
#include <stdio.h> // Standard input-output library
#include <stdlib.h> // Standard general utilities library
int main(void) {
int i = 65537;
unsigned short s = (unsigned short)i;
float f = (float)i;
char c = (char)i;
printf("s = %u, i = %d, f = %f, c = %d\n", s,i,f,c);
system("PAUSE");
return (0);
}

If to output the variable i in hex representation like this
#include <stdio.h>
int main(void)
{
int i = 65537;
printf( "%#0x\n", i );
return 0;
}
then you will see that it looks like
0x10001
Type char always occupies one byte. Thus in this assignment
char c = (char)i;
one byte of the object i
0x10001
^^
is stored in the variable c.
In the printf statement in your program
printf("s = %u, i = %d, f = %f, c = %d\n", s,i,f,c);
^^^^^^
it is outputted using type specifier %d. So its internal value is outputted as an integer of type int.
Usually objects of the type unsigned short occupy two bytes. Thus in this assignment
unsigned short s = (unsigned short)i;
the value in the first two bytes of object i
0x10001
^^^^
will be assigned to variable s.
So c and s the both will have value 1.

Related

Why I can't print 0 with %7.d or other %x.d in C

Can someone help me in printing 0 with %x.d i.e. %1.d, %2.d, %3.d, etc.
Actually if I'm printing 0 with %7.d and it is not showing on terminal. You can visit My GitHub for more reference.
#include <stdio.h>
int main() {
int num_1 = 0;
int num_2 = 10000;
int num_3 = 999;
printf("Value of \'num_1\' is = %7.d\n", num_1);
printf("Value of \'num_2\' is = %7.d\n", num_2);
printf("Value of \'num_3\' is = %7.d\n", num_3);
return 0;
}
The printf conversion specifier %7.d, equivalent to %7.0d, will convert an argument of type int to its decimal representation with at least 0 digits and pad it with initial spaces up to at least 7 characters.
As a special case, converting the argument value 0, yields no digits and the output will be seven spaces.
You probably do not want these semantics as you expect 0 to produce 0, so you should not specify a precision field with a .. Use %7d instead.
Note also that the \ in front of ' is not required in a C string, but it is in the C character constant '\''
Here is a modified version:
#include <stdio.h>
int main() {
int num_1 = 0;
int num_2 = 10000;
int num_3 = 999;
printf("Value of 'num_1' is = %7d\n", num_1);
printf("Value of 'num_2' is = %7d\n", num_2);
printf("Value of 'num_3' is = %7d\n", num_3);
return 0;
}
Output:
Value of 'num_1' is = 0
Value of 'num_2' is = 10000
Value of 'num_3' is = 999

atoi() not converting whole string because of special character

I have data in my .txt file containing different time ins and time outs of employees. For example, 10:20 but I initially designed the structure to have their data types to be of char arrays or string. Since I'll be using the time values in another function, I have to use the atoi() function to convert them into integer values. Problem is, there is a colon : in each of the time values. Would it be possible to convert the string 10:20 to an integer using atoi() so that I can it in my future functions? Does the use of atoi() allow some splitting or some sort so that I can convert my time value from string to int?
I tried
char time[10] = "10:20";
int val;
printf("string val = %s, int value = %d", time, atoi(time));
But my output is only
string val = 10:20, int value = 10 so only the string before the : is read and converted to string. I would want that after converting, I would stil have 10:20 as the result but in integer because I am going to use relational operators with it.
It's not clear what you actually want, but maybe something like:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
char *time = argc > 1 ? argv[1] : "10:20";
int d;
char *e;
d = strtol(time, &e, 10);
if( *e == ':' ){
d *= 100;
d += strtol(e + 1, &e, 10);
}
if( *e != '\0' ){
fprintf(stderr, "invalid input\n");
return 1;
}
printf("string val = %s, int value = %d\n", time, d);
return 0;
}
This will produce d = 1020 for the string "10:20". It's not at all clear to me what integer you want to produce, but that seems to be what you're looking for.
You can also use sscanf:
#include <stdio.h>
int main() {
char const* time = "10:20";
int h, m;
if (sscanf(time, "%d:%d", &h, &m) != 2)
return 1;
printf("string val = %s, int value = %d\n", time, h * 100 + m);
}

type conversion between pointers. Wrong print

The program is written in language C.
We ascertain that the values contained in the variables i and f have the same sequence of bits. Now go to line 63 of the program.
I create the variables ui and uf of type unsigned int.
I assign to ui the value of i converted to unsigned int.
I assign to uf the value of f converted to unsigned int.
MY QUESTION is: why when I print the contents of ui and uf I get two different values? (ui = 3281948672
uf = 4294966979). Considering that the values contained in i and f have the same binary representation, shouldn't the printing of ui and uf give me the same value? That is 3281948672.
it's strange, because when I print the contents of *ipi and *ipf, which point to i and f, they give me the same result (*ipi = 3281948672
*ipf = 3281948672). HELP ME!
Here is the source code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float f = -317.125;
int i = -1013018624;
printf("Value : %f %d\n",f,i);
printf("Indexs: %p %p\n",&f,&i);
if(i == f)
{
printf("equals\n");
}
else
{
printf("Differents\n");
}
float* pf = &f;
int* pi = &i;
printf("float *pt %p, int *pi %p\n",pf,pi);
if(*pi == *pf)
{
printf("*pt and *pi equals\n");
}
else
{
printf("differents\n");
}
void* vpf = &f;
void* vpi = &i;
unsigned int *ipf = (unsigned int *)vpf;
unsigned int *ipi = (unsigned int *)vpi;
if(*ipf == *ipi)
{
printf("*ipf e *ipi are equals why the bits contained in the pointed memory areas are the same\n");
}
else
{
printf("differents\n");
}
printf("*ipi = %u\n",*ipi);
printf("*ipf = %u\n",*ipf);
printf("*ipi in hex = %08X\n",*ipi);
printf("*ipf in hex = %08X\n\n\n",*ipf);
unsigned int ui,uf;
ui = (unsigned int)i;
uf = (unsigned int)f;
printf("ui = %u\n",ui);
printf("uf = %u",uf);
return 0;
}
In C, conversion from a floating point type to an integral type is not a bit-for-bit conversion. So, even though i and f are bit-for-bit identical, they are not converted to unsigned int in an identical way. What you see is expected behavior.

cast to pointer from integer of different size

I keep getting this warning
c:9:80: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
printf("Char= %c ASCII = %i hex = %x pointer = %p \n", i, i, i , (void*)i );
Code
#include<stdio.h>
int main (void) {
int *i;
for (int i = 75; i < 75 + 26; i++) {
printf("Char= %c ASCII = %i hex = %x pointer = %p \n", i, i, i , (void*)i );
}
return(0);
}
I fail to see what the question might be that is not answered by the compiler warning. You've got a variable "i" of type int (32 bit on 64 bit platforms), shadowing another variable called "i" in the main program.
You're casting the int variable to void*, and the compiler says you can't do that, because you are 32 bit short. Rename one of the two variables called i in your program to resolve.
You’re getting the warning because the variable “i” is declared twice in the same scope. The memory address of ‘i’ in your loop doesn’t change so what do you need the pointer outside the loop for?
#include<stdio.h>
int main (void) {
for (int i = 75; i < 75 + 26; i++) {
printf("Char= %c ASCII = %i hex = %x pointer = %p \n", i, i, i , &i );
}
return(0);
}
or yet still if you still want to have two variables.
#include<stdio.h>
int i;
int *j = &i;
int main (void) {
for ( i = 75; i < 75 + 26; i++) {
printf("Char= %c ASCII = %i hex = %x pointer = %p \n", i, i, i , (void *)j );
}
return(0);
}

copying between variables in C

I want to copy an unsigned int value to a char[2] variable. I presume the copying is straight forward since both of them have the same size (16 bits). Here's my code:
#include <stdlib.h>
#include <stdio.h>
int main()
{
unsigned short a = 63488; //16 bit value which is 1111100000000000;
unsigned char* b = malloc(2);
*b = a;
printf("%d\n",b[0]); // I expect the lower part here which is 0
printf("%d\n",b[1]); // I expect the higher part here which is 11111000
return 0;
}
But my result shows zero values. Do I have to copy each part separately? Isn't there any other easier method to do that?
Thank you
If you just want to interpret the short as a char array, you don't even need to copy. Just cast:
#include <stdio.h>
int main()
{
size_t i;
unsigned short a = 63488;
unsigned char* b = (unsigned char*)&a; // Cast the address of a to
// a pointer-to-unsgigned-char
printf("Input value: %d (0x%X)\n", a, a);
printf("Each byte:\n");
for (i = 0; i < sizeof(a); i++)
printf("b[%d] = %d (0x%X)\n", i, b[i], b[i]);
return 0;
}
Output:
$ gcc -Wall -Werror so1.c && ./a.out
Input value: 63488 (0xF800)
Each byte:
b[0] = 0 (0x0)
b[1] = 248 (0xF8)
Note that I ran this on my x86 PC, which is a little endian machine, which is why the first byte is the low byte of the input.
Also note that my code also never makes assumptions about the size of short.
Try like this
memcpy(b, &a, sizeof(a));
Or
b[0] = a & 0xFF;
b[1] = (a >> 8) & 0xFF;
Note that b is of type unsigned char so assigning to *b should be a value of the same type or the value will be truncated.

Resources