0

I have a text file with 4 rows and 3 columns

(0.165334,0) (0.166524,-0.0136064) (-0.144899,0.0207161)
(0.205171,0) (0.205084,-0.0139042) (-0.205263,0.0262445)
(0.216684,0) (0.215388,-0.0131107) (-0.193696,0.0251303)
(0.220137,0) (0.218849,-0.0135667) (-0.194153,0.025175)

I wrote following code to print the values of FFTfile. The script does not throw any errorm but it does not print the values. Any idea whats wrong?

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <algorithm>
#include <dirent.h>
#include <string>
#include <sstream>
using namespace std;

class Point
{
public:
  double x;

  double y;

  friend istream& operator>>(istream& input, Point& p);
  friend ostream& operator<<(istream& s, Point& p);

  double getX(void);

  double getY(void);


};

  double Point::getX(void){
      return x;
      }

  double Point::getY(void){
      return y;
      }

istream& operator>>(istream& input, Point& p)
{
  char c;
  input >> c; // Read open parenthesis
  input >> p.x;
  input >> c; // Read comma
  input >> p.y;
  input >> c; // Read closing parenthesis

  return input;
};

ostream& operator<<( ostream& s, Point& p)
{
    s << p.getX() << ", " << p.getY();
    return s;
} 

vector<vector<Point> > LoadFFT(string path){
    string Filename;   
    vector<vector<Point> > matrix;  
    Filename.append(path);                                                                  
    Filename.append("....txt"); 
    ifstream fileFFT(Filename.c_str());
    string raw_text;
    while(getline(fileFFT, raw_text)){

        vector<Point> row;
        istringstream(raw_text);
        Point p;
        while( raw_text >> p ){
            row.push_back(p);

        }

    matrix.push_back(row);
    }

return(matrix);
}

int main(){
    vector<vector<Point> > FFTfile=LoadFFT("...");

    for (int i = 0; i < FFTfile.size(); i++)
    {
        for (int j = 0; j < FFTfile[i].size(); j++){
            cout << FFTfile[i][j];
        }

    }

    return(0);
}
AndyG
  • 39,700
  • 8
  • 109
  • 143
Spandyie
  • 914
  • 2
  • 11
  • 23
  • you never test if the opening of a file succeeded. How can you be sure that the file was actually opened? – Fureeish Aug 31 '17 at 22:07
  • I am just a noob man !! with less than a month in C/C++experience, can you be of some help ? – Spandyie Aug 31 '17 at 22:16
  • your lack of experience does not entitle you to be treated differently. I suggested checking if the file opening succeeded. Have you tried checking if your program works with it? – Fureeish Aug 31 '17 at 22:20
  • 1
    **Start with something small and simple that works perfectly, then build up.** Have you tried writing a program that reads *one* number? – Beta Aug 31 '17 at 22:20
  • 1
    FWIW: It's a good time to start leaning which includes you need and which you don't. In this example you need fewer than half of those. – AndyG Aug 31 '17 at 22:26

3 Answers3

2

If the file opened successfully, one issue seems to be the following set of lines:

    istringstream(raw_text);
    Point p;
    while( raw_text >> p )

You have not created a std::istringstream object at the point where you are issuing the >> call. Instead a temporary object was created and immediately destroyed.

This should be:

    istringstream strm(raw_text);
    Point p;
    while( strm >> p )

Having said this, I'm surprised the code compiled with no errors.

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • With you on the surprise. Still trying to figure that one out. It looks like `istringstream(raw_text);` is sort-of being seen as a `istringstream raw_text;` and allowing compilation. Example: https://godbolt.org/g/CTcWw6 Why, I'll leave to folk who grok the nitty gritty of the language better than I do. – user4581301 Aug 31 '17 at 22:34
  • Strange, as here is the OP's code (with some changes), [compiled successully](https://godbolt.org/g/kXWsvb). – PaulMcKenzie Aug 31 '17 at 22:40
  • @bezet waiting to see if someone who does grasp what's going on drops by here. Paul, I'm pretty sure it's the deeper scope that allows it to compile. No collision with `voop` here: https://godbolt.org/g/3ye3Ti . – user4581301 Aug 31 '17 at 22:44
  • Yes. It's definitely the scope that allows it to compile, still `istringstream(raw_text)` being a valid(and non temporary variable) is confusing. I asked about it [here](https://stackoverflow.com/questions/45991094/which-part-of-the-c-standard-allow-to-declare-variable-in-parenthesis). – bezet Aug 31 '17 at 22:48
  • @user4581301 I think it's a redefinition of a `raw_text` variable. – Ron Aug 31 '17 at 23:00
  • @Ron It is. No doubt about it. Took a while, but I finally got it. `istringstream(raw_text)` is `istringstream raw_text;`, but not `istringstream raw_text(previous_incarnation_of_raw_text);`, so it's an empty `istringstream` and all the `input >> blah`s fail unchecked with EOF. A cautionary tail about why one should always check your input. – user4581301 Aug 31 '17 at 23:12
  • 1
    @user4581301 or the advantages of compiling with `-Wshadow` – M.M Sep 01 '17 at 00:20
  • Yep, I see it now. I had a sense that it had to do with variables being shadowed, but didn't identify it by sight. – PaulMcKenzie Sep 01 '17 at 01:40
1

You don't load a file. Your call to: LoadFFT("...") functions results in a file name of: .......txt which is not a valid file name. The stringstream variable (re)definition is wrong, intermediary strings are not needed, nor their c_str() counterparts. The distilled LoadFFT() function is:

vector<vector<Point>> LoadFFT(const char* path){
    vector<vector<Point> > matrix;
    ifstream fileFFT(path);
    string raw_text;
    while (getline(fileFFT, raw_text)){
        vector<Point> row;
        istringstream iss(raw_text);
        Point p;
        while (iss >> p){
            row.push_back(p);
        }
        matrix.push_back(row);
    }
    return(matrix);
}

The modified main() function to allow for the new line after each row:

int main(){
    vector<vector<Point> > FFTfile = LoadFFT("myfile.txt");
    for (size_t i = 0; i < FFTfile.size(); i++){
        for (size_t j = 0; j < FFTfile[i].size(); j++){
            cout << FFTfile[i][j];
        }
        cout << std::endl;
    }
}

These headers you need:

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

You can remove the others.

Ron
  • 14,674
  • 4
  • 34
  • 47
1

you're using raw_text (string) as as input parameter of type istream. I don't think such conversion is possible. try using istringstream return value as the parameter for "<<" or change your code so that you copy from the file directly to your matrix.

edit: comments above have done better job explaining it

sicarii443
  • 51
  • 5