I am trying to create an array of strings in C. If I use this code:
char (*a[2])[14];
a[0]="blah";
a[1]="hmm";
gcc gives me "warning: assignment from incompatible pointer type". What is the correct way to do this?
edit: I am curious why this should give a compiler warning since if I do printf(a[1]);, it correctly prints "hmm".
If you don't want to change the strings, then you could simply do
const char *a[2];
a[0] = "blah";
a[1] = "hmm";
When you do it like this you will allocate an array of two pointers to const char. These pointers will then be set to the addresses of the static strings "blah" and "hmm".
If you do want to be able to change the actual string content, the you have to do something like
char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");
This will allocate two consecutive arrays of 14 chars each, after which the content of the static strings will be copied into them.
There are several ways to create an array of strings in C. If all the strings are going to be the same length (or at least have the same maximum length), you simply declare a 2-d array of char and assign as necessary:
char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1];
...
strcpy(strs[0], aString); // where aString is either an array or pointer to char
strcpy(strs[1], "foo");
You can add a list of initializers as well:
char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1] = {"foo", "bar", "bletch", ...};
This assumes the size and number of strings in the initializer match up with your array dimensions. In this case, the contents of each string literal (which is itself a zero-terminated array of char) are copied to the memory allocated to strs. The problem with this approach is the possibility of internal fragmentation; if you have 99 strings that are 5 characters or less, but 1 string that's 20 characters long, 99 strings are going to have at least 15 unused characters; that's a waste of space.
Instead of using a 2-d array of char, you can store a 1-d array of pointers to char:
char *strs[NUMBER_OF_STRINGS];
Note that in this case, you've only allocated memory to hold the pointers to the strings; the memory for the strings themselves must be allocated elsewhere (either as static arrays or by using malloc() or calloc()). You can use the initializer list like the earlier example:
char *strs[NUMBER_OF_STRINGS] = {"foo", "bar", "bletch", ...};
Instead of copying the contents of the string constants, you're simply storing the pointers to them. Note that string constants may not be writable; you can reassign the pointer, like so:
strs[i] = "bar";
strs[i] = "foo";
But you may not be able to change the string's contents; i.e.,
strs[i] = "bar";
strcpy(strs[i], "foo");
may not be allowed.
You can use malloc() to dynamically allocate the buffer for each string and copy to that buffer:
strs[i] = malloc(strlen("foo") + 1);
strcpy(strs[i], "foo");
BTW,
char (*a[2])[14];
Declares a as a 2-element array of pointers to 14-element arrays of char.
Ack! Constant strings:
const char *strings[] = {"one","two","three"};
If I remember correctly.
Oh, and you want to use strcpy for assignment, not the = operator. strcpy_s is safer, but it's neither in C89 nor in C99 standards.
char arr[MAX_NUMBER_STRINGS][MAX_STRING_SIZE];
strcpy(arr[0], "blah");
Update: Thomas says strlcpy is the way to go.
Here are some of your options:
char a1[][14] = { "blah", "hmm" };
char* a2[] = { "blah", "hmm" };
char (*a3[])[] = { &"blah", &"hmm" }; // only since you brought up the syntax -
printf(a1[0]); // prints blah
printf(a2[0]); // prints blah
printf(*a3[0]); // prints blah
The advantage of a2 is that you can then do the following with string literals
a2[0] = "hmm";
a2[1] = "blah";
And for a3 you may do the following:
a3[0] = &"hmm";
a3[1] = &"blah";
For a1 you will have to use strcpy() (better yet strncpy()) even when assigning string literals. The reason is that a2, and a3 are arrays of pointers and you can make their elements (i.e. pointers) point to any storage, whereas a1 is an array of 'array of chars' and so each element is an array that "owns" its own storage (which means it gets destroyed when it goes out of scope) - you can only copy stuff into its storage.
This also brings us to the disadvantage of using a2 and a3 - since they point to static storage (where string literals are stored) the contents of which cannot be reliably changed (viz. undefined behavior), if you want to assign non-string literals to the elements of a2 or a3 - you will first have to dynamically allocate enough memory and then have their elements point to this memory, and then copy the characters into it - and then you have to be sure to deallocate the memory when done.
Bah - I miss C++ already ;)
p.s. Let me know if you need examples.
If you don't want to keep track of number of strings in array and want to iterate over them, just add NULL string in the end:
char *strings[]={ "one", "two", "three", NULL };
int i=0;
while(strings[i]) {
printf("%s\n", strings[i]);
//do something
i++;
};
Or you can declare a struct type, that contains a character arry(1 string), them create an array of the structs and thus a multi-element array
typedef struct name
{
char name[100]; // 100 character array
}name;
main()
{
name yourString[10]; // 10 strings
printf("Enter something\n:);
scanf("%s",yourString[0].name);
scanf("%s",yourString[1].name);
// maybe put a for loop and a few print ststements to simplify code
// this is just for example
}
One of the advantages of this over any other method is that this allows you to scan directly into the string without having to use strcpy;
If the strings are static, you're best off with:
const char *my_array[] = {"eenie","meenie","miney"};
While not part of basic ANSI C, chances are your environment supports the syntax. These strings are immutable (read-only), and thus in many environments use less overhead than dynamically building a string array.
For example in small micro-controller projects, this syntax uses program memory rather than (usually) more precious ram memory. AVR-C is an example environment supporting this syntax, but so do most of the other ones.
In ANSI C:
char* strings[3];
strings[0] = "foo";
strings[1] = "bar";
strings[2] = "baz";
The string literals are const char *s.
And your use of parenthesis is odd. You probably mean
const char *a[2] = {"blah", "hmm"};
which declares an array of two pointers to constant characters, and initializes them to point at two hardcoded string constants.
Your code is creating an array of function pointers. Try
char* a[size];
or
char a[size1][size2];
instead.
See wikibooks to arrays and pointers
hello you can try this bellow :
char arr[nb_of_string][max_string_length];
strcpy(arr[0], "word");
a nice example of using, array of strings in c if you want it
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
int i, j, k;
// to set you array
//const arr[nb_of_string][max_string_length]
char array[3][100];
char temp[100];
char word[100];
for (i = 0; i < 3; i++){
printf("type word %d : ",i+1);
scanf("%s", word);
strcpy(array[i], word);
}
for (k=0; k<3-1; k++){
for (i=0; i<3-1; i++)
{
for (j=0; j<strlen(array[i]); j++)
{
// if a letter ascii code is bigger we swap values
if (array[i][j] > array[i+1][j])
{
strcpy(temp, array[i+1]);
strcpy(array[i+1], array[i]);
strcpy(array[i], temp);
j = 999;
}
// if a letter ascii code is smaller we stop
if (array[i][j] < array[i+1][j])
{
j = 999;
}
}
}
}
for (i=0; i<3; i++)
{
printf("%s\n",array[i]);
}
return 0;
}
char name[10][10]
int i,j,n;//here "n" is number of enteries
printf("\nEnter size of array = ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
for(j=0;j<1;j++)
{
printf("\nEnter name = ");
scanf("%s",&name[i]);
}
}
//printing the data
for(i=0;i<n;i++)
{
for(j=0;j<1;j++)
{
printf("%d\t|\t%s\t|\t%s",rollno[i][j],name[i],sex[i]);
}
printf("\n");
}
Here try this!!!
I was missing somehow more dynamic array of strings, where amount of strings could be varied depending on run-time selection, but otherwise strings should be fixed.
I've ended up of coding code snippet like this:
#define INIT_STRING_ARRAY(...) \
{ \
char* args[] = __VA_ARGS__; \
ev = args; \
count = _countof(args); \
}
void InitEnumIfAny(String& key, CMFCPropertyGridProperty* item)
{
USES_CONVERSION;
char** ev = nullptr;
int count = 0;
if( key.Compare("horizontal_alignment") )
INIT_STRING_ARRAY( { "top", "bottom" } )
if (key.Compare("boolean"))
INIT_STRING_ARRAY( { "yes", "no" } )
if( ev == nullptr )
return;
for( int i = 0; i < count; i++)
item->AddOption(A2T(ev[i]));
item->AllowEdit(FALSE);
}
char** ev picks up pointer to array strings, and count picks up amount of strings using _countof function. (Similar to sizeof(arr) / sizeof(arr[0])).
And there is extra Ansi to unicode conversion using A2T macro, but that might be optional for your case.
Each element is a pointer to its first character
const char *a[2] = {"blah", "hmm"};
A good way is to define a string your self.
#include <stdio.h>
typedef char string[]
int main() {
string test = "string";
return 0;
}
It's really that simple.
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 don't quite understand how to correctly arrange const in order to pass a constant array of arrays to a function, for example, an array of strings:
void f (char **strings);
int main (void)
{
char strings[][2] = { "a", "b", "c" };
f (strings);
}
Could you tell me where to put const? As I understand it, there should be two const and one of them in the example above should stand before char.
There is a high probability of a duplicate, but I could not find a similar question :(
First of all, the declaration isn't ideal. char strings[][2] declares an indeterminate amount of char[2] arrays, where the amount is determined by the initializers. In most cases it makes more sense to declare an array of pointers instead, since that means that the strings pointed at do not need to have a certain fixed length.
So you could change the declaration to const char* strings[3] = { "a", "b", "c" };. Unless of course the intention is to only allow strings on 1 character and 2 null terminator, then the original code was correct. And if you need read/writeable strings then we can't use pointer notation either.
You can pass a const char* strings[3] to a function by declaring that function as
void f (const char* strings[3]);
Just like you declared the array you pass to the function.
Now as it happens, arrays when part of a function declaration "decay" into a pointer to the first element. In this case a pointer to a const char* item, written as const char**.
So you could have written void f (const char** strings); and it would have been equivalent.
I think this resource explains it nicely. In general, it depends what "depth" of const guarding you need. If you want function "f" to have read-only access on both the "outer" pointer, the pointer it points to (the "inner" pointer), and the char the "inner" pointer points to, then use
const char *const *const strings
If you want to relax the guards to make this legal:
strings = NULL;
Then use:
const char *const *strings
Relaxing further, to allow for:
strings = NULL;
*strings = NULL;
Use only one "const":
const char **strings
It is important to understand the difference between an array of arrays (for example, an array of arrays of 2 chars) and an array of pointers. As the wording suggests, their element type is totally different:
Each single element of an array of arrays, like my_arr_of_arrays below, is, well, an array! Not an address, not a pointer: Each element is a proper array, each of the same size (her: 2), a succession of a fixed number of sub-elements. The data is right there in the array object. After char my_arr_of_arrays[][2] = { "a", "b", "c", "" };, my_arr_of_arrays is a succession of characters, grouped in pairs: 'a', '\0', 'b', '\0', 'c', '\0', '\0', '\0'. The picture below illustrates that. Each element in my_arr_of_arrays has a size of 2 bytes. Each string literal is used to copy the characters in it into the corresponding array elements of my_arr_of_arrays. The data can be overwritten later, the copy is not const.
Contrast this with an array of pointers, like my_arr_of_ptrs below! Each element in such an array is, well, a pointer. The data proper is somewhere else! The actual data may have been allocated with malloc, or it is static data like the string literals in my example below. Each element — each address — has a size of 4 byte on a 32 bit architecture, or 8 byte on a 64 bit architecture. Nothing is copied from the string literals: The pointers simply point to the location in the program where the literals themselves are stored. The data is const and cannot be overwritten.
It is confusing that these completely different data structures can be initialized with the same curly-braced initializer list; it is confusing that string literals can serve as a data source for copying characters over into an array, or that their address can be taken and assigned to a pointer: Both char arr[3] = "12": and char *ptr = "12"; are valid, but for arr a copy is made and for ptr the address of the string literal itself is taken.
Your program shows that C permits you to pass an address of an array of 2 chars to a function that expects the address of a pointer; but that is wrong and leads to disaster if the function tries to dereference an "address" which is, in fact, a sequence of characters. C++ forbids this nonsensical conversion.
The following program and image may shed light on the data layout of the two different arrays.
#include <stdio.h>
void f_array_of_arrays(char(* const arr_of_arrays)[2])
{
for (int i = 0; arr_of_arrays[i][0] != 0; i++)
{
printf("string no. %d is ->%s<-\n", i, arr_of_arrays[i]);
}
const char myOtherArr[][2] = { "1", "2", "3", "4", "" };
// arr2d = myOtherArr; // <-- illegal: "const arr2d"!
arr_of_arrays[0][0] = 'x'; // <-- OK: The chars themselves are not const.
}
void f_array_of_pointers(const char** arr_of_ptrs)
{
for (int i = 0; arr_of_ptrs[i][0] != 0; i++)
{
printf("string no. %d is ->%s<-\n", i, arr_of_ptrs[i]);
}
arr_of_ptrs[1] = "87687686";
for (int i = 0; arr_of_ptrs[i][0] != 0; i++)
{
printf("after altering: string no. %d is ->%s<-\n", i, arr_of_ptrs[i]);
}
}
int main()
{
char my_arr_of_arrays[][2] = { "a", "b", "c", "\0" }; // last element has two zero bytes.
const char* my_arr_of_ptrs[] = { "111", "22", "33333", "" }; // "jagged array"
f_array_of_arrays(my_arr_of_arrays);
f_array_of_pointers(my_arr_of_ptrs);
// disaster: function thinks elements are arrays of char but
// they are addresses; does not compile as C++
// f_array_of_arrays(my_arr_of_ptrs);
// disaster: function thinks elements contain addresses and are 4 bytes,
// but they are arbitrary characters and 2 bytes long; does not compile as C++
// f_array_of_pointers(my_arr_of_arrays);
}
Is there any way to get more than 1 string in one array?
#include <stdio.h>
int main (void)
{
char str[4] = {"Linux", "Ubuntu", "Arch", "Void"};
for (int i = 0; i < 4; i++) {
printf("%d", str[i]);
printf("%s", str[i]);
}
printf("%s", str);
}
I just trying to do it. But didn't get it?
How store multiple string or create an array of strings in C, by using 1D array?
The short answer is: You can't
A string in C is by itself a char array (with a zero termination) so there is no way to have multiple strings in a 1D array.
You can make it a 2D array like:
int main()
{
// Make a 2D array to store
// 4 strings with 9 as max strlen
char str[4][10] = {"Linux", "Ubuntu", "Arch", "Void"};
for (int i=0; i<4; ++i) printf("%s\n", str[i]);
return 0;
}
Another approach is to use a 1D array of char pointers to string literals - like:
int main()
{
// Make a 1D array to store
// 4 char pointers
char *str[4] = {"Linux", "Ubuntu", "Arch", "Void"};
for (int i=0; i<4; ++i) printf("%s\n", str[i]);
return 0;
}
but notice that the strings are not saved in the array. The compiler place the strings somewhere in memory and the array just holds pointers to those strings.
Also notice that in the second example you are not allowed to modify the strings later in the program. In the first example you are allowed to change the strings after the initialization, e.g. doing strcpy(str[0], "Centos");
BTW: This may be of interrest Are string literals const?
It is possible to store multiple strings in a 1D array - the issue is accessing anything beyond the initial string. For example:
char strs[] = “foo\0bar\0bletch\0blurga”;
The 1D array strs contains 4 strings, but if we pass strs to any library function, only ”foo” will be used.. We would need to maintain a separate array of pointers into strs to access anything beyond the first string:
char *ptrs[] = {strs, &strs[4], &strs[8], &strs[15]};
If you need your strings to be contiguous in memory then this is a valid aproach, but it is cumbersome, and will be a massive pain in the ass if you need to update any of them. Better to use a 2D array.
I'm new in C programming and I'm trying to make a function that sends what is stored in one array character that each time is going to change. So if my array is first "hello" it should send only 5 characters, but if later is "goodbye" it should send 7. What I want to avoid is have to write a lot of characters if I want to extend my array, like in this:
int say (buttonpressed){
char a[11] = {'h','e','l','l','o'};
int i;
for (i = 0;i<12;i++)
{
U2TXREG = a[i];
while(U2STAbits.TRMT==0);
}
buttonpressed = 0;
return 0;
}
I would apreciate any ideas, thanks!
You need to know the length of your array or use an End-Of-String character (which usually is \x0 - a binary zero).
int say (buttonpressed){
char* a = "hello";
int i;
int size=strlen(a);
for (i = 0;i<size;i++)
{ //rest as before
By using a string constant you initialize the array to end with a null (0) char. This can then be used to find the string length using strlen.
I have also just used a pointer to the string constant as you are not modifying it.
You really need to explain more what do you want to do.
From what you say I understand that you want to change the size and contents of your array without changing the for loop.
If that's the case you can use this:
#define ARRAY_LENGTH 12 /* 12 is an example */
int say (buttonpressed)
{
char a[ARRAY_LENGTH] = { . . . . };
int i;
for(i =0; i<ARRAY_LENGTH; i++){
...
}
....
}
I would store the data and the actual size in a struct (similiar to how you would use a std::vector in C++
struct vec{
char data[11];
unsigned int size;
}
Then in your for loop can just loop from i=0 to i
If your array is always going to be a string, a c-style string would be idiomatic in c. This is just an char array terminated by \0, and test for \0 while looping over the array.
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) );