简体   繁体   中英

Reading data into a struct array from a file

I have an input file that looks like this

 1 0 3
 2 11 5
 3 15 1
 4 16 11

and a structure that looks like this

struct numb {
int numb1;
int numb2;
int numb3;
}

and I need to create an array of the struct so that each element of the array holds all three numbers. So

numbArray[0].numb1 == 1
numbArray[0].numb2 == 0
numbArray[0].numb3 == 3
numbArray[1].numb1 == 2
numbArray[1].numb2 == 11

and so on. I've gotten the hang of opening and closing files, finding how many lines there are in a file, and reading a single line from a file, but I do not know how to store individual elements from a line.

My program looks like this so far:

#include <iostream>
#include <fstream>
#include <string>

int main(int argc, char* argv[])
{
    ifstream inFile(argv[1]);
    int fileLength = 0;
    std::string line;
    while(std::getline(inFile, line))
    {
        ++fileLength;
    }
    struct numb {
    int numb1;
    int numb2;
    int numb3;
    }
    if(inFile.is_open())
    {
        for(unsigned i = 0; i <= fileLength; i++)
        {
            //What to do here?
        }
    }
}

Use getline when you don't have regular structure to the input and need to handle variation between lines. When your input file has regular structure (in this case, there are always three values per line), then simply use the stream extraction operators directly:

#include <iostream>
#include <vector>

struct group
{
    int n1;
    int n2;
    int n3;
};

int main()
{
    std::vector<group> groups;
    while (std::cin)
    {
        group line;
        line.n1 << std::cin;
        line.n2 << std::cin;
        line.n3 << std::cin;
        groups.push_back(group);
    }
}

Express your ideas directly in code as much as possible.

Note I've written the code assuming that the file is in the proper form. If there are too many or too few values per line, then the above code will be confused. However, it is best to code the simplest thing that could possibly work and worry about complexity when you need it. In your example you stated that the input file was well-formed, so there's no need to overcomplicate things.

I recommend using a std::stringstream for this:

#include <iostream>
#include <sstream>
#include <string>
#include <stdio.h>
#include <vector>

struct numb {
  int numb1;
  int numb2;
  int numb3;
};

void populate(std::vector<numb>& my_numbs, std::string line) {
   std::stringstream ss(line);
   numb my_numb;
   ss >> my_numb.numb1 >> my_numb.numb2 >> my_numb.numb3;
   my_numbs.push_back(my_numb);
}

void output(const numb my_numbs) {
    printf("%d %d %d\n", my_numbs.numb1, my_numbs.numb2, my_numbs.numb3);
}

int main(int argc, char* argv[]) {
  ifstream inFile(argv[1]);
  std::string line;
  std::vector<numb> my_vect;
  while(std::getline(inFile, line)) {
    populate(my_vect, line);
  }

  for(size_t i = 0; i < my_vect.size(); ++i) {
    std::cout << "my_vect[" << i << "]:";
    output(my_vect[i]);
  }

  return 0;
}

std::stringstream s allow you to parse out data types from std::string s, you you just need to parse out 3 int s, which you can use with your struct. You then push the struct into your vector.

Here's the working ideone taking input from stdin.

You should probably be able to do something like this:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
    ifstream inFile(argv[1]);
    int fileLength = 0;
    std::string line;
    struct numb {
        int numb1;
        int numb2;
        int numb3;
    };
    vector<vector<int>> sets;
    int n1, n2, n3;
    while (std::cin >> n1)
    {
        cin >> n2;
        cin >> n3;
        vector<int> vec;
        vec.push_back(n1);
        vec.push_back(n2);
        vec.push_back(n3);
        sets.push_back(vec);
    }

    numb * numbSet = new numb[sets.size()];

    //Since the vectors data is continuous in memory just as the array of structs are
    //you can just copy the data directly
    for (int i = 0; i < sets.size(); i++)
    {
        std::memcpy(&numbSet[i], &sets[i][0], sizeof(numb));
    }
}

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