I'm trying to use scanf to fill an array of char pointers to store the input as a string. The variable T is used to build an array of size T dynamically. Then T amount of strings are entered and displayed however when I fill in the array for example if T = 2 the first line could dog and the second line cat, it prints out "cdog" and "cat". So the first letter of the first string then the all of the 2nd string. I'm not sure where my mistake is in using char*. Any help would be appreciated.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main()
{
int T;
int i;
scanf("%d",&T);
char *new_array = (char*)malloc(T * sizeof(char));
for (i = 0; i < T; ++i)
{
scanf("%s", new_array+i);
}
for (i = 0; i < T; i++)
{
printf("%s\n", new_array+i);
}
}
- Always check the return value of
scanf()
.
You are not allocating space for pointers, but for bytes, which is the main problem, you need
char **new_array = malloc(T * sizeof(char *));
/* ^ ^ */
/* allocate pointer to poitners sizeof(pointer) */
if (new_array == NULL)
handleThisErrorAndDoNotTryToWriteTo_new_array();
you will also need space for each string so
new_array[i] = malloc(1 + lengthOfTheString);
if (new_array[i] == NULL)
handleThisErrorAndDoNotTryToWriteTo_new_array_i();
right before scanf()
, and instead of scanf("%s", new_array + i)
do this
scanf("%s", new_array[i]);
If you enable compiler warnings, the compiler should warn you that you are passing incompatible types to printf()
.
It would also be good, to use a length modifier for scanf()
to prevent buffer overflow, and don't forget to call free()
when you no longer need the pointers.
In your code, new_array
is of type char *
, which is not what you want. You have to change your definition to
char *new_array[T] = malloc(T * sizeof(char*));
Then, you can use the scanf()
as per your previous code.
Do this instead, together with the rest of the body:
int string_size;
//this begins just after reading T
scanf("%d", &string_size);
char **new_arrays = malloc(T * sizeof(char*));
for(i = 0; i < T; i++)
{
new_arrays[i] = malloc(string_size * sizeof(char));
}
The first malloc
is to specify how many strings you want, and the second malloc
is to specify how big a string can be.
Further tips:
- When you're writing in C, do not cast
void*
produced by malloc
and realloc
.
You should de-allocate the memory used in the reverse way:
for (i = 0; i < T; ++i)
{
free(new_array[i]);
}
free(new_array);
Always check if the memory allocation process is (un)succesful:
char **new_arrays = malloc(T * sizeof(char*));
if(new_arrays == NULL)
exit(0) //e.g.
for(i = 0; i < T; i++)
{
new_arrays[i] = malloc(string_size * sizeof(char));
if(new_arrays[i] == NULL)
exit(0) //e.g.
}
Check if the user provides valid values through scanf
.
Thanks everyone. The length of the strings in the char* array can not be greater than 1000 chars so thats hard coded. Here is the final working code...
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main()
{
int T;
int i;
scanf("%d",&T);
char **new_array = malloc(T * sizeof(char*));
for (i = 0; i < T ; i++)
{
new_array[i] = malloc(1000 * sizeof(char));
scanf("%s", new_array[i]);
}
for (i = 0; i < T; i++)
printf("%s\n", new_array[i]);
}