-2

Say have a file named, "dogs.txt", and it has like the name, breed, its age, and id num. So i wanted to read each element into my c++ program so they're accessible by like dog[0,2] will give me the 2nd element (breed) of the 0th dog.

example:

max, beagle, 12, 1  
sam, pit bull, 2, 2  

how would i code that into my program and then have it store into an array?

i can only use <iostream>, <fstream>, <iomanip>, <vector>, <cmath>, <ctime>, <cstdlib>, and <string>.

SirDarius
  • 41,440
  • 8
  • 86
  • 100
  • 1
    And what does your code look like for your current attempt? What *exactly* are you having problems with? What does the input look like (*exactly*)? Without code and a specific problem description, you can *not* expect anyone to give you a solution to your problem. The question "as given" is severely lacking in relevant details (and *I'd say* is unanswerable). – Jesper Juhl Oct 09 '19 at 18:39
  • Possible duplicate of [How can I read and parse CSV files in C++?](https://stackoverflow.com/questions/1120140/how-can-i-read-and-parse-csv-files-in-c) – drescherjm Oct 09 '19 at 18:55

1 Answers1

0

Looks like your input data is one record per line (row).
So, let's model the row:

struct Record  
{
    std::string name;
    std::string breed;
    int         age;
    int         id;
    friend std::istream& operator>>(std::istream& input, Record& r);
};

std::istream& operator>>(std::istream& input, Record& r)
{
    // read the fields into a string.
    std::string text_line;
    std::getline(input, text_line);
    char comma;
    std::istringstream input_stream(text_line);
    // Read the name until a comma.
    std::getline(input_stream, r.name, ',');
    // Read the bread until a comma.
    std::getline(input_stream, r.breed, ',');
    input_stream >> r.age;
    input_stream >> comma;
    input_stream >> r.id;
    return input_stream;
}

You input code would look something like this:

std::vector<Record> database;
Record r;
while (dog_file >> r)
{
  database.push_back(r);
}

Edit 1: Accessing database records
To find the breed of the second dog:

  std::cout << database[1].breed << "\n";

Remember that indices are zero based. So the 2nd element is at index 1.

Edit 2: Accessing fields by number
The issue with accessing fields by number is that the fields are different types. However, this can be resolve by return a string for all the contents because all types can be converted to a string:

struct Record  
{
    std::string name;
    std::string breed;
    int         age;
    int         id;
    std::string operator[](int field_index);
    std::string operator[](const std::string& field_name);
};
std::string Record::operator[](int field_index)
{
    std::string value;
    std::ostringstream value_stream;
    switch (field_index)
    {
        case 0:  value = name; break;
        case 1:  value = breed; break;
        case 2:  
            value_stream << age;
            value = value_stream.str();
            break;
        case 3:  
            value_stream << age;
            value = value_stream.str();
            break;          
    }
    return value;
}

std::string Record::operator[](const std::string& field_name)
{
    std::string value;
    std::ostringstream value_stream;
    if (field_name == "name") value = name;
    else if (field_name == "breed") value = breed;
    else if (field_name == "age")
    {
        value_stream << age;
        value = value_stream.str();
    }
    else if (field_name == "id")
    {
        value_stream << id;
        value = value_stream.str();
    }
    return value;
}

IMHO, the preference should be to refer to a struct's members by member name not treated as an array. One issue with treating the struct as an array is that the fields have different types. C++ variables like to be only one type, functions can only return one type. You can add complexity by using a union which will have a type ID field or maybe a tuple. The simplest method is to access by member using the '.' notation.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154