0

I have a file like this

2.7388  0 2.4670
3.6384  1 24.5927
8.7844  0 10.6871
11.2892 0 2.6507
19.6054 1 16.8974
25.8811 0 8.0084

For example i'll take the first row 2.7388 0 2.4670 . Im trying to accomplish something like the following

2.7388 = double x
0      = int y
2.4670 = double z

My attempt

struct fileReader{
double x;
int y;
double z;
};

std::vector<fileReader> afileReader(std::string fileName) {

  std::vector<fileReader> readtheFile;
  std::ifstream List;
  std::string line;
  List.open(fileName);
 char delimiter = ' '; //delimiter added

  while (std::getline(List, line))
  {
    line.pop_back();
    std::string token;
    std::istringstream ss(line);
    fileReader afileReader;

    std::getline(ss, token,delimiter);
    afileReader.x = std::stod(token); //change from stoi to stod
 
    std::getline(ss, token,delimiter);
    afileReader.y = std::stoi(token);

    std::getline(ss, token,delimiter);
    afileReader.z = std::stod(token); //change from stoi to stod
    readtheFile.push_back(std::move(afileReader));
  }

for(fileReader x: readtheFile) {
      std::cout << x.x;
      std::cout << x.y;
      std::cout << x.z;
  }
  return readtheFile;
  passengerList.close();

}

When i run this from main running a line afileReader("file.txt") . I get the following error

terminate called after throwing an instance of 'std::invalid_argument'
  what():  stod //error changed
Aborted (core dumped) 

Im not sure why im getting an error for stoi as its the correct conversion method to convert the int value to the string(as token is a string)

To refer back to the question though I wish to split the record when a blank space is hit. So refering back to the previous example of 2.7388 0 2.4670 , when 2.7388 is read its assigned to variable x, when 0 is read its assigned to varible y and 2.4670 is assigned to variable z

davylang
  • 23
  • 7
  • 3
    Why are you reading it as string? Why not simply do `file >> x >> y >> z`? – brc-dd Sep 29 '20 at 05:52
  • 1
    @brc-dd One problem is that the OP for some reason attempts to read what looks like floating-point numbers into integer variables. – Some programmer dude Sep 29 '20 at 05:53
  • @davylang Why do you try to read floating-point numbers (like e.g. `2.7388`) into integers? That conversion will truncate the value from `2.7388` to `2`. – Some programmer dude Sep 29 '20 at 05:55
  • 1
    As for one problem with the current code, please read more about [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) and think a little more how to use it to split on specific characters rather than newline (which is what you're doing right now). – Some programmer dude Sep 29 '20 at 05:56
  • @brc-dd Ive changed my code to accompany your sugguestions(see edited question above) However now i get the same error but for stod not stoi – davylang Sep 29 '20 at 06:18
  • @brc-dd still get the same error. Are you sugguesting I just do List >> x >> y >> z – davylang Sep 29 '20 at 06:26

1 Answers1

3

(Recommended) More direct way to do this :

#include <fstream>
#include <iostream>
#include <vector>

struct Data {
  double x;
  int y;
  double z;
};

std::vector<Data> fileReader(std::string fileName) {

  std::vector<Data> result;
  std::ifstream file(fileName);

  Data data;

  while (file >> data.x >> data.y >> data.z)
    result.push_back(data);

  for (auto &&i : result)
    std::cout << i.x << ' ' << i.y << ' ' << i.z << '\n';

  return result;
}

int main() { fileReader("test.txt"); }

Sample Run


Problems with your original code :

  1. fileReader::x and fileReader::z were not floating-type numbers.
  2. ' ' was not being passed as delimiter in call to std::getline.
  3. Inconsistent spacing in the file you were reading. (FIX)
  4. For some strange reason you were doing line.pop_back();
  5. [Cause of certain warning] You weren't returning anything from afileReader() (non-void function).

Fixed code :

#include <fstream>
#include <iostream>
#include <istream>
#include <sstream>
#include <vector>

struct fileReader {
  double x;
  int y;
  double z;
};

std::vector<fileReader> afileReader(std::string fileName) {

  std::vector<fileReader> readtheFile;
  std::ifstream List(fileName);
  std::string line;

  while (std::getline(List, line)) {

    std::string token;
    std::istringstream ss(line);
    fileReader afileReader;

    ss >> std::ws;
    std::getline(ss, token, ' ');
    afileReader.x = std::stod(token);

    ss >> std::ws;
    std::getline(ss, token, ' ');
    afileReader.y = std::stoi(token);

    ss >> std::ws;
    std::getline(ss, token);
    afileReader.z = std::stod(token);

    readtheFile.push_back(std::move(afileReader));
  }

  for (auto &&i : readtheFile)
    std::cout << i.x << ' ' << i.y << ' ' << i.z << '\n';

  return readtheFile;
}

int main() { afileReader("test.txt"); }
brc-dd
  • 10,788
  • 3
  • 47
  • 67