简体   繁体   中英

Reading in a comma delimited .txt file and putting into array

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> .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM