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];

jsmith
  • 175
  • 1
  • 10
  • `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. – François Andrieux Jan 28 '21 at 13:50
  • Does this answer your question? [Assigning value to char array](https://stackoverflow.com/questions/14915924/assigning-value-to-char-array) – Yksisarvinen Jan 28 '21 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. – François Andrieux Jan 28 '21 at 13:51
  • 2
    "dynamic array" in C++ is spelled "`std::vector`". – Sam Varshavchik Jan 28 '21 at 13:51
  • Why not using `std::array` ? – Damien Jan 28 '21 at 13:51
  • But really, it would be best to just use `std::string` instead of `_str`. And `std::vector` instead of `new[]`. – Yksisarvinen Jan 28 '21 at 13:51
  • It looks like you intend for your `AString` to manage an owning raw pointer. You need to learn about [The rule of 3/5/0](https://en.cppreference.com/w/cpp/language/rule_of_three) to avoid problems when you try to use your type. Prefer standard containers like `std::vector` and smart pointers like `std::unique_ptr` instead of managing memory manually. – François Andrieux Jan 28 '21 at 13:52

4 Answers4

1

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
Pat. ANDRIA
  • 2,330
  • 1
  • 13
  • 27
1

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]'
Deumaudit
  • 978
  • 7
  • 17
1

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);
Ali Razmkhah
  • 280
  • 1
  • 10
1

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
molbdnilo
  • 64,751
  • 3
  • 43
  • 82