new learner
new learner

Reputation: 49

how to store both string and integer in a single 2d array in c++ ? Is it possible? How? I want following results:

1    vikram jha   1999    local
2    ravi kr      1998    outsider
3    anil         2000    outsider
4    john         1999    local

here is a 2d array of size [4][4], I want to store these information in a 2d array. How to do it ? Is it possible in a single array? I am a binger . other ideas are also welcomed.

Upvotes: 0

Views: 377

Answers (1)

Joma
Joma

Reputation: 3859

Code
It uses std::vector as container(dynamic size) with std::tuple as elements or struct as elements.

It also can be C-style array[n] as container(fixed size) with std::tuple as elements or struct as elements.

It also can be std::array as container(fixed size) with std::tuple as elements or struct as elements.

With tuples you donΒ΄t need to create complex types, simply add the dessired types for tuple elements, but the syntax in my opinion I see it uglier, the programmer can fall into errors when he makes a mistake when writing an index of an element of the tuple.

With structs you can create a complex type with functions, fields, constructor. The syntax is simpler, clearer. If you want to use a field, you refer to it by name rather than by an index, thereby reducing typing errors.

I prefer to use the classes provided by the standard c ++ library, you can do more with data types, they come with vitamins(std::array, std::vector). On the other hand, using the arrays in c-style has to do a little more work and reinvent the wheel that already exists with the standard c ++ library. For productivity as a developer and for simplicity in the code I prefer the C ++ classes.

#include <iostream> //to reference std::cout.
#include <string> //to reference std::string
#include <tuple> //to reference std::tuple
#include <vector> //to reference std::vector

//Function. Get total of UTF8 chars in string. u8"β–ˆ"s contains 1 char but it needs 4 bytes to store in std::string. u8"@" contains 1 char but it needs 1 bytes to store in std::string
//UTF8 char size in bytes can be from 1 to 4 bytes.
size_t TotalUTF8Chars(const std::string &data)
{
    size_t ret = 0;
    for (char value : data)
    {
        if ((value & 0xc0) != 0x80)
        {
            ++ret;
        }
    }
    return ret;
}

//Function for add padding chars at right of string, if string total utf8 chars is greater than total width, it returns same string. 
//Example data = u8"β–ˆ", totalwidth = 5, paddingchar= u8"", the result is u8"β–ˆ...."
//Example data = u8"", totalwidth = 10, paddingchar= u8"🐢", the result is u8"🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢"
// 🐢 needs 4 bytes
//Padding char can be only 1 utf8 char length.
std::string PadRight(const std::string &data, const size_t &totalWidth, const std::string &paddingchar)
{
    if (TotalUTF8Chars(paddingchar) > 1)
    {
        throw std::invalid_argument(u8"Invalid padding char length.");
    }
    std::string ret = data;
    if (TotalUTF8Chars(data) >= totalWidth)
    {
        return ret;
    }
    size_t charsToAdd = totalWidth - TotalUTF8Chars(ret);
    for (int i = 0; i < charsToAdd; i++)
    {
        ret.append(paddingchar);
    }

    return ret;
}

/* 
Struct for store the 4 values.
*/
struct Person
{
    int id;//field
    std::string name;//field
    int year;//field
    std::string locality; //field
    
    Person(int id, std::string name, int year, std::string locality) //Constructor / function that allow create new Person with the values of parameters.
    {
        this->id = id; //Initialize the struct field with the value of parameter. The keyword "this" is needed for differentiate field(id) from struct vs parameter(id).
        this->name = name;
        this->year = year;
        this->locality = locality;
    }
    Person() //Constructor //Create new empty/default Person //this constructor is needed for example array of structs
    {
        //Initialize the struct field with default values.
        this->id = 0; 
        this->name = "N/A";
        this->year = 0;
        this->locality = "local";
    } 
};

int main()
{
    //With std::vector of tuples //Dynamic size array // Can be insert any number of elements. //https://en.cppreference.com/w/cpp/container/vector
    std::cout << "β–ˆ With std::vector of tuples" << std::endl;
    std::vector<std::tuple<int, std::string, int, std::string>> persons;//Declaring and create new std::vector<tuple<>>
    persons.push_back(std::tuple<int, std::string, int, std::string>{1, u8"vikram jha", 1999, u8"local"}); //Insert new tuple element at end of vector
    persons.push_back(std::tuple<int, std::string, int, std::string>{2, u8" ravi kr", 1998, u8"outsider"});
    persons.push_back(std::tuple<int, std::string, int, std::string>{3, u8"anil", 2000, u8"outsider"});
    persons.push_back(std::tuple<int, std::string, int, std::string>{4, u8"Anna", 1999, u8"local"});
    persons.push_back(std::tuple<int, std::string, int, std::string>{5, u8"Mary", 1999, u8"local"});
    persons.push_back(std::tuple<int, std::string, int, std::string>{6, u8"Joseph", 1999, u8"local"});
    persons.push_back(std::tuple<int, std::string, int, std::string>{7, u8"Tony Stark", 1999, u8"Stark Industries"});

    for (std::tuple<int, std::string, int, std::string> person : persons) //Range-based for loop, iterate over range of elements.
    {
        //std::get<N>(tupleVariable) where N is the index of field. In this case have 4 fields 0 - 3. 0 = id, 1 = name, 2 = year, 3 = locality 
        std::cout << "Id: " << std::get<0>(person) << "| Name: " << std::get<1>(person) << "| Year: " << std::get<2>(person) << "| Locality: " << std::get<3>(person) << std::endl; //Printing values
    }

    //With std::vector of structs ////Dynamic size array // https://en.cppreference.com/w/cpp/container/vector
    std::cout << "β–ˆ With std::vector of structs" << std::endl;
    std::vector<Person> persons2; //Declaring and create new std::vector<Person>
    persons2.push_back(Person{1, u8"vikram jha", 1999, u8"local"});//Initialize new Persona / Using the parameterized constructor in the struct and insert at end of vector.
    persons2.push_back(Person{2, u8" ravi kr", 1998, u8"outsider"});
    persons2.push_back(Person{3, u8"anil", 2000, u8"outsider"});
    persons2.push_back(Person{4, u8"john", 1999, u8"local"});
    persons2.push_back(Person{3, u8"anil", 2000, u8"outsider"});
    persons2.push_back(Person{7, u8"Tony Stark", 1999, u8"Stark Industries"});
    
    for (Person person : persons2)
    {
        std::cout << "Id: " << person.id << "| Name: " << person.name << "| Year: " << person.year << "| Locality: " << person.locality << std::endl;
    }

    //With C-style array of tuples // Fixed size array. //https://en.cppreference.com/w/cpp/language/array
    int n = 4;
    std::cout << "β–ˆ With C-style array of tuples" << std::endl;
    std::tuple<int, std::string, int, std::string> persons3[n];
    persons3[0] = {1, u8"vikram jha", 1999, u8"local"};
    persons3[1] = {2, u8" ravi kr", 1998, u8"outsider"};
    persons3[2] = {3, u8"anil", 2000, u8"outsider"};
    persons3[3] = {4, u8"john", 1999, u8"local"};

    for (std::tuple<int, std::string, int, std::string> person : persons3)
    {
        std::cout << "Id: " << std::get<0>(person) << "| Name: " << std::get<1>(person) << "| Year: " << std::get<2>(person) << "| Locality: " << std::get<3>(person) << std::endl;
    }

    //With C-style array of struct // Fixed size array. //https://en.cppreference.com/w/cpp/language/array
    n = 4;
    std::cout << "β–ˆ With C-style array of struct" << std::endl;
    Person persons4[n];
    persons4[0] = Person{1, u8"vikram jha", 1999, u8"local"};
    persons4[1] = Person{2, u8" ravi kr", 1998, u8"outsider"};
    persons4[2] = Person{3, u8"anil", 2000, u8"outsider"};
    persons4[3] = Person{4, u8"john", 1999, u8"local"};
    //using for instead of foreach
    for (int i = 0; i < n; i++)
    {
        std::cout << "Id: " << persons4[i].id << "| Name: " << persons4[i].name << "| Year: " << persons4[i].year << "| Locality: " << persons4[i].locality << std::endl;
    }

    //With std::array of struct // Fixed size array // https://en.cppreference.com/w/cpp/container/array
    const size_t n2 = 4; //std::array needs constant value for size. 
    std::cout << "β–ˆ With std::array of struct" << std::endl;
    std::array<Person, n2> persons5; //Need fixed length, constant value.
    persons5[0] = Person(1, u8"vikram jha", 1999, u8"local");
    persons5[1] = Person(2, u8" ravi kr", 1998, u8"outsider");
    persons5[2] = Person(3, u8"anil", 2000, u8"outsider");
    persons5[3] = Person(4, u8"john", 1999, u8"local");
    for (Person person : persons5)
    {
        std::cout << "Id: " << person.id << "| Name: " << person.name << "| Year: " << person.year << "| Locality: " << person.locality << std::endl;
    }

    //Complex example with text formatting
    //With std::array of tuple // Fixed size array. // https://en.cppreference.com/w/cpp/container/array
    std::cout << "β–ˆ With std::array of tuple" << std::endl<<std::endl;
    typedef std::tuple<int, std::string, int, std::string> MyPersonTuple; //reducing the name of the data type and avoid writing std::tuple<int, std::string, int, std::string>
    std::array<MyPersonTuple, 4> persons6{MyPersonTuple{1, u8"vikram jha", 1999, u8"local"},
                                           MyPersonTuple{2, u8" ravi kr", 1998, u8"outsider"},
                                           MyPersonTuple{3, u8"anil", 2000, u8"outsider"},
                                           MyPersonTuple{4, u8"john", 1999, u8"local"}}; //Another form of initialization of std::array using initialization list of MyPersonTuple type. Check typedef
    
    //Print headers
    std::string headers = PadRight(u8"β–ˆ Id: ", 15, u8" ") + PadRight(u8"β–ˆ Name : ", 15, u8" ") + PadRight(u8"β–ˆ Year: ", 15, u8" ") + PadRight(u8"β–ˆ Locality: ", 15, u8" ") + "β–ˆ";
    std::cout << PadRight(u8"", TotalUTF8Chars(headers) , u8"β–ˆ") << std::endl;
    std::cout << headers << std::endl;
    std::cout << PadRight(u8"", TotalUTF8Chars(headers) , u8"β–ˆ") << std::endl;
    for (int i = 0; i < n2; i++)
    {
        //Print elements
        size_t max_size = 13;
        std::string id = PadRight(std::to_string(std::get<0>(persons6[i])), 13, u8" "); //Converting element 0 from tuple element to string -> Padding with spaces
        std::string name = PadRight(std::get<1>(persons6[i]), 13, u8" "); //Padding with spaces second element of tuple.
        std::string year = PadRight(std::to_string(std::get<2>(persons6.at(i))), 13, u8" ");
        std::string locality = PadRight(std::get<3>(persons6[i]), 13, u8" ");
        std::cout << "β–ˆ " << id << "β–ˆ " << name << "β–ˆ " << year << "β–ˆ " << locality << u8"β–ˆ" << std::endl; //Print padded values.
    }
    //Print footer
    std::cout << PadRight(u8"", TotalUTF8Chars(headers) , u8"β–ˆ") << std::endl;
}

Console's output

clang++-7 -pthread -std=c++17 -o main main.cpp
./main
β–ˆ With std::vector of tuples
Id: 1| Name: vikram jha| Year: 1999| Locality: local
Id: 2| Name:  ravi kr| Year: 1998| Locality: outsider
Id: 3| Name: anil| Year: 2000| Locality: outsider
Id: 4| Name: Anna| Year: 1999| Locality: local
Id: 5| Name: Mary| Year: 1999| Locality: local
Id: 6| Name: Joseph| Year: 1999| Locality: local
Id: 7| Name: Tony Stark| Year: 1999| Locality: Stark Industries
β–ˆ With std::vector of structs
Id: 1| Name: vikram jha| Year: 1999| Locality: local
Id: 2| Name:  ravi kr| Year: 1998| Locality: outsider
Id: 3| Name: anil| Year: 2000| Locality: outsider
Id: 4| Name: john| Year: 1999| Locality: local
Id: 3| Name: anil| Year: 2000| Locality: outsider
Id: 7| Name: Tony Stark| Year: 1999| Locality: Stark Industries
β–ˆ With C-style array of tuples
Id: 1| Name: vikram jha| Year: 1999| Locality: local
Id: 2| Name:  ravi kr| Year: 1998| Locality: outsider
Id: 3| Name: anil| Year: 2000| Locality: outsider
Id: 4| Name: john| Year: 1999| Locality: local
β–ˆ With C-style array of struct
Id: 1| Name: vikram jha| Year: 1999| Locality: local
Id: 2| Name:  ravi kr| Year: 1998| Locality: outsider
Id: 3| Name: anil| Year: 2000| Locality: outsider
Id: 4| Name: john| Year: 1999| Locality: local
β–ˆ With std::array of struct
Id: 1| Name: vikram jha| Year: 1999| Locality: local
Id: 2| Name:  ravi kr| Year: 1998| Locality: outsider
Id: 3| Name: anil| Year: 2000| Locality: outsider
Id: 4| Name: john| Year: 1999| Locality: local
β–ˆ With std::array of tuple

β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
β–ˆ Id:          β–ˆ Name:        β–ˆ Year:        β–ˆ Locality:    β–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
β–ˆ 1            β–ˆ vikram jha   β–ˆ 1999         β–ˆ local        β–ˆ
β–ˆ 2            β–ˆ  ravi kr     β–ˆ 1998         β–ˆ outsider     β–ˆ
β–ˆ 3            β–ˆ anil         β–ˆ 2000         β–ˆ outsider     β–ˆ
β–ˆ 4            β–ˆ john         β–ˆ 1999         β–ˆ local        β–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ

You can check/run this code on https://repl.it/@JomaCorpFX/Tuples-and-Struct

References
UTF-8
std::vector
C-style array
std::array
std::tuple
Range based for loop

Upvotes: 3

Related Questions