A C string is a nul-terminated character array.
The C language does not allow assigning the contents of an array to another
array. As noted by Barry, you must copy the individual characters one by one
from the source array to the destination array. e.g. -
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
char str1[] = "Hello";
char str2[10] = {0};
for (int x = 0; x < strlen(str1); ++x)
{
str2[x] = str1[x];
}
printf("%s\n", str2);
return 0;
}
To make this common task easier there are standard library functions provided
which will perform this operation. e.g. - memcpy(), etc.
memcpy(str2, str1, 6);
When the array contains a nul-terminated string of characters you can use
strcpy(), etc.
strcpy(str2, str1);
Caveat: Some of the above functions are considered unsafe as they do not guard
against buffer overruns of the source and destination arrays. There are safer
versions provided by the compiler.
Note that if and when you start learning C++ you will find that there you can
assign a C++ std::string object to another object of the same type. However,
even in C++ the same rules apply when working with C strings, "raw" character
arrays, etc.
- Wayne
A C string is a nul-terminated character array.
The C language does not allow assigning the contents of an array to another
array. As noted by Barry, you must copy the individual characters one by one
from the source array to the destination array. e.g. -
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
char str1[] = "Hello";
char str2[10] = {0};
for (int x = 0; x < strlen(str1); ++x)
{
str2[x] = str1[x];
}
printf("%s\n", str2);
return 0;
}
To make this common task easier there are standard library functions provided
which will perform this operation. e.g. - memcpy(), etc.
memcpy(str2, str1, 6);
When the array contains a nul-terminated string of characters you can use
strcpy(), etc.
strcpy(str2, str1);
Caveat: Some of the above functions are considered unsafe as they do not guard
against buffer overruns of the source and destination arrays. There are safer
versions provided by the compiler.
Note that if and when you start learning C++ you will find that there you can
assign a C++ std::string object to another object of the same type. However,
even in C++ the same rules apply when working with C strings, "raw" character
arrays, etc.
- Wayne
str2 is an array. It cannot appear on the left side of an assignment. You will need to use something like strcpy.
q is a pointer. It is perfectly legal to copy one pointer to another.
Videos
use strncpy() rather than strcpy()
/* code not tested */
#include <string.h>
int main(void) {
char *src = "gkjsdh fkdshfkjsdhfksdjghf ewi7tr weigrfdhf gsdjfsd jfgsdjf gsdjfgwe";
char dst[10]; /* not enough for all of src */
strcpy(dst, src); /* BANG!!! */
strncpy(dst, src, sizeof dst - 1); /* OK ... but `dst` needs to be NUL terminated */
dst[9] = '\0';
return 0;
}
use strncpy to be sure to not copy more charachters than the char[] can contains
char *s = "abcdef";
char c[6];
strncpy(c, s, sizeof(c)-1);
// strncpy is not adding a \0 at the end of the string after copying it so you need to add it by yourself
c[sizeof(c)-1] = '\0';
Edit: Code added to question
Viewing your code the segmentation fault could be by the line
strcpy(c, token)
The problem is if token length is bigger than c length then memory is filled out of the c var and that cause troubles.
Your problem is with the destination of your copy: it's a char* that has not been initialized. When you try copying a C string into it, you get undefined behavior.
You need to initialize the pointer
char *to = malloc(100);
or make it an array of characters instead:
char to[100];
If you decide to go with malloc, you need to call free(to) once you are done with the copied string.
You need to allocate memory for to. Something like:
char *to = malloc(strlen(from) + 1);
Don't forget to free the allocated memory with a free(to) call when it is no longer needed.
If I have array of strings like string a = {"Hello", "Bye", "HI"};
I want to copy hello in an array of char such as char copy. So that I can iterate over characters of Hello one by one.
How can I achieve this?
The array dict is an array of pointers to string literals.
In this statement
strcpy(dict[1],newWord1);
you are trying to copy one string literal in another string literal.
String literals are non-modifiable in C and C++. Any attempt to modify a strig literal results in undefined behavior of the program.
From the C Standard (6.4.5 String literals)
7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.
You should declare a two-dimensional character array if you are going to copy string literals in its elements or a one dimensional array of dynamically allocated character arrays.
The program can look the following way
#include <stdio.h>
#include <string.h>
#define N 9
size_t numberOfWordsInDict( char dict[][N] )
{
size_t n = 0;
while ( *dict[n] ) ++n;
return n;
}
void printDict( char dict[][N] )
{
printf("Dictionary:\n");
size_t n = numberOfWordsInDict( dict );
if ( n == 0 )
{
printf("The dictionary is empty.\n");
}
else
{
for ( size_t i = 0; i < n; i++ )
{
printf( "- %s\n", dict[i] );
}
}
}
int main(void)
{
char dict[10][9] =
{
"aap", "bro ", "jojo", "koe", "kip", "haha", "hond", " drop"
};
char *newWord1 = "hoi";
printDict(dict);
strcpy(dict[1], newWord1);
printDict(dict);
return 0;
}
The program output is
Dictionary:
- aap
- bro
- jojo
- koe
- kip
- haha
- hond
- drop
Dictionary:
- aap
- hoi
- jojo
- koe
- kip
- haha
- hond
- drop
Or you could use a Variable Length Array.
Keep in mind that according to the C Standard the function main without parameters shall be declared like
int main( void )
Since "bro" is a string constant and dict[1] points to it, dict[1] points to a string constant.
When you use strcpy(dict[1]), ..., you are trying to modify the thing that dict[1] points to. But it points to a constant. So you are trying to modify a constant.
Constants cannot be modified.
char *s1="Salahuddin";
char *s2="Ashraf";
With this s1 and s2 points to constant string not actually a character array. And their content shouldn't be changed.
Update it to
char s1[20] ="Salahuddin";
char s2[20] ="Ashraf";
Here 20 is just random number, you may want to change that.
Also in copy function, add '\0' at the end of the string.
void copy_string(char *to,char *from)
{
while(*from != '\0')
{
*to++=*from++;
}
*to = '\0';
}
Your big problem here is that s1 and s2 points to literal string, and those are constant and read only. So you can't use normal pointer here.
Instead you have to use arrays, e.g.
char s1[] = "some string";
char s2[] = "some other string";
The second thing you have to do is to make sure that the destination have enough space for the source string. In the example above it doesn't. It can be easily solved by making the arrays fixed-size:
char s1[30] = "some string";
char s2[30] = "some other string";
we simply use the strcpy function to copy the array into the pointer.
char str[] = "Hello World";
char *result = (char *)malloc(strlen(str)+1);
strcpy(result,str);
In your first snippet you modify the pointer in the loop, so after the loop it will no longer point to the same location returned by the malloc call.
Look at it this way, after the call to malloc the pointer and the memory look like this:
result | v +---+---+---+---+---+---+---+---+---+---+---+---+ | | | | | | | | | | | | | +---+---+---+---+---+---+---+---+---+---+---+---+
After the first iteration of the loop it will look like this:
result
|
v
+---+---+---+---+---+---+---+---+---+---+---+---+
| H | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
And after the loop is done it will look like this
result
|
v
+---+---+---+---+---+---+---+---+---+---+---+----+
| H | e | l | l | o | | W | o | r | l | d | \0 |
+---+---+---+---+---+---+---+---+---+---+---+----+
The copying is made, but the pointer no longer points to the original position.
[Note: Before the copying, the memory allocated by malloc will not be "empty" or initialized in any way, I just show it like that here for simplicity's sake.]
just make your array 2D. The error was because of your array is 1D so you ccan store only one string int that array.To Store multiple make the following changes.
char timelog[maxline][10];
matchescount = 0;
while ((read = getline(&line, &len, fp)) != -1) {
struct matches matched = check_match(line,lgd,grd);
if (matched.status==1)
{
strcpy(timelog[matchescount],matched.timelog);
matchescount++;
}
}
UPDATE:
char timelog[maxline][255]
creates a 2d array of char.As String is an array of chars you can store only si1D array of string in 2d array of char
timelog[0][0]='a';
timelog[0][1]='b';
timelog[0][2]='c';
timelog[0][3]='d';
timelog[0][4]='e';
this indicates you have a string "abcde" at timelog[0];
to store 2d array of strings you need a 3D char array
timelog[maxline][noOfStrings][maxLengthOfEachString];
now you can store 2D array of strings.
strcpy(timelog[0][0],"abcd");
strcpy(timelog[0][1],"efgh");
strcpy(timelog[1][0],"ijkl");
strcpy(timelog[1][1],"xyz");
Assuming your timelog string always look like "hh:mm:ss", you can do
#define MAXTIMELOG 9
#define MAXENTRIES 1000
char timelog[MAXENTRIES][MAXTIMELOG];
matchescount = 0;
while ((read = getline(&line, &len, fp)) != -1) {
struct matches matched = check_match(line, lgd, grd);
if (matched.status==1)
{
strncpy(timelog[matchescount], matched.timelog, MAXTIMELOG);
timelog[matchescount][MAXTIMELOG-1] = 0;
if (++matchescount == MAXENTRIES) {
... deal with full array ...
}
}
}
To copy strings in C, you can use strcpy. Here is an example:
#include <stdio.h>
#include <string.h>
const char * my_str = "Content";
char * my_copy;
my_copy = malloc(sizeof(char) * (strlen(my_str) + 1));
strcpy(my_copy,my_str);
If you want to avoid accidental buffer overflows, use strncpy instead of strcpy. For example:
const char * my_str = "Content";
const size_t len_my_str = strlen(my_str) + 1;
char * my_copy = malloc(len_my_str);
strncpy(my_copy, my_str, len_my_str);
To perform such manual copy:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* orig_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char* ptr = orig_str;
// Memory layout for orig_str:
// ------------------------------------------------------------------------
// |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26| --> indices
// ------------------------------------------------------------------------
// |A|B|C|D|E|F|G|H|I|J|K |L |M |N |O |P |Q |R |S |T |U |V |W |X |Y |Z |\0| --> data
// ------------------------------------------------------------------------
int orig_str_size = 0;
char* bkup_copy = NULL;
// Count the number of characters in the original string
while (*ptr++ != '\0')
orig_str_size++;
printf("Size of the original string: %d\n", orig_str_size);
/* Dynamically allocate space for the backup copy */
// Why orig_str_size plus 1? We add +1 to account for the mandatory
// '\0' at the end of the string.
bkup_copy = (char*) malloc((orig_str_size+1) * sizeof(char));
// Place the '\0' character at the end of the backup string.
bkup_copy[orig_str_size] = '\0';
// Current memory layout for bkup_copy:
// ------------------------------------------------------------------------
// |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26| --> indices
// ------------------------------------------------------------------------
// | | | | | | | | | | | | | | | | | | | | | | | | | | |\0| --> data
// ------------------------------------------------------------------------
/* Finally, copy the characters from one string to the other */
// Remember to reset the helper pointer so it points to the beginning
// of the original string!
ptr = &orig_str[0];
int idx = 0;
while (*ptr != '\0')
bkup_copy[idx++] = *ptr++;
printf("Original String: %s\n", orig_str);
printf("Backup String: %s\n", bkup_copy);
return 0;
}
There are two way of working with array of characters (strings) in C. They are as follows:
char a[ROW][COL];
char *b[ROW];
Pictorial representation is available as an inline comment in the code.
Based on how you want to represent the array of characters (strings), you can define pointer to that as follows
char (*ptr1)[COL] = a;
char **ptr2 = b;
They are fundamentally different types (in a subtle way) and so the pointers to them is also slightly different.
The following example demonstrates the different ways of working with strings in C and I hope it helps you in better understanding of array of characters (strings) in C.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ROW 5
#define COL 10
int main(void)
{
int i, j;
char a[ROW][COL] = {"string1", "string2", "string3", "string4", "string5"};
char *b[ROW];
/*
a[][]
0 1 2 3 4 5 6 7 8 9
+---+---+---+---+---+---+---+------+---+---+
| s | t | r | i | n | g | 1 | '\0' | | |
+---+---+---+---+---+---+---+------+---+---+
| s | t | r | i | n | g | 2 | '\0' | | |
+---+---+---+---+---+---+---+------+---+---+
| s | t | r | i | n | g | 3 | '\0' | | |
+---+---+---+---+---+---+---+------+---+---+
| s | t | r | i | n | g | 4 | '\0' | | |
+---+---+---+---+---+---+---+------+---+---+
| s | t | r | i | n | g | 5 | '\0' | | |
+---+---+---+---+---+---+---+------+---+---+
*/
/* Now, lets work on b */
for (i=0 ; i<5; i++) {
if ((b[i] = malloc(sizeof(char) * COL)) == NULL) {
printf("unable to allocate memory \n");
return -1;
}
}
strcpy(b[0], "string1");
strcpy(b[1], "string2");
strcpy(b[2], "string3");
strcpy(b[3], "string4");
strcpy(b[4], "string5");
/*
b[] 0 1 2 3 4 5 6 7 8 9
+--------+ +---+---+---+---+---+---+---+------+---+---+
| --|------->| s | t | r | i | n | g | 1 | '\0' | | |
+--------+ +---+---+---+---+---+---+---+------+---+---+
| --|------->| s | t | r | i | n | g | 2 | '\0' | | |
+--------+ +---+---+---+---+---+---+---+------+---+---+
| --|------->| s | t | r | i | n | g | 3 | '\0' | | |
+--------+ +---+---+---+---+---+---+---+------+---+---+
| --|------->| s | t | r | i | n | g | 4 | '\0' | | |
+--------+ +---+---+---+---+---+---+---+------+---+---+
| --|------->| s | t | r | i | n | g | 5 | '\0' | | |
+--------+ +---+---+---+---+---+---+---+------+---+---+
*/
char (*ptr1)[COL] = a;
printf("Contents of first array \n");
for (i=0; i<ROW; i++)
printf("%s \n", *ptr1++);
char **ptr2 = b;
printf("Contents of second array \n");
for (i=0; i<ROW; i++)
printf("%s \n", ptr2[i]);
/* b should be free'd */
for (i=0 ; i<5; i++)
free(b[i]);
return 0;
}
What would be the correct way to solve this problem?
Well, the correct way would be to use a library specifically designed for dealing with multilanguage interfaces - for instance gettext.
Another way, though patchier, would be to use a hash table (also known as "dictionary" or "hash map" or "associative map" in other languages/technologies): Looking for a good hash table implementation in C
It's probably not the answer you were looking for, but you've asked the wrong question to the right problem.