Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 2 12 LastLast
Results 1 to 15 of 21
  1. #1
    New Coder
    Join Date
    Mar 2005
    Posts
    26
    Thanks
    0
    Thanked 0 Times in 0 Posts

    C++: Ignoring spaces when reading a file?

    All,

    I have delclared a struct, and a vector with that structs type.
    As my program reads the file the vector's size is increased by one, and the information which is supposed to be separated by tabs is put into the attributes(?) of the struct:

    Code:
    while(!inFile.eof()){
                                          
                         areas.resize(areas.size()+1);
                         inFile>>areas[i].mc;
                         inFile>>areas[i].st;
                         inFile>>areas[i].ad;
                         inFile>>areas[i].lp;
                         inFile>>areas[i].cp;
                         inFile>>areas[i].cd;
                         inFile>>areas[i].sb;
                         inFile>>areas[i].dm;
                         inFile>>areas[i].tp;
                         inFile>>areas[i].yb;
                         inFile>>areas[i].sz;
                         inFile>>areas[i].br;
                         inFile>>areas[i].fb;
                         inFile>>areas[i].hb;
                         
                     }
    The problem is that some of the data includes spaces and therefore treated as a separate element. My question: Is there anyway to ignore spaces and only read the file by tabs (\t)?

    Any help would be greatly appreciated,
    Mario

  • #2
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    You may find getline() to work better for you than >> since it accepts a delimiter argument.

    Or, you could overload operator>> for the type of your records, in which case the code you posted should start working like you'd like. Here's a simple example assuming string records:

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <sstream>
    
    std::istream& operator>>(std::istream& in, std::string& str)
    {
    	char ch;
    	std::stringstream ss;
    
    	while (in)
    	{
    		in.get(ch);
    		// Return a record at the delimiter
    		if (ch == '\t')
    		{
    			str = ss.str();
    			return in;
    		}
    		// Accumulate chars
    		ss << ch;
    	}
    	
    	// Ran out of stream, this record may be incomplete
    	str = ss.str();
    	return in;
    }
    
    int main(int argc, char* argv[])
    {
    	if (argc != 2)
    	{
    		std::cout << argv[0] << " <filename>" << std::endl;
    		return 0;
    	}
    
    	std::ifstream ifh(argv[1]);
    	if (!ifh.good())
    	{
    		std::cerr << "Couldn't open " << argv[1] << " for reading." << std::endl;
    		return 1;
    	}
    
    	std::string str;
    	while (ifh)
    	{
    		ifh >> str;
    		std::cout << str << std::endl;
    	}
    
    	return 0;
    }

  • #3
    New Coder
    Join Date
    Mar 2005
    Posts
    26
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Hey, thanks for the reply,

    If I can figure it out I think I'll use getline(), I don't want to change >> because I'm also collecting data from the user. The thing I can't figure out is how to get the getline() to work.

    Code:
    string s;
    while(getline(inFile, s)){
    //store lines of txt file here
    }
    But then how do I separate it into a struct based on tabs? (the tab character, \t)

    -Thanks for help

  • #4
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    use the three argument form: getline(source, dest, '\t')

    (I don't know why I didn't use that instead of the character loop in the post above, especially since I mentioned it in the post )

  • #5
    New Coder
    Join Date
    Mar 2005
    Posts
    26
    Thanks
    0
    Thanked 0 Times in 0 Posts
    OK,

    The problem is that each line in the text file is a record, and each record within the record is separated by a tab. So basically I need to read the file line by line and then separate each record out by tabs.

    The default third parameter of getline() is defaulted to newline unless changed, in this case a tab. So there is a problem because the data needs to first be separated by \n then \t ignoring the spaces ' '.

    I'm sorry but I guess my original post was confusing and this was probably how I should have asked in the first place.

    Additional help greatly appreciated,
    -Mario

  • #6
    New Coder
    Join Date
    Mar 2005
    Posts
    26
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Again... OK,

    I've been working on this using getline():

    Code:
    #include<iostream>
    #include<fstream>
    #include<vector>
    #include<stdlib.h>
    #include<string>
    using namespace std;
    
    struct tests {
           
           string one;
           string two;
           string three;
           
    };
    
    int main() {
        
        ifstream inFile("test.txt");
        vector<string> lines(0);
        
        string s;
        int i = 0;
        
        // Separate by newline.
        while(getline(inFile, s)){
                              
             lines.resize(lines.size()+1);
             lines[i] = s;
             i++;
             
        }
        
        // Divide into tabs.
        vector<tests> test(lines.size());
        
        for(int j=0; j<test.size(); j++){
             
             string temp = "";
             
             bool oneset = false;
             bool twoset = false;
             bool threeset = false;
             
             for(int x=0; x<lines[j].size(); x++){
             
                  if(oneset == false){
                     
                       if(lines[j][x] == '\t'){
                                 
                            test[j].one = temp;
                            oneset = true;
                       
                       } else {
                         
                            temp += lines[j][x];
                       
                       }
                       
                  } else if(oneset == true && twoset == false){
                         
                       if(lines[j][x] == '\t'){
                                 
                            test[j].two = temp;
                            twoset = true;
                       
                       } else {
                         
                            temp += lines[j][x];
                       
                       }
                       
                  } else if(oneset == true && twoset == true && threeset == false){
                         
                       if(lines[j][x] == '\t'){
                                 
                            test[j].two = temp;
                            threeset = true;
                       
                       } else {
                         
                            temp += lines[j][x];
                       
                       }
                       
                  }
                  
             }
             
        }
        
        // Reasign null values.
        for(int q = 0; q<test.size(); q++){
        
             if(test[q].one == ""){
                  
                  test[q].one == "_";
                  
             }
             
             if(test[q].two == ""){
                  
                  test[q].two == "_";
                  
             }
             
             if(test[q].three == ""){
                  
                  test[q].three == "_";
                  
             }
             
        }
        
        // Output the data.
        for(int p = 0; p<test.size(); p++){
                
             cout<<"Data "<<p<<": One: "<<test[p].one<<" Two: "<<test[p].two<<" Three: "<<test[p].three<<endl;
             
        }
        
        // Add a pause so the prompt doesn't close.
        int w;
        cin>>w;
        
        return(0);
        
    }
    It still doesn't work and I can't figure it out. For some reason I can't select and copy the output so I took a screenshot.

    C++: Ignoring spaces when reading a file?-example1.gif

    The text file looks like this:

    Code:
    row 1 col 1		row 1 col 3
    	row 2 col 2	row 2 col 3
    row 3 col 1	row 3 col 1
    And here is the same but with a '|' after each tab.

    Code:
    row 1 col 1	|	|row 1 col 3
    	|row 2 col 2	|row 2 col 3
    row 3 col 1	|row 3 col 1	|
    The over all problem seems to be... well I can't even figure out whats going wrong.

    Appreciatively,
    -Mario

  • #7
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    Give this a shot

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    
    typedef std::vector<std::string> Columns;
    
    Columns split_record(const std::string& record)
    {
    	Columns rv;
    	std::string::size_type last_pos = 0;
    
    	for (
    		std::string::size_type pos = record.find_first_of('\t'); 
    		pos != record.npos; 
    		pos = record.find_first_of('\t', last_pos))
    	{
    		// I'm not sure if the "_" for blank columns is just for debug or
    		// not, if so you can remove the ternary and just push the substr
    		rv.push_back(
    			(pos - last_pos == 0) 
    				? "_" 
    				: record.substr(last_pos, pos - last_pos)
    		);
    		last_pos = pos + 1;
    	}
    
    	rv.push_back(
    		(record.length() - last_pos == 0) 
    			? "_"
    			: record.substr(last_pos, record.length() - last_pos)
    	);
    	return rv;
    }
    
    int main(int argc, char* argv[])
    {
    	if (argc != 2)
    	{
    		std::cout << argv[0] << " <filename>" << std::endl;
    		return 0;
    	}
    
    	std::ifstream ifh(argv[1]);
    	if (!ifh.good())
    	{
    		std::cerr << "Couldn't open " << argv[1] << " for reading." << std::endl;
    		return 1;
    	}
    
    	int rec_num, col_num = 0;
    	std::string str;
    	Columns cols;
    	while (getline(ifh, str))
    	{
    		std::cout << "Record " << ++rec_num << ": " << std::endl;
    		std::cout << str << std::endl;
    		std::cout << "\tColumns: " << std::endl;
    		cols = split_record(str);
    		col_num = 0;
    		for (Columns::const_iterator ci = cols.begin(); ci != cols.end(); ++ci)
    		{
    			std::cout << "\t\t" << ++col_num << ": " << *ci << std::endl;
    		}
    	}
    
    	return 0;
    }

  • #8
    New Coder
    Join Date
    Mar 2005
    Posts
    26
    Thanks
    0
    Thanked 0 Times in 0 Posts
    OK, so I tried this and it compiles without errors, but then when it runs the prompt closes before I can see anything. Any ideas?

    I tried to put this at the end:

    Code:
    	int pause;
    	std::cin>>pause;
    But still no luck.

    Thanks,
    Mario

  • #9
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    I don't know, it pauses for me when I add that before return 0;

    You might consider just opening a command prompt and running it from there, where it won't close afterwards regardless.

    edit: it probably closes because you didn't provide a filename or it couldn't open the file. Am I doing homework here? Seemed legit to begin with :[
    Last edited by ralph l mayo; 06-27-2007 at 08:55 PM.

  • #10
    Gox
    Gox is offline
    Regular Coder Gox's Avatar
    Join Date
    May 2006
    Location
    Ontario, Canada
    Posts
    392
    Thanks
    2
    Thanked 20 Times in 20 Posts
    If you're using Dev C++ try putting a system("PAUSE") in your main. This may help to keep the console window open.

    Code:
    int main()
    {
    //code
    
    system("PAUSE");
    return 0;
    }

  • #11
    New Coder
    Join Date
    Mar 2005
    Posts
    26
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by ralph l mayo View Post
    I don't know, it pauses for me when I add that before return 0;

    You might consider just opening a command prompt and running it from there, where it won't close afterwards regardless.

    edit: it probably closes because you didn't provide a filename or it couldn't open the file. Am I doing homework here? Seemed legit to begin with :[
    No homework, school ended weeks ago...

  • #12
    New Coder
    Join Date
    Mar 2005
    Posts
    26
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Gox View Post
    If you're using Dev C++ try putting a system("PAUSE") in your main. This may help to keep the console window open.

    Code:
    int main()
    {
    //code
    
    system("PAUSE");
    return 0;
    }
    I am using Dev C++ and I added system("PAUSE") but still no luck.

  • #13
    New Coder
    Join Date
    Mar 2005
    Posts
    26
    Thanks
    0
    Thanked 0 Times in 0 Posts
    OK, I tried to output the results to a file but when I use the ofstream object but my compiler complained: "`ofstream' undeclared (first use this function) ". I checked and fstream is included so I don't know whats wrong.

  • #14
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    Code:
    std::ofstream

  • #15
    New Coder
    Join Date
    Mar 2005
    Posts
    26
    Thanks
    0
    Thanked 0 Times in 0 Posts
    That compiled, but the text file is empty...

    I simply changed std::cout to outFile (which is my ofstream object)

    Code:
    while (getline(ifh, str))
    	{
    		outFile << "Record " << ++rec_num << ": " << std::endl;
    		outFile << str << std::endl;
    		outFile << "\tColumns: " << std::endl;
    		cols = split_record(str);
    		col_num = 0;
    		for (Columns::const_iterator ci = cols.begin(); ci != cols.end(); ++ci)
    		{
    			outFile << "\t\t" << ++col_num << ": " << *ci << std::endl;
    		}
    	}
    I've been doing a lot of research and something which may be easier is to instead of trying to split up the information straight from the read file would be to store all of the information then split it up by tabs from there?

    -Mario


  •  
    Page 1 of 2 12 LastLast

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •