0
char *ptr=(char*)calloc(n,sizeof(int));

using the above, we can allocate memory for char array. But is reading it character-by-character mandatory? How to read and access it using%s` i.e the string format specifier?

Lundin
  • 195,001
  • 40
  • 254
  • 396

2 Answers2

2

Reading character by character is not mandatory and using exactly %s is susceptible to buffer overruns. Specifying the maximum number of characters to read, one less than the number of bytes in the buffer being populated, prevents the buffer overrun. For example "%10s" reads a maximum of ten characters then assigns the null terminating character so the target buffer requires at least 11 bytes.

However, as the code suggests that n is unknown at compile time using %s with a dynamic width is not possible explicitly. But it would be possible to construct the format specifier (the format specifier is not required to be a string literal):

char fmt[32];
sprintf(fmt, "%%%ds", n - 1); /* If 'n == 10' then 'fmt == %9s' */
if (1 == scanf(fmt, ptr))
{
    printf("[%s]\n", ptr);
}

An alternative would be fgets():

if (fgets(ptr, n, stdin))
{
}

but the behaviour is slightly different:

  • fgets() does use whitespace to terminate input.
  • fgets() will store the newline character if it encounters it.

Casting the return value of calloc() (or malloc() or realloc()) is unrequired (see Do I cast the result of malloc?) and the posted is confusing as it is allocating space for int[n] but is intended to be character array. Instead:

char* ptr = calloc(n, 1); /* 1 == sizeof(char) */

Also, if a null terminated string is being read into ptr the initialisation provided by calloc() is superfluous so a malloc() only would suffice:

char* ptr = malloc(n, 1);

And remember to free() whatever you malloc()d, calloc()d or realloc()d.

Community
  • 1
  • 1
hmjd
  • 120,187
  • 20
  • 207
  • 252
0

Yes, you can read such array using %s but make sure you have allocated enough memory for what you try to read(don't forget the terminating zero character!).

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176