1

There's a series of coordinates I'm trying to write to an array so I can perform calculations on, but I haven't been able to read the file correctly since I can't ignore the headers, and when I do remove the headers it also doesn't seem to correctly write the values to the array.

The coordinate file is a txt as below.

Coordinates of 4 points  
   x        y         z
-0.06325 0.0359793 0.0420873
-0.06275 0.0360343 0.0425949
-0.0645  0.0365101 0.0404362
-0.064   0.0366195 0.0414512

Any help with the code is much appreciated. I've tried using .ignore to skip the two header lines but they don't seem to work as expected.

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

using namespace std;

int main() {
    int i = 1; 
    int count = 1;
    char separator;

    const int MAX = 10000;

    int x[MAX];
    int y[MAX];
    int z[MAX];
    int dist[MAX];

    char in_file[16]; // File name string of 16 characters long
    char out_file[16];

    ifstream in_stream;
    ofstream out_stream;

    out_stream << setiosflags(ios::left); // Use IO Manipulators to set output to align left

    cout << "This program reads a series of values from a given file, saves them into an array and performs calculations." << endl << endl;

    // User data input

    cout << "Enter the input in_file name: \n";
    cin >> in_file;
    cout << endl;
    
    in_stream.open(in_file, ios::_Nocreate);

    cout << "Enter the output file name: \n";
    cin >> out_file;
    cout << endl;

    out_stream.open(out_file);

    // While loop in case in_file does not exist / cannot be opened

    while (in_stream.fail()) {
        cout << "Error opening '" << in_file << "'\n";
        cout << "Enter the input in_file name: ";
        cin >> in_file;
        in_stream.clear();
        in_stream.open(in_file, ios::_Nocreate);
    }


    while (in_stream.good) {
        in_stream.ignore(256, '\n');
        in_stream.ignore(256, '\n');
        in_stream >> x[i] >> separator >>y[i] >> separator >> z[i];
        i++;
        count = count + 1;
    }

    cout << x[1] << y[1] << z[1];

    in_stream.close();
    out_stream.close();

    return 0;
}

jmtse
  • 11
  • 1
  • 1
    Beside of the problem described in [c++ - Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong? - Stack Overflow](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons), `while (in_stream.good)` is bad because the function is directly used as condition instead of being called. – MikeCAT Mar 30 '21 at 11:39
  • you seem to ignore every 2 out of 3 lines, because you `ignore` inside the loop instead of only once to skip first two lines once – 463035818_is_not_a_number Mar 30 '21 at 11:40
  • @MikeCAT what should the correct conditions be for reading the file? – jmtse Mar 30 '21 at 11:42
  • Just ignore or read the first two lines with getline before the loop and make your loop `while (in_stream >> x[i] >> y[i] >> z[i]) { ... }` You might consider using a `std::vector` rather than making a huge array and either wasting or running out of space. – Retired Ninja Mar 30 '21 at 11:42
  • Your input files consists of lines of text. To read a line of text from a file: this is what `std::getline()` is for. Once you've read each line from the file, you can then work on it further, and extract its contents. But when dealing with input that consists of lines of text, `std::getline()` is always the answer. Any other approach, like using `>>`, or random invocations of `ignore()`, will only end in tears. – Sam Varshavchik Mar 30 '21 at 12:11
  • @RetiredNinja I have getline to read the first two lines, but it still isn't writing the values to the array correctly. Could it be that it's not moving onto the next row? `getline(in_stream, dummy1); ` `getline(in_stream, dummy2);` `while (in_stream >> x[i] >> y[i] >> z[i]) { in_stream >> x[i] >>y[i] >> z[i]; i++; count = count + 1; }` – jmtse Mar 30 '21 at 12:13
  • @SamVarshavchik How would I go about writing the values using getline? – jmtse Mar 30 '21 at 12:16
  • 1
    `std::getline` is for reading, not writing. – Sam Varshavchik Mar 30 '21 at 12:27

1 Answers1

0

Within your reading of the file, you are using in_stream.ignore(256, '\n'); correctly, but you want to use it outside the while loop. When you have it inside the while loop, every time it runs, you will ignore the first two lines, then read the third. Your output would actually read in only a third of what you expect. To fix this, just move those 2 lines outside the while loop.

    in_stream.ignore(256, '\n');
    in_stream.ignore(256, '\n');

    while (in_stream.good)
    {
        in_stream >> x[i] >> separator >>y[i] >> separator >> z[i];
        i++;
        count = count + 1;
    }

This should fix your problem, but you should generally use a vector instead of an array. Vectors automatically manage memory and check for bounds instead of you having to do that. Also, good practice is to read values out of the stream as the while condition instead of in_stream.good:

    while(stream >> var)
    {
        //Your code here
    }

Here is a good resource on why that is.

Hawkeye5450
  • 557
  • 4
  • 15