Run the file up to * string * and then read the columns until there is no decimal *

I have a file similar to

some header
this is the first block
                         1    2    3    4
                         5    6    7    8
                         9   10   11   12
this is the second block
                         1    4    7   10
                         2    5    8   11
                         3    6    9   12
this is the third block
                         1    2    3    4
                         5    6    7    8
                         9   10   11   12

      

I want to read this file and check the words "first", "second" and "third" to read the next blocks of numbers into arrays so that they can be built later. For example, I would only like to read in columns 1 and 2 of the second block. The main problem is that I cannot read until the start of the third block. It stops reading after the first line of a block of seconds. In a simple way, my code looks like this:

#include <string>
#include <fstream>
#include <istream>
#include <vector>

std::string line;
std::vector<double> vector1;
std::vector<double> vector2;
double v1;
double v2;
double v3;
double v4;

ifstream infile ("myfile.txt");
while (std::getline(infile, line)){ 
  if (line.find("second",0) != std::string::npos){    // when "second" is found start to read block.
    while (line.find_first_of("123456789.") != std::string::npos){    // while the next line is not a number continue reading. THIS DOESN'T WORK !
      infile >> v1 >> v2 >> v3 >> v4;
      vector1.push_back(v1);
      vector2.push_back(v2);
      std::getline(infile, line);
    }
  }
}
infile.close();

cout << "Vector1" << "  " << "Vector2" << endl;
for (unsigned int i = 0; i < vector1.size(); i++){
  cout << vector1[i] << "  " << vector2[i] << endl;
}

      

Expected Result:

Vector1  Vector2
1        4
2        5
3        6

      

But I am getting:

Vector1  Vector2
1        4

      

+3


source to share


3 answers


This should fix the internal double read and loop exit,



ifstream infile ("myfile.txt");
while (std::getline(infile, line)) { 
    if (line.find("second",0) != std::string::npos) {
        while (infile >> v1 >> v2 >> v3 >> v4) {
            vector1.push_back(v1);
            vector2.push_back(v2);
            // note getline is removed, else double reads on break.
        }
        // this may be needed if you plan on reading anything else.
        infile.clear();
    }
}

      

+1


source


There are two problems with the code. First, after reading the numbers, the "reading cursor" stays right before the end of the line. Then when you call getline you get an empty line. This is a common problem when mixing string reading methods with other input methods. This happens when using mix gets and scanf, and when mixing streams -> operator and getline.

Second, you read a whole line and then read the numbers from the file again. If you are reading a line of text, you should read the numbers from the line read and not receive new input from the file. So try this:



std::getline(infile, line);
while (line.find_first_of("123456789.") != std::string::npos) {
  std::stringstream stream(line);
  stream >> v1 >> v2 >> v3 >> v4;
  vector1.push_back(v1);
  vector2.push_back(v2);
  std::getline(infile, line);
}

      

+1


source


I'm pretty surprised you got this result. If the string contains "second", then it does not contain any digit, and you cannot enter an if.

I would change the body like this:

ifstream infile("myfile.txt");
while (std::getline(infile, line)){
    if (line.find("second", 0) != std::string::npos)
    {    // when "second" is found start to read block.
        while (infile){    // while the next line is not a number continue reading. THIS DOESN'T WORK !

            infile >> v1 >> v2 >> v3 >> v4;
            if (!infile)
                break;
            vector1.push_back(v1);
            vector2.push_back(v2);
            std::getline(infile, line);
        }
    }
}

      

So, when you find the "second", keep reading the numbers. When the number failure if (!infile)

completes the cycle

+1


source







All Articles