-1

I have successfully opened and discarded the headers. Then I calculated the distances between point 1 and others and the minimum distance as well. However, I am not sure how to make the code work for more than 4 points. The text file I am trying to extract data from looks like:

Coordinates of many points (1st line)

x y z (second)

-0.06325 0.03597 0.042823 (third line)

. . . . . . . . .

continued .. and point 1 has coordinates (-0.06325, 0.03597 , 0.042823).

Also, I need to tell which is the closest point to point 1 and the distance between point 1 and the closest point on the output screen, could you help me? Thank you.

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;

int main() {

double x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, dist_12, dist_13, 
dist_14, minimum_distance;
ifstream inFile("input-week6-ad-q4-2.txt"); // ifstream function to read the 
file
string line, c; // To read the characters
char ch;


if (inFile.is_open())
{
    getline(inFile, line); // To read the header of the input file then 
discard it
    getline(inFile, line);



    inFile >> x1 >> y1 >> z1;
    inFile >> x2 >> y2 >> z2;
    inFile >> x3 >> y3 >> z3;
    inFile >> x4 >> y4 >> z4;

    int i = 1;
    while (inFile >> xi >> yi >> zi) {

        i++;    
    }
    int number_of_points = i;

    inFile.close();

    }

  else
    cout << "The file could not be opened." << "\n"; // To check for any 
 error

system("pause");
return 0;
 }
JJL
  • 15
  • 4
  • I recommend replacing `while (!inFile.eof()) { inFile >> xi >> yi >> zi ;` with `while (inFile >> xi >> yi >> zi) {`. [Rational.](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – user4581301 Mar 15 '19 at 23:43
  • Thanks for your comment but could you explain why? I am a beginner. There are more than 100 lines in the data file and I want to read it all the way through the end, is there no need to use eof? – JJL Mar 15 '19 at 23:47
  • 2
    You will have a better Stack Overflow experience if you A) ask questions with only one question and B) make an attempt at solving the problem. If your solution works, great! You're done! If it doesn't, you might only be out by a little bit and the answers will probably come fast and furious. If you are out by a lot, 1) people know you tried. This is socially important and 2) people have a baseline they can use to make better-targeted answers. – user4581301 Mar 15 '19 at 23:48
  • I completely understand. I tried to use for loops but did not work when I tried on Debugger. So I deleted from my code. – JJL Mar 15 '19 at 23:51
  • JJL, It's covered well in the linked question ([Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong)), but the basis is you test for the end of the file BEFORE reading. What if the read fails because it hit the end of the file? Ooops. Plus there are many more things that can go wrong reading from a file than merely reaching the end of the file. If any occur, you missed them and kept trying to read a broken file. This usually is infinite loop because the end can't be reached . – user4581301 Mar 15 '19 at 23:51
  • Any time you get input you have to follow a certain order of operations: read data, verify that you read correct data, use data. Any other order usually results in the program making decisions based on bad data sooner or later. – user4581301 Mar 15 '19 at 23:53
  • `while (inFile >> xi >> yi >> zi)` will loop until ANYTHING goes wrong and then not enter the loop. See [std::basic_ios::operator bool](https://en.cppreference.com/w/cpp/io/basic_ios/operator_bool) for the nitty-gritty details of how. – user4581301 Mar 15 '19 at 23:56
  • I found an example similar to mine, could you check please? – JJL Mar 16 '19 at 00:23

1 Answers1

0

Good question. As mentioned in the comments, a preferred way to read a file of unknown length with ifstream is to use something like while (inFile >> xi >> yi >> zi).

To track the closest point and distance, check this after each read and update the shortest distance and the point index if you find one that is closer than the last point.

Since you were already using sqrt(), I thought it was OK to use the pow() function to calculate the square in the distance formula. Good luck and let me know if this is helpful or if there is something that is confusing.

#include <iostream>
#include <fstream>
#include <string>
#include <math.h>
#include <vector>

int main()
{
  double xFirst, yFirst, zFirst, xi, yi, zi;
  std::ifstream
      inFile("input-week6-ad-q4-2.txt");
  std::string line; // To read the characters
  double min_distance{UINT_MAX}; // Start with largest distance possible.
  uint closest_point;

  if (inFile.is_open()) {
    // read and discard first 2 lines of file
    getline(inFile, line); getline(inFile, line);

    // Save first point's coordinates
    inFile >> xFirst >> yFirst >> zFirst;
    int i = 1;
    while (inFile >> xi >> yi >> zi) { // safer way to read 3 vars from file
      i++;
      // use the pow(base, power) function for squaring
      double distance = sqrt(pow((xi - xFirst), 2)
                                 + pow((yi - yFirst), 2)
                                 + pow((zi - zFirst), 2));
      if (distance < min_distance) {
        min_distance = distance;
        closest_point = i;
      }
    }
    std::cout << "Read " << i  << " points\n";

    inFile.close();
  }

  std::cout << "The minimum distance is " << min_distance
            << ", which is the distance between point[1] and point["
            << closest_point << "], using 1-based indexing.\n";

  std::cin >> line;
}
Gardener
  • 2,427
  • 1
  • 9
  • 21