0

How do I create a dynamic array of fixed length strings?

I created class AString which has pointers to struct _str which has fixed-length array data.

How to assign values, and what is wrong?

#include "stdafx.h"
#include <iostream>

struct _str {
    char data[20];
};

class AString {
public:
    AString();
    ~AString();
    void Add(_str string);
private:
    _str *str;
    int count;
};

AString::AString() {
    std::cout << "Constructor" << std::endl;
    str = nullptr;
    count = 0;
}

AString::~AString() {
    std::cout << "Destructor" << std::endl;
    if (str != nullptr) delete[] str;
}

void AString::Add(_str string) {
    _str *str2 = new _str[count+1];
    for (int i=0;i<count;i++) {
        str2[i] = str[i];
    }
    delete[] str;
    str = str2;
    count++;
    str[count-1] = string;
}

int _tmain(int argc, _TCHAR* argv[])
{
    AString astring;
    _str str1;
    str1.data="0123456789012345678"; // cannot convert from 'const char[20]' to 'char[20]'
    astring.Add(str1);
    std::cin.get();
    return 0;
}

str1.data="0123456789012345678";: cannot convert from 'const char[20]' to 'char[20]'

Want to: not use _str str1;, and use char str1[20];

7
  • AStrring needs a pointer to an array it can change, but string literals cannot be changed. You have to decide if you want to use the literal's storage, but turn AString into an immutable type, or if you want to copy the string literal to a modifiable array. Commented Jan 28, 2021 at 13:50
  • Does this answer your question? Assigning value to char array Commented Jan 28, 2021 at 13:50
  • There is an error in your logic. Your destructor delete[]s the pointed array but you never new[] an array in the first place. Commented Jan 28, 2021 at 13:51
  • 2
    "dynamic array" in C++ is spelled "std::vector". Commented Jan 28, 2021 at 13:51
  • Why not using std::array<char, 20> ? Commented Jan 28, 2021 at 13:51

4 Answers 4

0

As for me, I used this:

   strcpy(str1.data, "0123456789012345678");

Here is the main:

int main(int argc, char* argv[])
{
    AString astring;
    _str str1;
    //str1.data=const_cast<char>("0123456789012345678"); // cannot convert from 'const char[20]' to 'char[20]'
    strcpy(str1.data, "0123456789012345678");
    astring.Add(str1);

    std::cout << str1.data;
    std::cin.get();
    return 0;
}

The result is as follows:

Constructor
0123456789012345678
Sign up to request clarification or add additional context in comments.

Comments

0

First of all, I would recomend you yo use std::string or std::array. But if you forced to use char[], I would recomend you to use strncpy instead of operator =, so it would looks like this

strncpy(str1.data,"0123456789012345678", 20); // cannot convert from 'const char[20]' to 'char[20]'

Comments

0

To copy char* or block of memory, it is better to use memcpy!

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

It copies the values of length bytes starting the location pointed to by source directly to the memory block pointed to by destination. Note that, the underlying type of the objects pointed to by both the source and destination pointers dose not matter.

You can also use strncpy.

char* strncpy(char* destination, const char* source, size_t length);

It works properly for your code but if there is/are some 0 valued bytes, the strncpy consider it as null-termination and coping continued with '0' i.e. (pad) until length is satisfied.

try

memcpy(str1.data, "0123456789012345678", 20);

Comments

0

You can't assign to arrays - that's just the way it is.
You could use strncpy in main, or get an assignable array with std::array<char, 20>, but if there was a need to do this by hand, I would add constructors (and hide the implementation details) in order to keep things safe:

class _str {
  public:
    typedef char base[20];
    _str() { data[0] = 0; }
    _str(const base& in) { strncpy(data, in, 20); }
    const base& get() const { return data; }
 private:
    base data;
};

and then you can

AString astring;
_str str1 = "01234567890123456789"; // Fine
astring.Add(str1);
std::cout << str1.get();
_str str2 = "012345678901234567890"; // Compilation error
_str str3 = "0"; // Compilation error

5 Comments

hi, I get error: 'base': symbol cannot be used in a using-declaration
If you're using a very old C++ version, such as C++03, you need typedef char base[20];.
I'm using Visual Studio 2012. On base data = {} I get error: data member initializer is not allowed
@jsmith I have updated the answer to an older variant.
Is it possible to create array of strings of arbitrary length? Move "20" to constructor parameters