I want to create a new array with the same size of "chaine" but only after the function
char chaine[Lenght]; //Lenght = 20
function(chaine, sizeof(chaine));
When I called "function" the size of "chaine" is changing randomly.
The new array "chaine2" also needs to be full of " * " characters.
Let met try to explain with some printf :
printf("chaine = %s\n", chaine);
will show on screen something like : chaine = WORDS (5 characters)
And i want "chaine2" to be shown like this : chaine2 = ***** (5 stars)
I apologize for my english, thank you for reading
#include <stdio.h>
#include <stdlib.h>
char *dup_and_fillStar(const char *src, const size_t size){
char *p,*ret;
ret=p=(char*)malloc(sizeof(char)*size);
while(*src++)
*p++='*';
*p = '\0';
return ret;
}
#define Length 20
int main(void){
char chaine[Length] = "WORDS";
char *chaine2;
chaine2 = dup_and_fillStar(chaine, sizeof(chaine));
printf("chine = %s\n", chaine);
printf("chine2 = %s\n", chaine2);
free(chaine2);
return(0);
}
Remember that char arrays are special, in the sense that they have a size, which you specify when you declare them, and a length, which depends on their contents. The size of an array is the amount of memory that's been allocated to it. The length of a string is the number of characters before a terminating null ('\0').
some_func() {
int len = 20; // Size of the array
char chaine[len]; // Uninitialized array of size 20.
memset(chaine, '\0', sizeof(chaine)); // Init to all null chars, len = 0
strcpy(chaine, "WORDS"); // Copy a string, len = 5
char *chaine2 = function(chaine, sizeof(chaine));
printf("%s\n", chaine2);
free (chaine2);
}
When you pass an array to a function, it's treated like a pointer. So sizeof(str) inside the function will always return the size of pointer-to-char, and not the size of the original array. If you want to know how long the string is, make sure it's null-terminated and use strlen() like this:
char *function(char *str, int len) {
// Assume str = "WORDS", len = 20.
char *new_str = malloc(len); // Create a new string, size = 20
memset(new_str, '\0', len); // Initialize to nulls
memset(new_str, '*', strlen(str)); // Copy 5 '*' chars, len = 5
return new_str; // Pointer to 20 bytes of memory: 5 '*' and 15 '\0'
}
I'm going to assume that you're using C99 (and so are able to use variable length arrays).
If you want to create the array outside of function() (where chaine is still an array), you can simply do:
char chaine2[Lenght];
Or, probably better:
char chaine2[sizeof(chaine)];
If you're inside function(), note that chaine will be a pointer, since the compiler sees an array definition in a function parameter as a pointer to it's first element (if this is confusing, remember that pointers are not arrays)
So, even if function is defined like this:
function(char chaine[], size_t length) {
the compiler will see it as:
function(char *chaine, size_t length) {
Either way, you can create chaine2 by saying:
char chaine2[length];
but NOT
char chaine2[sizeof(chaine)]; // DONT DO THIS
since the sizeof will return the size of the pointer instead of the size of the array.
However you create it, if you want to fill the new array with '*' characters, you can use memset():
memset(chaine2,'*',sizeof(chaine2));
Related
I need to intialize an empty array of strings with fixed size ( 3 by 100 for example), pass it to a function to fill it with data and perform things like strcpy(), strcmp(), memset() on it. After the function is terminated I need to be able to read the data from my main().
What I tried so far:
char arrayofstrings[3][100] = {0};
char (*pointer)[3][100] = &arrayofstrings;
function(pointer);
Initalizing an (empty?) array of strings and initializing a pointer on the first element.
int function (char (*pointer)[3][100])
{
strcpy((*pointer)[i], somepointertostring);
strcmp((*pointer)[i], somepointertostring)
memset((*pointer)[i], 0, strlen((*pointer)[i]));
}
Is this a good way to do it? Is there an easier way to do it? Whats up with the brackets around the pointer?
C string functions expect a buffer to be null-terminated. Your arrayofstrings allocation happens on the stack. Depending on your compiler it might be initialized to all zeros or might contain garbage.
The simplest way in your case to make sure string functions won't overrun your buffers is to set the first character of each to 0 (null)
arrayofstrings[0][0] = 0x00;
arrayofstrings[1][0] = 0x00;
arrayofstrings[2][0] = 0x00;
This will give you 3, 100-char buffers that contain a valid empty "string". Note that you can only store 99 "characters" because the last character must be 0x00 (null-terminator).
char (*pointer)[3][100] = &arrayofstrings;
This is unnecessary.
Something to keep in mind about arrays in C is that the [] index is really only there to make things easier for the human programmer. Any array definition is simply a pointer to memory. The values inside the [][]...[] indexes and the type are used by the compiler to allocate the right amount of memory on the stack and do some simple math to come up with the right memory address for the element you want to access.
char arrayofstrings[3][100];
This will allocate sizeof(char)*3*100 bytes on the stack and give you a char* called 'arrayofstrings'. There's nothing special about the char* itself. It would be the same pointer if you had char arrayofstrings[300] or char arrayofstrings[3][10][10] or even long arrayofstrings[75] (char is 1 byte, long is 4 bytes).
Because you declared it as a multidimensional array with [a][b], when you ask for arrayofstrings[x][y], the compiler will calculate ((x*b)+y)*sizeof(type) and add it to the arrayofstrings pointer to get the address of the value you want. But because it's just a pointer, you can treat it like any other pointer and pass it around or cast it to other types of pointer or do pointer math with it.
You don't need the extra level of indirection.
An array, when passed to a function, is converted to a pointer to its first member. So if you declare the function like this:
int function(char (*pointer)[100])
Or equivalently:
int function(char pointer[][100])
Or:
int function(char pointer[3][100])
You can pass the array directly to the function:
function(arrayofstrings);
Then the body could look something like this:
strcpy(pointer[0], "some string");
strcpy(pointer[1], "some other string");
strcpy(pointer[2], "yet another string");
Best way to initialize an array of strings ...
char arrayofstrings[3][100] = {0}; is fine to initialize an array of strings.
In C, initialization is done only at object definition, like above.
Later code like strcpy(), assigns data to the array.
Best way to ... pass it to a function
When the C compiler supports variable length arrays, use function(size_t n, size_t sz, char a[n][sz]).
Add error checks.
Use size_t for array sizing and indexing.
#define somepointertostring "Hello World"
int function(size_t n, size_t sz, char arrayofstrings[n][sz]) {
if (sz <= strlen(somepointertostring)) {
return 1;
}
for (size_t i = 0; i < n; i++) {
strcpy(arrayofstrings[i], somepointertostring);
if (strcmp(arrayofstrings[i], somepointertostring)) {
return 1;
}
// Drop this it see something interesting in `foo()`
memset(arrayofstrings[i], 0, strlen(arrayofstrings[i]));
}
return 0;
}
void foo(void) {
char arrayofstrings[3][100] = {0};
size_t n = sizeof arrayofstrings / sizeof arrayofstrings[0];
size_t sz = sizeof arrayofstrings[0];
if (function(n, sz, arrayofstrings)) {
puts("Fail");
} else {
puts("Success");
puts(arrayofstrings[0]);
}
}
Initalizing an (empty?) array of strings and initializing a pointer on the first element.
The type of &arrayofstrings is char (*)[3][100] i.e. pointer to an object which is a 2D array of char type with dimension 3 x 100. So, this initialisation
char (*pointer)[3][100] = &arrayofstrings;
is not initialisation of pointer with first element of arrayofstrings array but pointer will point to whole 2D array arrayofstrings. That why, when accessing the elements using pointer you need bracket around it -
`(*pointer)[0]` -> first string
`(*pointer)[1]` -> second string and so on..
Is this a good way to do it? Is there an easier way to do it?
If you want pointer to first element of array arrayofstrings then you can do
char (*p)[100] = &arrayofstrings[0];
Or
char (*p)[100] = arrayofstrings;
both &arrayofstrings[0] and arrayofstrings are equivalent1).
Pass it to a function and access the array:
function() function signature should be -
int function (char (*pointer)[100])
// if you want the function should be aware of number of rows, add a parameter for it -
// int function (char (*pointer)[100], int rows)
this is equivalent to
int function (char pointer[][100])
and call it in from main() function like this -
function (p);
In the function() function you can access array as p[0], p[1] ...:
Sample program for demonstration:
#include <stdio.h>
#include <string.h>
#define ROW 3
#define COL 100
void function (char (*p)[COL]) {
strcpy (p[0], "string one");
strcpy (p[1], "string two");
strcpy (p[2], "string three");
}
int main(void) {
char arrayofstrings[ROW][COL] = {0};
char (*pointer)[COL] = &arrayofstrings[0];
function (pointer);
for (size_t i = 0; i < ROW; ++i) {
printf ("%s\n", arrayofstrings[i]);
}
return 0;
}
When you access an array, it is converted to a pointer to first element (there are few exceptions to this rule).
I am trying to create a program that populates a fixed-size argument array using the arguments passed through the terminal. My first step is trying to create and populate the array of default argument strings, which I have succeeded in doing. However, I am now trying to use malloc() to allocate space for this array, and cannot get it to compile. I've tried everything I can think of regarding the proper syntax. I've tried doing more research into malloc() and how to use it for two dimensional arrays, but I haven't found any information that helps me. I'm stuck and not sure what to do next. Here is the code:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_NUM_OF_ARGS 5
#define MAX_ARG_SIZE 256
int main(int argc, char **argv) {
printf("%s%d\n", "Length: ", argc); //for debug purposes
// Make sure we don't have more than five arguments
if(argc > MAX_NUM_OF_ARGS) {
printf("%s", "Too many arguments. Must enter fewer than 4.");
}
// Populate the array
else{
char defaultArgs[] = "defaultArgs"; //create default argument array
//allocate memory for default array
char argumentArray[MAX_NUM_OF_ARGS][MAX_ARG_SIZE] =
(char *)malloc(MAX_NUM_OF_ARGS * MAX_ARG_SIZE * sizeof(char));
//populate array with default arguments
for (int i = 0; i < MAX_NUM_OF_ARGS; i++) {
strcpy(argumentArray[i], defaultArgs);
printf("%s\n", argumentArray[i]);
}
free(argumentArray);
return 0;
}
}
When I try to compile I get an invalid initializer error at the (char*) cast for malloc(). I've tried casting it to (char**) and (char) and also changing the sizeof(char) to sizeof(char*) and sizeof(char**).
I am not really sure what I am doing wrong at this point and I am at a loss as far as what to even try next.
You've declared argumentArray as a two-dimensional array of char. The malloc function returns a pointer, so you can't assign a pointer to an element of this array.
You need a pointer to store what's being returned. Actually, in this case you need a pointer to a pointer, and you'll need to call malloc multiple times, once for an array of pointers for the arguments, then again in a loop for each argument:
char **argumentArray = malloc(MAX_NUM_OF_ARGS * sizeof(char *));
for (int i=0; i<MAX_NUM_OF_ARGS; i++) {
argumentArray[i] = malloc(MAX_ARG_SIZE);
strcpy(argumentArray[i], defaultArgs);
printf("%s\n", argumentArray[i]);
}
You cannot store an array of strings in C, as a string is a variable-length datastructure, not a simple type.
So, decide what you want:
An array of fixed-length buffers storing strings of fixed (maximum) length.
char (*p)[MAX_LEN] = malloc(n * sizeof *p);
// Store the strings at p[0], p[1], …, p[n - 1]
A buffer storing any number of strings consecutively.
char* p = malloc(sum_of_string_lengths + count_of_strings);
// Now fill in the strings one after the other, including Terminator
An array of pointers to strings.
char** p = malloc(n * sizeof *p);
p[0] = strdup(source[0]);
// ...
// p[n - 1] = ...
With strdup() the common utility-function defined like:
char* strdup(const char* s) {
size_t n = strlen(s) + 1;
char* r = malloc(n);
if (r)
memcpy(r, s, n);
return r;
}
Try thinking about it like this:
Strings are character pointers
You need an array of character pointers
Here is an example where I make an array of char *. Essentially the pointer returned by malloc points to an area where char * will reside. Here is an illustration of what is going on.
/*
malloc_ret_ptr ---> [ char * my_str1 | char * my_str2 | char * my_str3 ]
| | |
| | |
v v v
"Thank" "You" "Chicago"
*/
int main() {
char * my_string = "this is my string";
char ** my_string_array;
my_string_array = malloc(sizeof(char*)*10); //Create an array of character pointers
//Place char * inside of char * array
my_string_array[0] = my_string;
return 0;
}
I have a string in my main functions.
I need to send it to other functions and make malloc to new string with the same size of the original.
I try something like this:
#define SIZE_STRING 100
typedef char string[SIZE_STRING];
char *testCode(string str)
{
char *new_str;
int limit = strlen(str);
int new_limit;
new_str = (char*)calloc(limit, sizeof(char));
new_limit = strlen(new_str);
printf("%d", new_limit);
return new_str;
}
void main()
{
char str[SIZE_STRING] = { "BLA BLA BLA" };
char *new_str;
new_str=testCode(str);
}
The new_limit get the size of 0.
What should I do?
Change:
new_str = (char*)calloc(limit, sizeof(char));
to
new_str = malloc(limit + 1);
strcpy(new_str, str);
You never copied the old string into the buffer you just made, so when you do strlen on it, of course you get zero.
To malloc() string in c with the same size of original string, the function 'testCode' must be given one additional item of information. Namely, the size of the original string.
#define SIZE_STRING 100
typedef char string[SIZE_STRING];
char *testCode(string str, size_t strSize)
Added 'strSize' (above) to the arguments of 'testCode' to provide the actual size of 'str'.
{
char *new_str;
// int limit = strlen(str);
// int new_limit;
new_str = (char*)calloc(strSize, sizeof(char));
Exchanged 'limit' for 'strSize' in order to allocate the correct size.
new_limit = strSize;
Exchanged 'strlen(new_str)' for 'strSize'. The previous term 'strlen(new_str)' will always be zero due to calloc()'s 'zeroing-out the new memory' feature.
printf("%d", new_limit);
return new_str;
}
void main()
{
char str[SIZE_STRING] = { "BLA BLA BLA" };
char *new_str;
new_str=testCode(str, sizeof(str));
}
A final thought...
The question was how to "malloc string in c with the same size of original string". Keep in mind that the 'size' of a character array differs from the 'length' of a character array. While the 'size' of an array is defined as the number of bytes (or perhaps elements) that make up the entire array, the 'length' of a C string is the number of characters found in the array up to the terminating '\0' character.
Hence if the question was actually how to "malloc string in c with the same length of original string", the above answer would still apply, except for the line:
new_str=testCode(str, sizeof(str));
would have to be changed to:
new_str=testCode(str, strlen(str)+1);
Do you mean you were given task to reimplement strdup() libc function?
https://sourceware.org/git/?p=glibc.git;a=blob;f=string/strdup.c;h=cedffa0da2e7a94ea8b95e79af6a7a5d0d3236d9;hb=HEAD#l37
In C, I have two char arrays:
char array1[18] = "abcdefg";
char array2[18];
How to copy the value of array1 to array2 ? Can I just do this: array2 = array1?
You can't directly do array2 = array1, because in this case you manipulate the addresses of the arrays (char *) and not of their inner values (char).
What you, conceptually, want is to do is iterate through all the chars of your source (array1) and copy them to the destination (array2). There are several ways to do this. For example you could write a simple for loop, or use memcpy.
That being said, the recommended way for strings is to use strncpy. It prevents common errors resulting in, for example, buffer overflows (which is especially dangerous if array1 is filled from user input: keyboard, network, etc). Like so:
// Will copy 18 characters from array1 to array2
strncpy(array2, array1, 18);
As #Prof. Falken mentioned in a comment, strncpy can be evil. Make sure your target buffer is big enough to contain the source buffer (including the \0 at the end of the string).
If your arrays are not string arrays, use:
memcpy(array2, array1, sizeof(array2));
If you want to guard against non-terminated strings, which can cause all sorts of problems, copy your string like this:
char array1[18] = {"abcdefg"};
char array2[18];
size_t destination_size = sizeof (array2);
strncpy(array2, array1, destination_size);
array2[destination_size - 1] = '\0';
That last line is actually important, because strncpy() does not always null terminate strings. (If the destination buffer is too small to contain the whole source string, sntrcpy() will not null terminate the destination string.)
The manpage for strncpy() even states "Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated."
The reason strncpy() behaves this somewhat odd way, is because it was not actually originally intended as a safe way to copy strings.
Another way is to use snprintf() as a safe replacement for strcpy():
snprintf(array2, destination_size, "%s", array1);
(Thanks jxh for the tip.)
As others have noted, strings are copied with strcpy() or its variants. In certain cases, you could use snprintf() as well.
You can only assign arrays the way you want as part of a structure assignment:
typedef struct { char a[18]; } array;
array array1 = { "abcdefg" };
array array2;
array2 = array1;
If your arrays are passed to a function, it will appear that you are allowed to assign them, but this is just an accident of the semantics. In C, an array will decay to a pointer type with the value of the address of the first member of the array, and this pointer is what gets passed. So, your array parameter in your function is really just a pointer. The assignment is just a pointer assignment:
void foo (char x[10], char y[10]) {
x = y; /* pointer assignment! */
puts(x);
}
The array itself remains unchanged after returning from the function.
This "decay to pointer value" semantic for arrays is the reason that the assignment doesn't work. The l-value has the array type, but the r-value is the decayed pointer type, so the assignment is between incompatible types.
char array1[18] = "abcdefg";
char array2[18];
array2 = array1; /* fails because array1 becomes a pointer type,
but array2 is still an array type */
As to why the "decay to pointer value" semantic was introduced, this was to achieve a source code compatibility with the predecessor of C. You can read The Development of the C Language for details.
You cannot assign arrays, the names are constants that cannot be changed.
You can copy the contents, with:
strcpy(array2, array1);
assuming the source is a valid string and that the destination is large enough, as in your example.
it should look like this:
void cstringcpy(char *src, char * dest)
{
while (*src) {
*(dest++) = *(src++);
}
*dest = '\0';
}
.....
char src[6] = "Hello";
char dest[6];
cstringcpy(src, dest);
I recommend to use memcpy() for copying data.
Also if we assign a buffer to another as array2 = array1 , both array have same memory and any change in the arrary1 deflects in array2 too. But we use memcpy, both buffer have different array. I recommend memcpy() because strcpy and related function do not copy NULL character.
array2 = array1;
is not supported in c. You have to use functions like strcpy() to do it.
c functions below only ... c++ you have to do char array then use a string copy then user the string tokenizor functions... c++ made it a-lot harder to do anythng
#include <iostream>
#include <fstream>
#include <cstring>
#define TRUE 1
#define FALSE 0
typedef int Bool;
using namespace std;
Bool PalTrueFalse(char str[]);
int main(void)
{
char string[1000], ch;
int i = 0;
cout<<"Enter a message: ";
while((ch = getchar()) != '\n') //grab users input string untill
{ //Enter is pressed
if (!isspace(ch) && !ispunct(ch)) //Cstring functions checking for
{ //spaces and punctuations of all kinds
string[i] = tolower(ch);
i++;
}
}
string[i] = '\0'; //hitting null deliminator once users input
cout<<"Your string: "<<string<<endl;
if(PalTrueFalse(string)) //the string[i] user input is passed after
//being cleaned into the null function.
cout<<"is a "<<"Palindrome\n"<<endl;
else
cout<<"Not a palindrome\n"<<endl;
return 0;
}
Bool PalTrueFalse(char str[])
{
int left = 0;
int right = strlen(str)-1;
while (left<right)
{
if(str[left] != str[right]) //comparing most outer values of string
return FALSE; //to inner values.
left++;
right--;
}
return TRUE;
}
Well, techincally you can…
typedef struct { char xx[18]; } arr_wrap;
char array1[18] = "abcdefg";
char array2[18];
*((arr_wrap *) array2) = *((arr_wrap *) array1);
printf("%s\n", array2); /* "abcdefg" */
but it will not look very beautiful.
…Unless you use the C preprocessor…
#define CC_MEMCPY(DESTARR, SRCARR, ARRSIZE) \
{ struct _tmparrwrap_ { char xx[ARRSIZE]; }; *((struct _tmparrwrap_ *) DESTARR) = *((struct _tmparrwrap_ *) SRCARR); }
You can then do:
char array1[18] = "abcdefg";
char array2[18];
CC_MEMCPY(array2, array1, sizeof(array1));
printf("%s\n", array2); /* "abcdefg" */
And it will work with any data type, not just char:
int numbers1[3] = { 1, 2, 3 };
int numbers2[3];
CC_MEMCPY(numbers2, numbers1, sizeof(numbers1));
printf("%d - %d - %d\n", numbers2[0], numbers2[1], numbers2[2]); /* "abcdefg" */
(Yes, the code above is granted to work always and it's portable)
for integer types
#include <string.h>
int array1[10] = {0,1,2,3,4,5,6,7,8,9};
int array2[10];
memcpy(array2,array1,sizeof(array1)); // memcpy("destination","source","size")
You cannot assign arrays to copy them. How you can copy the contents of one into another depends on multiple factors:
For char arrays, if you know the source array is null terminated and destination array is large enough for the string in the source array, including the null terminator, use strcpy():
#include <string.h>
char array1[18] = "abcdefg";
char array2[18];
...
strcpy(array2, array1);
If you do not know if the destination array is large enough, but the source is a C string, and you want the destination to be a proper C string, use snprinf():
#include <stdio.h>
char array1[] = "a longer string that might not fit";
char array2[18];
...
snprintf(array2, sizeof array2, "%s", array1);
If the source array is not necessarily null terminated, but you know both arrays have the same size, you can use memcpy:
#include <string.h>
char array1[28] = "a non null terminated string";
char array2[28];
...
memcpy(array2, array1, sizeof array2);
None of the above was working for me..
this works perfectly
name here is char *name which is passed via the function
get length of char *name using strlen(name)
storing it in a const variable is important
create same length size char array
copy name 's content to temp using strcpy(temp, name);
use however you want, if you want original content back. strcpy(name, temp); copy temp back to name and voila works perfectly
const int size = strlen(name);
char temp[size];
cout << size << endl;
strcpy(temp, name);
You can't copy directly by writing array2 = array1.
If you want to copy it manually, iterate over array1 and copy item by item as follows -
int i;
for(i=0;array1[i]!='\0';i++){
array2[i] = array1[i];
}
array2[i]='\0'; //put the string terminator too
If you are ok to use string library, you can do it as follows -
strncpy ( array2, array1, sizeof(array2) );
I have an array of characters declared as:
char *array[size];
When I perform a
printf("%s", array);
it gives me some garbage characters, why it is so?
http://www.cplusplus.com/reference/clibrary/cstdio/printf/
This url indicates printf takes in the format of: `int printf ( const char * format, ... );
#include <stdio.h>
#include <string.h>
#define size 20
#define buff 100
char line[buff];
int main ()
{
char *array[100];
char *sep = " \t\n";
fgets(line, buff, stdin);
int i;
array[0] = strtok(line, sep);
for (i = 1; i < size; i++) {
array[i] = strtok(NULL, sep);
if (array[i] == NULL)
break;
}
return 0;
}
You declare an array of characters like so:
char foo[size];
You seem to have it mixed up with char *, which is a pointer to a character. You could say
char *bar = foo;
which would make bar point to the contents of foo. (Or, actually, to the first character of foo.)
To then print the contents of the array, you can do one of the following:
// either print directly from foo:
printf("%s", foo);
// or print through bar:
printf("%s", bar);
Note, however, that C performs no initialization of the contents of variables, so unless you specifically set the contents to something, you'll get garbage. In addition, if that garbage doesn't happen to contain a \0; that is, a char with value 0, it will keep on outputting past the end of the array.
Your array is not initialized, and also you have an array of pointers, instead of an array of char's. It should be char* array = (char*)malloc(sizeof(char)*size);, if you want an array of char's. Now you have a pointer to the first element of the array.
Why are we making such a simple thing sound so difficult?
char array[SIZE];
... /* initialize array */
puts(array); /* prints the string/char array and a new line */
/* OR */
printf("%s", array); /* prints the string as is, without a new line */
The char in array after the end of what you want to be your string (ie. if you want your string to read "Hello" that would be the next char after the 'o') must be the terminating NUL character '\0'. If you use a C function to read input that would automatically be appended to the end of your buffer. You would only need to worry about doing it manually if you were individually writing characters to your buffer or something for some reason.
EDIT: As with pmg's comment, the '\0' goes wherever you want the string to end, so if you wanted to shorten your string you could just move it up closer to the front, or to have an empty string you just have array[0] = '\0';. Doing so can also be used to tokenise smaller strings inside a single buffer, just as strtok does. ie. "Part1\0Part2\0Part3\0". But I think this is getting away from the scope of the question.
ie. you wanted to store the first 3 chars of the alphabet as a string (don't know why anyone would do it this way but it's just an example):
char array[4];
array[0] = 'a';
array[1] = 'b';
array[2] = 'c';
array[3] = '\0';
printf("%s\n", array);
If you have something like char array[] = "Hello"; the '\0' is automatically added for you.
char *array[size];
array is not a char * with that, it's more like a char ** (pointer to an array of chars, with is similar to pointer to pointer to char).
If all you need is a C string, either:
char array[size];
and make sure you 0-terminate it properly, or
char *array;
and make sure you properly allocate and free storage for it (and 0-terminate it too).