Shash
Shash

Reputation: 4250

why does the string array does not discriminate the numerical values but the integer array doesn't display characters?

I came up through a strange problem where I had a string wherein it displayed all the characters and numerals without any issues. But the same thing was not possible with an integer array. As far as I know string is a NULL terminated character array. So, what makes strings different to display everything without any discrimination.

Any help is appreciated. Thanks!

Upvotes: 0

Views: 110

Answers (3)

librin.so.1
librin.so.1

Reputation: 375

/* the very answer to the question is at the bottom. A single sentence, huh. */

Since a char string is delimited with a NULL, aka 0 value, printf stops whenever it encounters one. Now let's say we have two arrays, one char and one int, like this:

char char_array[] = { 'a', 'b', 'c', '\0' };
int int_array[] = { 'a', 'b', 'c', '\0' };

now, if we were to try to print those with:

printf("char array: %s\n", char_array);
printf("int array: %s\n", (char*) int_array);

We would get this output:

char array: abc
int array: a

And even if we don't cast int_array as char*, it still does the same (compiler might complain, though). But why so? Let us check the memory that is holding those two arrays. (on little-endian) The char_array holds: 0x00636261 while the int_array holds (separated every 32 bits): 0x00000061 0x00000062 0x00000063 0x00000000

So, what happens is - printf reads a string one char, in other words, one byte at a time. Thus, when reading the int_array, it reads the first byte, that is 0x61 (character 'a'), then jumps to the next byte. But whoops! The next byte 0x00 ( 0x0000 00 61 )! That signals the end of string and it stops.

Now, let us set the values in the int_array to:

int int_array[] = { 0x61616161, 0x62626262, 0x63636363, '\0' };

it now prints int array: aaaabbbbcccc!

Since there are no longer any 0x00 gaps in the values, printf simply prints till it reaches the fourth int that we initialized to zero.

That said, if one wants to print an int array as it was a string, one either has to write a function/wrapper to build a char string holding only the values of the first byte of each int, or one that builds a string with all the 0x00 values diked out.

So, to answer Your question "what makes them different": Since this is C, all of it is just a bunch of bits, aka plain old data. So the only difference is how we treat it. With that, I bet You, if char_array is allocated continuously and is aligned, if You would use char_array as a *((int*) char_array), on little endian, it will give You a value of 6513249 ( 0x00636261 ) =]

Upvotes: 1

fhtuft
fhtuft

Reputation: 976

like this?:

#include <stdio.h>

int main(void)
{

  int a =1;
  int array[] = {1,2,3};
  const char c = 'a';
  char str[] = "hello";
  const char char_a[] ={119,111,114,108,100,0}; //ascii codes for world

  printf("this is a int: %d\n",a);
  printf("this is a int array: %d, prints only the first element of array\n",*array);
  printf("this is a int array: %d, prints only the  2. element of array\n",array[1]);
  printf("this is a char: %c\n",c);
  printf("this is a char array: %c, print only first element of str\n",*str);
  printf("this is a char array: %s, prints to \\0 \n",str);
  printf("this is a char array(made from numbers): %s, prints to 0 \n",char_a);
  return 0;
}

the options %s tells printf, that it should think about the elements in the array as chars, and that it should print this until it reach \0.

Upvotes: 1

Luchian Grigore
Luchian Grigore

Reputation: 258588

The way you instruct the compiler to print them makes them different.

When your write

printf("%s", charPtr);

you tell the compiler that it should treat charPtr as a NULL-terminated string. It looks at the memory charPtr points to and interprets each byte as a character, until it reaches a 0.

There's no equivalent for generic array types.

Upvotes: 1

Related Questions