开发者

C++ rookie (streams)... How to read strings from file where the string has a space (e.g., Tom Smith)? Trouble using getline instead of >>

I wrote a template function for reading in string or numerical data from files and saving the data in vectors of either strings or ints/doubles. I then use the data to perform calculations with another code I wrote.

Advance apologies, because I think this is a simple question... I can't read in string data where there is a whitespace... For example, a first and last name. When I want "Tom Smith," I only get "Tom"). From googling, it seems that the problem is >> and that I should use getline instead. I have tried replacing >> with getline(test,100), but I'm getting a "no matching function for call to std::basic_istringstream..." type error ( error: no matching function for call to ‘std::basic_ifstream >::getline(double&)’)

I would be very grateful if someone could put me right! I just can't seem to get my head around streams!

This is some example data and my code. I configured it for strings here.

labelInFile // Identifier for subset of data for one vector

'Tom Smith' 'Jackie Brown' 'John Doe' // These names should end up as elements in a vector

#include <algorithm>  
#include <cctype>     
#include <istream>
#include <fstream>
#include <iostream>    
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

using namespace std; 

template<typename T>  
void fileRead( std::vector<T>& results, const std::string& theFile, const std::string& findMe, T& test )  
{   
    std::ifstream file( theFile.c_str() ); 
    std::string   line;

    while( std::getline( file, line ) )
    {
        if( line == findMe )
        {
            do{
                std::getline( file, line, '\'' );  
                std::getline( file, line, '\'');

                std::istringstream myStream( line );

                myStream >> test;
                results.push_back( test );
            } 
            while ( file.get() != '\n' );
        }
    }
}


int main () 
{
    const std::string theFile               = "test.txt";  // Path to file
    const std::string findMe                = "labelInFile"; 
    std::string test;

    std::vector<string> results;

    fileRead&开发者_运维知识库lt;std::string>( results, theFile, findMe, test );

    cout << "Result: \n";
    std::copy(results.begin(), results.end(), std::ostream_iterator<string>(std::cout, "\n")); 

    return 0;
}


I've written some code to solve part of your problem: parsing the names. You can adapt it to your needs. Note: this is not the fastest way to solve this, but it is a simple way that is hopefully easy to understand.

Test.cpp

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

int main()
{
    const char szFname[] = "Test.dat";
    std::vector<std::string> vData;

    std::ifstream ifstr(szFname);

    while (ifstr.good())
    {
        // find first quote
        ifstr.ignore(0xffff, '\'');
        std::string sData;
        char ch;
        while (ifstr.good() && ('\'' != (ch=ifstr.get())))
            sData += ch;
        if (!sData.empty())
            vData.push_back(sData);
    }
    for (size_t i=0; i<vData.size(); ++i)
        std::cout << vData[i] << std::endl;

    return 0;
}

Test.dat

'Tom Smith' 'Jackie Brown' 'John Doe' 
'Robert Burns'   'James Joyce''Joseph Conrad' 'Dylan Thomas'
'Edgar Allan Poe' 'V.S. Naipaul' 'Vladimir Nabokov'
'William Shakespeare'  'William Langland' 'Robert Greene'

Results

Tom Smith
Jackie Brown
John Doe
Robert Burns
James Joyce
Joseph Conrad
Dylan Thomas
Edgar Allan Poe
V.S. Naipaul
Vladimir Nabokov
William Shakespeare
William Langland
Robert Greene


The following is the extract of fileRead. I changed only line (1). With this change, as far as I see, your code seems to work as you expect.

do{
  ....
  std::istringstream myStream( line );

  while ( myStream >> test ) // (1)
    results.push_back( test );
} 
while ( file.get() != '\n' )

Hope this helps

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜