ifstream and getline

Hi!

Why can't I use a getline in a ifstream, if it is a inherited member from istream, according to:

http://www.cplusplus.com/reference/iostream/ifstream/

?

This is my script:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//This program must be inside the folder with the all the energy's folders

{
  char name[20], title[20], file_name[30];
  ifstream read;
  string line;
  Float_t x, y, rms, file=8.0;
  Int_t i, n;
  TProfile *h;
  TObjArray Hlist(0);
  
  //open data files
  for(i=0; i<=6; i++, file+=0.5){
    sprintf(file_name,"%.1fmev/energy-ph-trans.dat",file);
    read.open(file_name);

    if(read.is_open())
      cout << "File ./" << file_name << " is open.\n";
      else
	cout << "Error opening " << file_name << ".\n";
    
    //put stream pointer in the 6th line
    for(n=1; n<=6; n++){
      read.getline (line,100);
    }
    
    //create histogram
    h = new TProfile(name,title,60,5000000,11000000);
    Hlist.Add(h);
    
    //get and write data lines
    while(!read.eof()){
      
      //read data from file
      line.clear();
      read.getline (line,100);
      sscanf(line," %f %f %f ", &x, &y, &rms);
      
      //write name and title of histogram
      sprintf(name,"%.1f", file);
      sprintf(title,"%.1f MeV", file);
      
      //Fill histogram with data from a line
      h->Fill(x,y,rms);
    }
    
    //close the data files
    read.close();
  }

  TFile f("histograms.root","RECREATE","Bremsstrahlung");
  Hlist->Write();
}


This is the output:

File ./8.0mev/energy-ph-trans.dat is open.
Error: Can't call basic_ifstream<char,char_traits<char> >::getline(line,100) in current scope create_histograms.cpp:24:
Possible candidates are...
public: basic_istream<char,char_traits<char> >::__istream_type& basic_istream<char,char_traits<char> >::getline(basic_istream<char,char_traits<char> >::char_type* s,streamsize n,basic_istream<char,char_traits<char> >::char_type delim);
public: basic_istream<char,char_traits<char> >::__istream_type& basic_istream<char,char_traits<char> >::getline(basic_istream<char,char_traits<char> >::char_type* s,streamsize n);
*** Interpreter error recovered ***
*** Interpreter error recovered ***


Last edited on
You are using it wrong. Like this:
 
std::getline(read, line);
(The trick is that they are two totally different functions. The one you want, exampled by Galik, is a global function provided by #including <string>. The member functions of the istream class hierarchy don't understand std::string.)
Ok, it worked! But now the problem is with sscanf...

The new script is like this:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//This program must be inside the folder with the all the energy's folders

{
  char name[20], title[20], file_name[30];
  ifstream read;
  string line;
  float x, y, rms, file=8.0;
  int i, n;
  TProfile *h;
  TObjArray Hlist(0);
  
  //open data files
  for(i=0; i<=6; i++, file+=0.5){
    sprintf(file_name,"%.1fmev/energy-ph-trans.dat",file);
    read.open(file_name);

    //Check if data file is open and reports
    if(read.is_open())
      cout << "File ./" << file_name << " is open.\n";
      else
	cout << "Error opening " << file_name << ".\n";
    
    //put stream pointer in the 6th line
    for(n=1; n<=5; n++){
      std::getline (read,line);
      cout << "Stream pointer currently in line " << n << ".\n";
      cout << "Confirmation: " << line << "\n";
    }
    
    //create histogram
    h = new TProfile(name,title,60,5000000,11000000);
    Hlist.Add(h);
    
    //get and write data lines
    while(!read.eof()){
      
      //read data from file
      std::getline (read,line);
      cout << "Confirmation of data reading: " << line << endl;
      sscanf (line," %f %f %f ", &x, &y, &rms);

      //write name and title of histogram
      sprintf(name,"%.1f", file);
      sprintf(title,"%.1f MeV", file);
      
      //Fill histogram with data from a line
      h->Fill(x,y,rms);
    }
    
    //close the data files
    read.close();
  }

  TFile f("histograms.root","RECREATE","Bremsstrahlung");
  Hlist->Write();
}


The line that it's reading from, that gives this error, has this format:

5.050000E+06 2.437000E-10 1.480961E-11


And the output is:

Error: sscanf parameter mismatch param[0] C u create_histograms.cpp:40:
*** Interpreter error recovered ***
*** Interpreter error recovered ***


The line is read and saved in the string. I have confirmed this because I made a cout after the getline function. The problem is with sscanf. Any ideas?
You could try replacing sscanf (line," %f %f %f ", &x, &y, &rms); with std::istringstream(line) >> x >> y >> rms;.
Last edited on
Also you should replace this:
1
2
3
4
5
6
7

    while(!read.eof()){
      
      //read data from file
      std::getline (read,line);
      cout << "Confirmation of data reading: " << line << endl;
      sscanf (line," %f %f %f ", &x, &y, &rms);

with this:
1
2
3
4
5
6

      //read data from file
    while(std::getline (read,line)){
         
      cout << "Confirmation of data reading: " << line << endl;
      sscanf (line," %f %f %f ", &x, &y, &rms);

The reason being that EOF is not flagged until AFTER the read fails. That means you get one corrupted line each time. By putting the getline() inside the while condition you make sure that the read was a success before performing the while block.
Galik, your answer nÂș1214 saved my life! Thank you!

What does the "std::" means? I've read the tutorial but I don't remember seeing what it means.

One last problem... After all the operations of reading and writing are done, I get this error:

Warning: wrong member access operator '->' _string:55
:

Only problem is, there isn't anything at line 55, like you can see from:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//This program must be inside the folder with the all the energy's folders

{
  char name[20], title[20], file_name[30];
  ifstream read;
  string line;
  float x, y, rms, file=8.0;
  int i, n;
  TProfile *h;
  TObjArray Hlist(0);
  
  //open data files
  for(i=0; i<=6; i++, file+=0.5){
    sprintf(file_name,"%.1fmev/energy-ph-trans.dat",file);
    read.open(file_name);

    //Check if data file is open and reports
    if(read.is_open())
      cout << "File ./" << file_name << " is open.\n";
      else
	cout << "Error opening " << file_name << ".\n";
    
    //put stream pointer in the 6th line
    for(n=1; n<=5; n++){
      std::getline (read,line);
      cout << "Stream pointer currently in line " << n << ".\n";
      cout << "Confirmation: " << line << "\n";
    }
    
    //create histogram
    h = new TProfile(name,title,60,5000000,11000000);
    Hlist.Add(h);
    
    //get and write data lines
    while( std::getline (read,line)){
      
      //read data from file
      std::istringstream(line,ios_base::in) >> x >> y >> rms;
      printf("Confirmation of data reading: x=%.2E; y=%.2E; rms=%.2E\n", x, y, rms);
      /*      cout << "; y=" << y;
	      cout << "; rms=" << rms << ".\n";*/
      
      //write name and title of histogram
      sprintf(name,"%.1f", file);
      sprintf(title,"%.1f MeV", file);
      
      //Fill histogram with data from a line
      h->Fill(x,y,rms);
      line.clear();
    }
    
    //close the data files
    read.close();
  }
  
  TFile f("histograms.root","RECREATE","Bremsstrahlung");
  Hlist->Write();
}


Any idea of what this may be?
tirwit wrote:
What does the "std::" means?

That is the namespace qualifier. Everything you #include from the standard library is in the std namespace. So you need to prepend std:: in front of any standard symbols that you wish to use.
Also line 57 should probably be Hlist.Write(); as Hlist is not a pointer.
Topic archived. No new replies allowed.