В C у меня есть два массива char:
char array1[18] = "abcdefg";
char array2[18];
Как скопировать значение array1
в array2
? Могу ли я просто сделать это: array2 = array1
?
В C у меня есть два массива char:
char array1[18] = "abcdefg";
char array2[18];
Как скопировать значение array1
в array2
? Могу ли я просто сделать это: array2 = array1
?
Вы не можете напрямую выполнить array2 = array1
, потому что в этом случае вы будете манипулировать адресами (char *
) массивов, а не их значениями.
Для такой ситуации рекомендуется использовать strncpy
чтобы избежать переполнения буфера, особенно если array1
заполняется из пользовательского ввода (клавиатура, сеть и т.д.). Вот так:
// Will copy 18 characters from array1 to array2
strncpy(array2, array1, 18);
Как @Prof. Falken упоминается в комментариях, strncpy
может быть злым. Убедитесь, что целевой буфер достаточно большой, чтобы в нем содержался исходный буфер (включая \0
в конце строки).
Если ваши массивы не являются строковыми массивами, используйте: memcpy(array2, array1, sizeof(array2));
Если вы хотите защитить от строк без прерывания, которые могут вызвать всевозможные проблемы, скопируйте свою строку следующим образом:
char array1[18] = {"abcdefg"};
char array2[18];
size_t destination_size = sizeof (array2);
strncpy(array2, array1, destination_size);
array2[destination_size - 1] = '\0';
Эта последняя строка действительно важна, потому что strncpy()
не всегда null завершает строки. (Если буфер назначения слишком мал, чтобы содержать всю исходную строку, sntrcpy() не будет завершать нулевую строку.)
В manpage для strncpy() даже указано "Предупреждение: если в первом n байтах src нет нулевого байта, строка, помещенная в dest, не будет заканчиваться нулем".
Причина, по которой strncpy() ведет себя несколько странно, состоит в том, что на самом деле она не была изначально предназначена для безопасного копирования строк.
Другим способом является использование snprintf() в качестве безопасной замены для strcpy():
snprintf(array2, destination_size, "%s", array1);
(Спасибо jxh за подсказку.)
Вы не можете назначать массивы, имена - это константы, которые нельзя изменить.
Вы можете скопировать содержимое, используя:
strcpy(array2, array1);
Предполагая, что источник является допустимой строкой и что назначение достаточно велико, как в вашем примере.
Как отмечали другие, строки копируются с strcpy()
или его вариантами. В некоторых случаях вы также можете использовать snprintf()
.
Вы можете назначать только массивы так, как вы хотите, как часть назначения структуры:
typedef struct { char a[18]; } array;
array array1 = { "abcdefg" };
array array2;
array2 = array1;
Если ваши массивы передаются функции, будет показано, что вам разрешено назначать их, но это просто случайность семантики. В C массив будет распадаться на тип указателя со значением адреса первого члена массива, и этот указатель будет передан. Итак, ваш параметр массива в вашей функции - это просто указатель. Назначение - это просто назначение указателя:
void foo (char x[10], char y[10]) {
x = y; /* pointer assignment! */
puts(x);
}
Сам массив остается неизменным после возврата из функции.
Это семантическое значение "decay to pointer value" для массивов является причиной того, что присваивание не работает. Значение l имеет тип массива, но r-значение - тип разложившегося указателя, поэтому назначение выполняется между несовместимыми типами.
char array1[18] = "abcdefg";
char array2[18];
array2 = array1; /* fails because array1 becomes a pointer type,
but array2 is still an array type */
Что касается того, почему была введена семантика "распад к указателю", это было для обеспечения совместимости исходного кода с предшественником C. Вы можете прочитать Разработка языка C для деталей.
он должен выглядеть следующим образом:
void cstringcpy(char *src, char * dest)
{
while (*src) {
*(dest++) = *(src++);
}
*dest = '\0';
}
.....
char src[6] = "Hello";
char dest[6];
cstringcpy(src, dest);
array2 = array1;
не поддерживается в c. Для этого вам нужно использовать такие функции, как strcpy().
Я рекомендую использовать memcpy() для копирования данных.
Также, если мы назначим буфер другому как array2 = array1
, оба массива имеют одну и ту же память, и любое изменение в arrary1 также отклоняется в массиве2. Но мы используем memcpy, оба буфера имеют разные массивы. Я рекомендую memcpy(), потому что strcpy и связанная функция не копируют символ NULL.
c функции ниже только... С++ вам нужно сделать массив char, затем использовать строчную копию, а затем использовать функции tokenizor для строк... С++ сделал это намного сложнее сделать 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;
}
для целых типов
#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")
Вы не можете назначать массивы для их копирования. Как копировать содержимое одного в другое зависит от нескольких факторов:
Для массивов char
, если вы знаете, что исходный массив имеет нулевой конец, а целевой массив достаточно велик для строки в исходном массиве, включая нулевой ограничитель, используйте strcpy()
:
#include <string.h>
char array1[18] = "abcdefg";
char array2[18];
...
strcpy(array2, array1);
Если вы не знаете, достаточно ли массива назначения, но источником является строка C, и вы хотите, чтобы пункт назначения был правильной строкой C, используйте snprinf()
:
#include <stdio.h>
char array1[] = "a longer string that might not fit";
char array2[18];
...
snprintf(array2, sizeof array2, "%s", array1);
Если исходный массив необязательно завершен нулем, но вы знаете, что оба массива имеют одинаковый размер, вы можете использовать memcpy
:
#include <string.h>
char array1[28] = "a non null terminated string";
char array2[28];
...
memcpy(array2, array1, sizeof array2);
Ну, технически вы можете...
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" */
но это не будет выглядеть очень красиво.
(Да, приведенный выше код разрешен для работы всегда и он переносим)