क्या C / C ++ में किसी सरणी को कॉपी करने के लिए कोई फ़ंक्शन है?


91

मैं एक जावा प्रोग्रामर हूं जो C / C ++ सीख रहा है। तो मुझे पता है कि जावा में System.arraycopy () जैसा एक फ़ंक्शन है; किसी सरणी को कॉपी करने के लिए। मैं सोच रहा था कि किसी सरणी को कॉपी करने के लिए C या C ++ में कोई फंक्शन है या नहीं। मैं केवल लूप, पॉइंटर्स इत्यादि का उपयोग करके किसी सरणी को कॉपी करने के लिए कार्यान्वयन खोजने में सक्षम था। वहाँ एक समारोह है कि मैं एक सरणी की नकल करने के लिए उपयोग कर सकते हैं?


7
man memmoveऔरman memcpy
टिम कूपर

28
उपयोग न करें memcpy, उपयोग करें std::copy। यदि आपके प्रकार में एक सार्थक प्रतिलिपि निर्माता है तो memcpyगलत काम करेगा।
एड एस।

10
क्या आप वास्तव में एक ही समय में C और C ++ सीखने की कोशिश कर रहे हैं? वे बहुत अलग भाषाएं हैं।
फेर्रुकियो

1
वैसे मैंने C का थोड़ा बहुत सीखा है और अब मैंने हाल ही में C ++ सीखना शुरू किया है। मैंने एक ऑनलाइन संसाधन से जो पढ़ा है, मुझे लगा कि C ++ सिर्फ एक भाषा है जिसमें C भाषा के लिए बहुत सारी अतिरिक्त सुविधाएँ हैं।
JL

6
मैं यह इसलिए कह रहा हूं क्योंकि किसी ने भी पहले इसका उल्लेख नहीं किया है: C ++ में आपको लगभग सभी मामलों में std :: वेक्टर का उपयोग करना चाहिए। ऐसे मामले हैं जहां अन्य कंटेनर भी उपयोगी हैं, लेकिन मैं ज्यादातर मामलों में std :: वेक्टर सबसे अच्छा विकल्प होगा। C ++ में कच्ची सरणियों का उपयोग न करें और std :: array से बचने की कोशिश करें।
स्कोली

जवाबों:


79

C ++ 11 के बाद से, आप सरणियों को सीधे कॉपी कर सकते हैं std::array:

std::array<int,4> A = {10,20,30,40};
std::array<int,4> B = A; //copy array A into array B

यहाँ std :: array के बारे में प्रलेखन है


@XAleXOwnZX: वही जो आप किसी अन्य प्रकार के कॉपी असाइनमेंट का समर्थन करते हैं। B = A
स्वैग

2
मुझे लगता है कि फ़ंक्शन बी के लिए ए के मेमोरी एड्रेस की कॉपी है। अगर मैं बी के मेमोरी एड्रेस को बदले बिना ए के आइटम मूल्यों को बी में कॉपी करने की कोशिश करता हूं। मैं उसे कैसे कर सकता हूँ?
एरोन ली

@Aaron_Lee: मैंने अभी इसका परीक्षण किया है, और यह वास्तव में तत्वों को एक अलग मेमोरी स्थान में एक सरणी में कॉपी करता है। असाइनमेंट ऑपरेटर के लिए सरणी वर्ग का स्पष्ट रूप से अपना अधिभार है।
डेव रोव

4
आप लोगों को पता है कि कोड के उन दो लाइनों में कोई असाइनमेंट ऑपरेटर दिखाई नहीं दिया, है ना? यह कॉपी कंस्ट्रक्टर है जिसे तब भी बुलाया जा रहा है, जबकि नोटेशन असाइनमेंट ऑपरेटर की तरह दिखता है।
अल्बिनो कॉर्डियारो

137

चूंकि आपने सी ++ समाधान के लिए कहा था ...

#include <algorithm>
#include <iterator>

const int arr_size = 10;
some_type src[arr_size];
// ...
some_type dest[arr_size];
std::copy(std::begin(src), std::end(src), std::begin(dest));

2
erreur: '
start

23
@ डेविड: वोंग: आप एक पुराने संकलक का उपयोग कर रहे हैं या आपने हेडर को शामिल नहीं किया है। क्या है<iterator>
एड एस

9
हो सकता है कि आपको यह कहना चाहिए कि आपको किसकी आवश्यकता है। में कॉपी है <algorithm>?
जेरी यिर्मयाह

15
मैं केवल इसलिए पूछता हूं क्योंकि अगर आपको यह समझाना था कि std :: start <iterator> में था, जिसका अर्थ है कि लोग googling std नहीं हैं :: यह पता लगाना शुरू करें कि यह किस हेडर में है, इसलिए वे google std के लिए संभावना नहीं है :: उसी के लिए कॉपी करें कारण। यह बेहतर उत्तर देता है यदि किसी को सामान नहीं पूछना है जो केवल टिप्पणियों में उत्तर दिया गया है। हो सकता है कि मैंने आपको इसे करने के लिए संकेत देने के बजाय सिर्फ उत्तर संपादित किया हो।
जेरी जेरेमिया

3
आप src और arr_size में src और end (src) में शुरू (src) को बदल सकते हैं
केल्विन

82

जैसा कि दूसरों ने उल्लेख किया है, सी में आप उपयोग करेंगे memcpy । ध्यान दें कि यह एक कच्ची मेमोरी कॉपी करता है, इसलिए यदि आपकी डेटा संरचनाएं खुद को या एक-दूसरे को इंगित करती हैं, तो कॉपी में पॉइंटर्स अभी भी मूल ऑब्जेक्ट्स को इंगित करेंगे।

C ++ में आप भी उपयोग कर सकते हैं memcpyयदि आपके सरणी सदस्यों पॉड (है कि अनिवार्य रूप से प्रकार है जो आप भी सी में कोई बदलाव नहीं इस्तेमाल किया जा सकता था), लेकिन सामान्य रूप में, कर रहे हैं memcpyजाएगा नहीं की अनुमति दी जाए। जैसा कि दूसरों ने उल्लेख किया है, उपयोग करने का कार्य हैstd::copy

कहा जाता है कि, C ++ में आपको शायद ही कभी कच्चे सरणियों का उपयोग करना चाहिए। इसके बजाय आपको या तो मानक कंटेनरों में से एक का उपयोग करना चाहिए ( std::vectorएक अंतर्निहित सरणी के सबसे करीब है, और मुझे यह भी लगता है कि जावा सरणियों के सबसे करीब - सादे सी ++ सरणियों की तुलना में वास्तव में - लेकिन, std::dequeया std::listकुछ मामलों में अधिक उपयुक्त हो सकता है) या, यदि आप C ++ 11 का उपयोग करते हैं,std::array जो बिल्ट-इन सरणियों के बहुत करीब है, लेकिन अन्य C ++ प्रकारों जैसे मूल्य शब्दार्थों के साथ। मेरे द्वारा उल्लिखित सभी प्रकारों को असाइनमेंट या कॉपी निर्माण द्वारा कॉपी किया जा सकता है। इसके अलावा, आप itter सिंटैक्स का उपयोग करके opne से दूसरे (और यहां तक ​​कि एक अंतर्निहित सरणी से) "क्रॉस-कॉपी" कर सकते हैं।

यह संभावनाओं का अवलोकन देता है (मुझे लगता है कि सभी प्रासंगिक हेडर शामिल किए गए हैं):

int main()
{
  // This works in C and C++
  int a[] = { 1, 2, 3, 4 };
  int b[4];
  memcpy(b, a, 4*sizeof(int)); // int is a POD

  // This is the preferred method to copy raw arrays in C++ and works with all types that can be copied:
  std::copy(a, a+4, b);

  // In C++11, you can also use this:
  std::copy(std::begin(a), std::end(a), std::begin(b));

  // use of vectors
  std::vector<int> va(a, a+4); // copies the content of a into the vector
  std::vector<int> vb = va;    // vb is a copy of va

  // this initialization is only valid in C++11:
  std::vector<int> vc { 5, 6, 7, 8 }; // note: no equal sign!

  // assign vc to vb (valid in all standardized versions of C++)
  vb = vc;

  //alternative assignment, works also if both container types are different
  vb.assign(vc.begin(), vc.end());

  std::vector<int> vd; // an *empty* vector

  // you also can use std::copy with vectors
  // Since vd is empty, we need a `back_inserter`, to create new elements:
  std::copy(va.begin(), va.end(), std::back_inserter(vd));

  // copy from array a to vector vd:
  // now vd already contains four elements, so this new copy doesn't need to
  // create elements, we just overwrite the existing ones.
  std::copy(a, a+4, vd.begin());

  // C++11 only: Define a `std::array`:
  std::array<int, 4> sa = { 9, 10, 11, 12 };

  // create a copy:
  std::array<int, 4> sb = sa;

  // assign the array:
  sb = sa;
}

1
यादगार उदाहरण गलत है; स्रोत और गंतव्य स्विच किए जाते हैं।
एटी - छात्र

1
वास्तव में, memcpyउदाहरण में यह एकमात्र गलती नहीं थी ; आकार भी गलत था। मैंने अब इसे ठीक कर लिया है, धन्यवाद।
celtschk

आप सिर्फ std के नाम स्थान का उपयोग करने के बजाय सभी समय std क्यों लिख रहे हैं ???
काला

क्या आप मेमसीपी (बी, ए, आकारऑफ ए) नहीं कर सकते; भी?
आरडी

एक जावा सरणी पसंद की std:arrayतुलना में अधिक है std::vector, क्योंकि इसका एक निश्चित आकार है।
बार्ट वैन ह्युकेलोम

17

आप का उपयोग कर सकते हैं memcpy(),

void * memcpy ( void * destination, const void * source, size_t num );

memcpy()numद्वारा बताए गए sourceमेमोरी ब्लॉक से सीधे बताए गए स्थान से बाइट्स के मूल्यों को कॉपी करता है destination

यदि ओवरलैप destinationऔर sourceउपयोग किया जाता है, तो आप उपयोग कर सकते हैं memmove()

void * memmove ( void * destination, const void * source, size_t num );

memmove()numबताई गई sourceमेमोरी ब्लॉक द्वारा बताए गए स्थान से बाइट्स के मूल्यों को कॉपी करता है destination। नकल करना ऐसा लगता है जैसे कि एक मध्यवर्ती बफर का उपयोग किया गया था, जो गंतव्य और स्रोत को ओवरलैप करने की अनुमति देता है।


3
यहाँ -1 के लिए जाना है। ओपी विशेष रूप से C ++ समाधान के लिए पूछ रहा है और यह उत्तर कहता है कि जिन स्थितियों में memcpyगलत है, उनमें से कुछ भी गलत नहीं है, अर्थात, बाइट्स की नकल करना अपर्याप्त है।
एड एस।

2
@EdS। यदि आपने ध्यान नहीं दिया है, तो ओपी अब C या C ++ समाधान के लिए पूछ रहा है ।
ऑटिस्टिक

4
जब मैंने उत्तर दिया कि ओपी C / C ++ समाधानों के लिए पूछ रहा है, हालांकि मैं व्यक्तिगत रूप से मानता हूं कि "C / C ++" दोनों भाषाओं का अपमान है। :)
दीपू

उचित रूप से, मुझे नहीं पता था कि यह बदल रहा था। शायद यह भी कहा कि पहले और मैं इसे याद किया। -1 निकाला गया।
एड एस।

2
@ ईडीएस मुझे लगा कि यह 2 मिनट है, लेकिन इस बात पर ध्यान दिए बिना कि यह उत्तर जिस समय पोस्ट किया गया था, प्रश्न C और C ++ दोनों को संदर्भित किया गया था। यहां तक ​​कि अगर मैं गलत था और किसी बिंदु पर सवाल केवल सी ++ ने कहा, तो डाउनवोट को वारंट नहीं किया गया था।
जिम बाल्टर

16

memcpyC में, std::copyC ++ में उपयोग करें ।


एक छोटी सी सरणी के लिए, मुझे लगता है कि न तो किसी भी फ़ंक्शन कॉल ओवरहेड ( memcpyएक संकलक आंतरिक होना चाहिए) को उकसाना नहीं है?
15

@ मेहरदाद मैंने अन्यथा नहीं कहा; सिर्फ एक टिप्पणी कर रहा हूँ। और मैं इसे या तो नीचे नहीं किया।
एमडी एक्सएफ

12

मुझे एड एस का उत्तर पसंद है, लेकिन यह केवल निश्चित आकार के सरणियों के लिए काम करता है, न कि जब सरणियों को संकेत के रूप में परिभाषित किया जाता है।

तो, C ++ समाधान जहां सरणियों को संकेत के रूप में परिभाषित किया गया है:

#include<algorithm>
...
const int bufferSize = 10;
char* origArray, newArray;
std::copy(origArray, origArray + bufferSize, newArray);

नोट : buffersize1 के साथ कटौती करने की आवश्यकता नहीं है :

  1. श्रेणी के सभी तत्वों को [पहले, अंतिम) पहले से शुरू करके अंतिम -१ तक ले जाना

देखें: https://en.cppreference.com/w/cpp/algorithm/copy


10

C में आप उपयोग कर सकते हैं memcpy। C ++ std::copyमें <algorithm>हैडर से उपयोग करें ।


3

C ++ 11 में आप Copy()std कंटेनरों के लिए काम कर सकते हैं

template <typename Container1, typename Container2>
auto Copy(Container1& c1, Container2& c2)
    -> decltype(c2.begin())
{
    auto it1 = std::begin(c1);
    auto it2 = std::begin(c2);

    while (it1 != std::end(c1)) {
        *it2++ = *it1++;
    }
    return it2;
}

std::endप्रदर्शन कारणों से (लूप के दौरान पुनरावृत्तियों को बदलना या अमान्य नहीं करता है, इसलिए अंत को फिर से गणना करना अनावश्यक है), लूप के बाहर खींचने के लिए यह बेहतर विचार होगा ।
celtschk

3

मैं यहाँ C और C ++ भाषा के लिए, सरणी के 2 तरीके देता हूँ। memcpy और कॉपी दोनों सी पर प्रयोग करने योग्य गिरफ्तारी ++ लेकिन प्रति सी के लिए प्रयोग करने योग्य नहीं है, आप उपयोग करने के लिए है memcpy अगर आप सी में सरणी कॉपी करने के लिए कोशिश कर रहे हैं

#include <stdio.h>
#include <iostream>
#include <algorithm> // for using copy (library function)
#include <string.h> // for using memcpy (library function)


int main(){

    int arr[] = {1, 1, 2, 2, 3, 3};
    int brr[100];

    int len = sizeof(arr)/sizeof(*arr); // finding size of arr (array)

    std:: copy(arr, arr+len, brr); // which will work on C++ only (you have to use #include <algorithm>
    memcpy(brr, arr, len*(sizeof(int))); // which will work on both C and C++

    for(int i=0; i<len; i++){ // Printing brr (array).
        std:: cout << brr[i] << " ";
    }

    return 0;
}

4
using namespace std;एक बुरा अभ्यास है । कभी इसका इस्तेमाल न करें। Cplusplus.com के बजाय, कृपया cppreference.com का उपयोग करें, जिसमें मानक के बहुत बेहतर और अद्यतित प्रलेखन शामिल हैं। stdio.hC ++ बराबर है cstdioकि बजाय उपयोग करते हैं,। इसके अतिरिक्त, कोड काफी गैर-मुहावरेदार C ++ है। मुझे लगता है कि यदि आप C और C ++ के लिए अलग-अलग समाधानों का प्रदर्शन कर चुके हैं तो यह बहुत स्पष्ट होगा।
ताम्र

3

बस अपने कोड में मानक पुस्तकालय शामिल करें।

#include<algorithm>

सरणी आकार के रूप में चिह्नित किया जाएगा n

आपका पुराना ऐरे

int oldArray[n]={10,20,30,40,50};

नई ऐरे की घोषणा करें जिसमें आपको अपने पुराने ऐरे मूल्य को कॉपी करना होगा

int newArray[n];

इसे इस्तेमाल करो

copy_n(oldArray,n,newArray);

1

सबसे पहले, क्योंकि आप C ++ पर स्विच कर रहे हैं, इसलिए पारंपरिक सरणी के बजाय वेक्टर का उपयोग करने की सिफारिश की जाती है । इसके अलावा, एक सरणी या वेक्टर की प्रतिलिपि बनाने के लिए, आपके लिए सबसे अच्छा विकल्प है।std::copy

प्रतिलिपि फ़ंक्शन का उपयोग करने के तरीके के लिए इस पृष्ठ पर जाएं: http://en.cppreference.com/w/cpp/algorithm/copy

उदाहरण:

std::vector<int> source_vector;
source_vector.push_back(1);
source_vector.push_back(2);
source_vector.push_back(3);
std::vector<int> dest_vector(source_vector.size());
std::copy(source_vector.begin(), source_vector.end(), dest_vector.begin());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.