Character Array - c

I am trying to build a char array of words using calloc.
What I have:
char** word;
word=(char**)calloc(12,sizeof(char*));
for(i=0;i<12;i++){
word[i]=(char*)calloc(50,sizeof(char));
}
Is this correct if I want a char array that has 12 fields each capable of storing 50 characters?
Thanks!

The code is correct. Some points:
No need to cast return value of calloc() ( Do I cast the result of malloc? )
sizeof(char) is guaranteed to be 1
So code could be rewritten as:
char** word;
int i;
word = calloc(12, sizeof(char*));
for (i = 0; i < 12; i++)
word[i] = calloc(50, 1);
In C, most of the functions that operate on 'strings' require the char array to be null terminated (printf("%s\n", word[i]); for example). If it is required that the buffers holds 50 characters and be used as 'strings' then allocate an additional character for the null terminator:
word[i] = calloc(51, 1);
As commented by eq- a less error prone approach to using sizeof is:
word = calloc(12, sizeof(*word));

Related

C: convert int[ ] to string

Technically I realize they are slightly different as the array is null terminated. But looking for a way to convert
int charArray[] = {'h', 'e', 'l', 'l', 'o'}; //ascii chars = ints
to
char *string;
Since charArray is not a string, you can't use the standard functions like strcpy(), or strlen(). Instead, copy every character, and add '\0' at the end. sizeof(charArray) / sizeof(int) can tell you how many characters to copy.
size_t sz = sizeof(charArray) / sizeof(int);
char *string = malloc(sz + 1);
for (int i = 0; i < sz; i++)
{
string[i] = charArray[i];
}
string[sz] = '\0';
You can't convert between int[] and char * in c. You can iterate over the array and build a char* with the desired value, though, then add \0 to the end. You can also typecast, by using (char*) charArray, but this is prone to lots of problems, like the missing \0 terminator. It won't work for strcpy, for example.
char arr[] = {'h','e','l'};
string str(arr);
cout<<str<<endl; // output hel
charArray is of type int[8] where as string is of type char *. They are different and incompatible types and you can't convert one into the other. What you can do is define an array of characters of enough size and then copy the integers(implicitly converted to char type) from the charArray into it.
// length of charArray
int length = sizeof charArray / sizeof charArray[0];
char string[length + 1]; // +1 for the null byte
for(int i = 0; i < length; i++)
string[i] = charArray[i]; // copy the characters
string[i] = '\0'; // add the terminating null byte

C: How do I allocate an exact amount of bytes to a string?

Here's my function.
char * substring(int begin, int end, char * string)
{
int size = end - begin + 1;
char * s = (char *)malloc (sizeof(size));
int i;
for (i = 0; i < size; i++)
{
s[i] = string[begin++];
}
return s;
}
So let's say my string was only supposed to be "I". But when I try to print out the string later, I get I + 3 extra characters that were unintended. How do I fix this?
First, change the line
char * s = (char *)malloc (sizeof(size));
to
char * s = malloc( size + 1 ); // + 1 for null terminator
sizeof (size) gives you the number of bytes in an integer (2 to 4 to 8 depending on your platform), which is not necessarily what you want.
Next, use the strncpy function to copy the first size characters of string:
strncpy( s, string, size );
Make sure the string is null-terminated:
s[size] = '\0';
You have extra characters printed since you haven't null-terminated the s string:
s[i] = 0;
return s;
Fix the allocation to size, and also note that the following may depend on your interpretation of begin and end, but if you interpret the end as pointing to the last character you intend to copy (this would be a-typical), then you will need to adjust the size by 1.
This is undefined behavior waiting to happen. Your biggest problem is that your allocation should be
char * s = (char *)malloc (size);

String termination - char c=0 vs char c='\0'

When terminating a string, it seems to me that logically char c=0 is equivalent to char c='\0', since the "null" (ASCII 0) byte is 0, but usually people tend to do '\0' instead. Is this purely out of preference or should it be a better "practice"?
What is the preferred choice?
EDIT: K&R says: "The character constant '\0' represents the character with value zero, the null character. '\0' is often written instead of 0 to emphasize the character nature of some expression, but the numeric value is just 0.
http://en.wikipedia.org/wiki/Ascii#ASCII_control_code_chart
Binary Oct Dec Hex Abbr Unicode Control char C Escape code Name
0000000 000 0 00 NUL ␀ ^# \0 Null character
There's no difference, but the more idiomatic one is '\0'.
Putting it down as char c = 0; could mean that you intend to use it as a number (e.g. a counter). '\0' is unambiguous.
'\0' is just an ASCII character. The same as 'A', or '0' or '\n'
If you write char c = '\0', it's the same aschar c = 0;
If you write char c = 'A', it's the same as char c = 65
It's just a character representation and it's a good practice to write it, when you really mean the NULL byte of string. Since char is in C one byte (integral type), it doesn't have any special meaning.
Preferred choice is that which can give people reading your code an ability to understand how do you use your variable - as a number or as a character.
Best practice is to use 0 when you mean you variable as a number and to use '\0' when you mean your variable is a character.
The above answers are already quite clear. I just share what I learned about this issue with a demo.
#include <stdlib.h>
#include <stdio.h>
char*
mystrcat(char *dest, char *src) {
size_t i,j;
for(i = 0; dest[i] != '\0'; i++)
;
for(j = 0; src[j] != '\0'; j++)
dest[i+j] = src[j];
dest[i+j] = '\0';
return dest;
}
int main() {
char *str = malloc(20); // malloc allocate memory, but doesn't initialize the memory
// str[0] = '\0';
str[0] = 0;
for (int k = 0; k <10; k++) {
char s[2];
sprintf(s, "%d", k);
mystrcat(str, s);
}
printf("debug:%s\n", str);
return 0;
}
In the above program, I used malloc to initialize the pointer, but malloc doesn't initialize the memory. So after the mystrcat operation(which is nearly the same as the strcat function in glibc), the string may contain mess code(since the memory content is not initialized).
So I need to initialize the memory. In this case str[0] = 0 and str[0] = 0 both can make it work.

Initialize array of characters using pointers

This problem is driving me crazy, I'm sure I'm missing something. I need to initialize an array of chars using only pointers. Below is the code I have so far:
int p2(){
/* Implements problem 2 of lab */
// Create an array
char **s = (char**)malloc( 11 *sizeof(char));
char *p = *s;
char start ='A';
while( p != s+10){
*p = start;
start++;
p++;
}
return(0);
}
The problem I'm having is I don't know how to address the characters inside of the array. I understand the base address of the array is **s, and the pointer to the first element is *s. What I don't understand is how to get to **s+10 (i.e. the end of the array).
Can anyone shine some light for me??? Please!
EDIT: Ok, looks like I misunderstood the question. I appears I need to create an array of strings (thus the char ** allocation). Then I need to loop through this array, and assign each string (i.e. char *) a value 15 chars long. Please let me know if I'm understanding this correctly:
char **strings ==> strings[0 ... n ] where each element is a pointer to a char (possibly an array). There for *string ==> strings[0], *(string+1) = strings[1], etc etc.
Am I close or way off?
char **s is 2 dimensional array of characters, or array of C strings if you want.
If you want to use array of characters you should use:
char *string = (char*)malloc( 11 *sizeof(char));
If you really want to initialize array of strings, at first step you're initializing array of pointers, that's:
char **s = (char**)malloc( 11 *sizeof(char *));
Please note that I'm using char * inside sizeof. Than when you may use strings, but at first you must initialize each string.
s[0] = (char*) malloc( 15*size(char)); // This is actually string, 14 characters long (NULL terminated)
char *p = s[0]; // p is pointer to beginning of your string now
And there's two way how to address your string:
s[0][3] // 4th character of your string
p[3]
Or if you want to use just pointers:
char *p = *(s+0);
*(p+3); // 4th character
*((*(s+0))+3) // To do it "hardcore"
EDIT: added an example
When you have **char p and use p++ or p + 1, C increases memory address. *p operator tells compiler that you now want to work with data stored in memory, not with pointer. Therefor those two syntax do the same:
p[10] = 'a';
*(p+10) = 'a';
So if you want traverse both your dimensions, you should use:
for( int i = 0; i < 11; i++){
char *p = *(s+i);
for( int j = 0; j < 10; j++){
*(p + j) = 'a'; // Say you wanna fill them with as
}
// You may also use this syntax:
while( p < (*(s+i) + 10)){ // or use != instead of <
*p = 'a';
p++;
}
}
I think you meant this:
char *s = (char*) malloc(11 *sizeof(char));
char *p = s;
In which case you'd address the characters with s[x]
First, you don't need a char ** unless you need an array of arrays.
Second, you can get to the end of the array with (*s)[10] or *((*s)+10)
Third, in C programming, don't cast the result of malloc()
The code is falling apart here.
char **s = (char**)malloc( 11 *sizeof(char));
You're allocating enough memory for 11 chars, which sounds like what you want to do.
However, you're casting the address to those 11 chars to a (char**) as if you were allocating space for pointers, not chars.
Why should you use a double pointer for creating an array of chars?
char *s = (char *) malloc(10 * sizeof(char));
char *start = s; // save starting pointer
for(; s < start+10; s++)
*s = 'a';
return 0;
If you allocate char ** essentially you're allocating an array of pointers to char(eg. array of strings). If you need char array, allocate char array. If you start working with pointers a design of stack and heap can be really helpful.

C dynamic string array

I have char * lines[1000] string that can hold 1000 characters. How to create 100 arrays of that string. I get error with this code down.
char * lines[1000];
lines = (lines*)malloc(100 * sizeof(lines));
main.c:19:20: error: expected expression before ')' token
The simplest way is:
char lines[100][1000];
Alternatively:
char* lines[100];
int i;
for (i = 0; i < 100; i++) {
lines[i] = malloc(1000);
}
...
for (i = 0; i < 100; i++) {
free(lines[i]);
}
The latter is a bit more flexible in that -- with minor modifications -- it permits you to allocate a different amount of memory for every string.
It looks like you want an array strings, each string holding at most 1000 characters. There are some issues with your code.
You've declared an array of char *s but what you really want is a pointer to an array of chars. For that, your declaration should be
char (*lines)[1000];
On the other hand, you shouldn't forget about the NULL bytes at the end of strings, and should probably instead declare
char (*lines)[1001];
To set the pointer, you'll want to use
lines = (char (*)[1001]) malloc(100 * sizeof(char[1001]));
or
lines = (char (*)[1001]) malloc(100 * sizeof(*lines));
the latter working because, with lines a pointer to an array of chars, *lines is a char[1001]. Remember to make sure you didn't get a NULL pointer back.
At the end, you should free the memory you've malloced with
free(lines);
You can write a for-loop as:
char * lines[1000];
int i = 0;
for (i = 0; i < 1000; i++)
{
lines[i] = (char*)malloc(100 * sizeof(lines));
}
Don't forget to free-up the memory pointed by all the pointers
for (i = 0; i < 1000; i++)
{
free(lines[i])
}
Why don't you create a 2 dimensional array?

Resources