getline function

im trying to read from a file into a structure and the names of the items has spaces

i can very easily put underscores between the words and just use >> but i need to learn how to use the getline function

I am aware that using getline is actually a pretty straight forward concept, unfortunately for some reason i just cant get it. (i know it has to do with the "infile>>")

the contents of the dat file are as follows

Big Bowie knife
BK001
39.95
Long Samurai sword
SS001
159.95
Colt 45
CO001
299.95
Magnum 357
MG001
359.95
Super Sniper rifle
SR001
290.95

NOTE: as mentioned before the program work fines with underscores for the spaces


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
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
struct ProductType   
{
       string productName;
       string modelNum;
       float price;
};     

int main()
{
    const int MAXRECS=10;
    ProductType productList [MAXRECS];
    int i;
    
    
    ifstream infile;
    infile.open("products.dat");
    
    for(int i=0;i<MAXRECS;i++)
    {
    
    infile>>productList[i].productName
          >>productList[i].modelNum
          >>productList[i].price;
    }
    
    infile.close();
            
    cout<<"the product for sale are: \n";
    cout<<"\n\n";
    cout<<setiosflags(ios::left);//left jestify the output
    for(i=0;i<MAXRECS;i++)
                          cout<<setw(15)          <<productList[i].productName
                              <<setw(10)         <<productList[i].modelNum
                              <<setw(6)          <<productList[i].price<<endl;

    cout<<'\n';
    system("pause");
    return 0;
} 


If someone, anyone can show me how to modify this code to read the dat file with the white spaces it will be a great help!!
hi mkb84

i use visual C and text files a lot. i usually use a workaround for these spaces. i keep one whole sentence joined by underscores, like you did.

for example, in the text file, i'll have "big_bad_wolf". get this line into a buffer, then change the underscores to spaces. then assign it into desired variable.

1
2
3
4
5
6
7
8
while (...) //while file has not ended
{
    //scan it to a buffer first

    //change all the underscores to space

    //assign buffer to desired variable
}


note that this is definitely not a solution, and is more of a workaround.

hope this helps
I like to use it this way:
1
2
3
4
5
6
7
std::ifstream infile("input.txt"); // Open your text file
std::string line; // It will contain an entire line of text

while( std::getline(infile, line) ) // Get a line, repeat until empty.
{
    // line now contains a line from the file, process as nessesary
}


If you need to extract numbers or something from std::string line, then convert it to a stringstream.
1
2
3
4
5
6
7
8
9
std::ifstream infile("input.txt"); // Open your text file
std::string line; // It will contain an entire line of text

while( std::getline(infile, line) ) // Get a line, repeat until empty.
{
    std::stringstream iss(Line); //iss now contains the line
    float number;
    iss >> number; // If the first line contains a float, we can convert it like this.
}


For your application you may want to do something 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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string> // Required for getline() and for cout << string
#include <vector> // For vectors (duh)
using namespace std;
struct ProductType   
{
       string productName;
       string modelNum;
       float price;
};     

int main()
{
    vector<ProductType> productList; // A vector of items (Size is not limited as in arrays)
    ifstream infile("input.txt"); // Open your text file
    string line; // It will contain an entire line of text
    
    while( getline(infile, line) ) // Get a line, repeat until empty.
    {
        ProductType temp;
        temp.productName = line;
        infile >> temp.modelNum;
        infile >> temp.price;
    
        productList.push_back(temp);
    }
    
    infile.close();
            
    cout<<"the product for sale are: \n";
    cout<<"\n\n";
    cout<<setiosflags(ios::left);//left jestify the output
    for(vector<ProductType>::iterator it = productList.begin(); it != productList.end(); ++it)
                          cout<<setw(15)         << it->productName
                              <<setw(10)         << it->modelNum
                              <<setw(6)          << it->price;

    cout<<'\n';
    system("pause");
    return 0;
}


Here's similar code without vectors (in case you are new to those). I find it a little uglier and less accomodating to variably-size files.
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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string> // Required for getline() and for cout << string
using namespace std;
struct ProductType   
{
       string productName;
       string modelNum;
       float price;
};     

int main()
{
    const int MAXRECS=10;
    ProductType productList[MAXRECS]; // An array of MAXRECS items
    int inventory_size = 0; // Keeps track of the number of items in the 
    
    ifstream infile("input.txt"); // Open your text file
    string line; // It will contain an entire line of text
    
    while( getline(infile, line) ) // Get a line, repeat until empty.
    {
        ProductType temp;
        temp.productName = line; // Big Bowie knife 
        infile >> temp.modelNum; // BK001 
        infile >> temp.price;    // 39.95
    
        productList[ inventory_size++ ] = temp;
    
        if (inventory_size >= MAXRECS) 
            break; // Avoid overflowing the array 
    }
    
    infile.close();
            
    cout<<"the product for sale are: \n";
    cout<<"\n\n";
    cout<<setiosflags(ios::left);//left jestify the output
    for(i=0;i<inventory_size ;i++)
                          cout<<setw(15)          <<productList[i].productName
                              <<setw(10)         <<productList[i].modelNum
                              <<setw(6)          <<productList[i].price<<endl;

    cout<<'\n';
    system("pause");
    return 0;
} 
Last edited on
Actually:
while( getline(infile, line) )
is good if you are checking every line. Since we will probably reach the end of the file after infile >> temp.price instead, it would be better to replace that with the following:

1
2
3
4
while( !infile.eof() )
{
    getline(infile, line);
    //... 
Topic archived. No new replies allowed.