Thread: Vector Question

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    19

    Vector Question

    I'm working on a program, and what I'm trying to do is have the TempVec assigned to a multidimensional vector, but that's where I get stuck.

    Basically, the TempVec is read in from a line from a .txt file. All the spaces are removed, and then each line from the .txt file is supposed to be added to a row of the multidem vector.

    There's a header file and a driver file, but those don't matter.

    Code:
    vector<string>TempVec;
    
    	ifstream InStream;
    
    	InStream.open( FileName.c_str(), ios::in );
    
    	int pos = 0;
        string str, word;
    
    	if(!InStream.fail())
    	{
    
    	 while(!InStream.eof())
          {
    		getline(InStream, str);
                 
    		string::size_type pos = str.find(" ");
    		string::size_type pos2 = 0;
    
    		while (pos != string::npos) 
    		{
    			word = str.substr(pos2, pos - pos2);
    			if(word != "")
    			cout << word << " ";
    			TempVec.push_back(word);
    			
    			
    		  	pos2 = pos + 1;
    			pos = str.find(" ", pos2);			 
    			//pos2 = str.find_first_of("\n", pos2 + 1);
    		}
    		cout << str.substr(pos2, str.size()-pos2) << endl;
          }
    	}
    	else{
    		cerr << "Unable to read from " << FileName << endl;
    	}
    	InStream.close();
    Thanks for your input; I have not been able to think up a solution.

  2. #2
    User
    Join Date
    Jan 2006
    Location
    Canada
    Posts
    499
    Just a suggestion, don't you think it would be easier to use a stringstream to split up the words rather than to use string::find and string::substr?

    Regarding the 2-dimensional vector, it's quite easy:
    Code:
    vector<vector<string>> TempVc;
    Now just make another vector which you place all the words in one line into. Push this vector onto TempVc.

  3. #3
    Registered User
    Join Date
    Apr 2005
    Posts
    19
    Quote Originally Posted by joeprogrammer View Post
    Now just make another vector which you place all the words in one line into. Push this vector onto TempVc.
    That's what I was wondering how to do.

  4. #4
    Registered User
    Join Date
    May 2006
    Posts
    903
    Code:
    std::vector< std::vector<std::string> > TempVc;
    int line_no = 1;
    
    do
    {
      TempVc.push_back(std::vector<std::string>()); // wild guess
    
      std::string tmp_word;
      std::stringstream ss;
      std::getline(InStream, ss);
    
      while(ss &#173;>> tmp_word) // this is just a guess though
      {
        TempVc[line_no - 1].push_back(tmp_word);
      }
      line_no++;
    } while(!InStream.eof());
    Disclaimer: I didn't fully understand what you wanted to do and I haven't compiled this code either so it might not be what you are looking for or it might contain mistakes.

    Edit: Thinking about it, you will need to use the resize() (or reserve() ?) function in order to allocate memory or find some other way (which I added in the code).
    Last edited by Desolation; 04-22-2007 at 06:56 PM. Reason: Moved line_no out of first while loop.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> // wild guess
    Looks correct. There are some other small errors in there, but I'll leave it to Kramer55 to figure those out. The basic idea is correct.

    >> you will need to use the resize() (or reserve() ?)
    No, you use push_back, which is enough.

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    903
    I'm sorry, I should have pointed out that the "or find some other way" part was that push_back() idea.

  7. #7
    Registered User
    Join Date
    Apr 2005
    Posts
    19
    I've changed my code a bit, and now I'm trying to get pass some info onto another part of my header file.

    Code:
    MatchingTile::MatchingTile(string FileName)
    {
    		
    	ifstream InStream;
    
    	InStream.open(FileName.c_str(), ios::in);
    
    	if(!InStream.fail())
    		{
    		for(unsigned int r = 0 ;!InStream.eof() ;++r, InStream.get())
    			{
    		MyGrid.resize( MyGrid.size() + 1 ); //Resize the grid, adding a new row.
    	   for(unsigned int c = 0; InStream.peek() != '\n' && !InStream.eof(); ++c)
    	   {
    		  string Word;
    		  InStream >> Word;
    
    		  (MyGrid[ r ]).push_back( Word ); //Add the word to the end of this row.
    	   }
    	}
    
    	for(unsigned int r = 0; r < MyGrid.size(); ++r)//Loop through every row
    	{
    	   for(unsigned int c = 0; c < (MyGrid[ r ]).size(); ++c) //Loop through every word in the row.
    	   {
    		  cout << (MyGrid[ r ])[ c ] << " "; //Print the word.
    		}
    	   cout << endl;//After each row has been printed, skip to the next line.
               // MyGrid.at(i).size() is the value I need from this part for the # of rows
    	} 
    	//MyGrid.size() to get the number of columns
    }
    	else{
    	cerr << "Unable to read from: " << FileName << endl;
    	}
    }
    What I'm trying to get is the size of the vector MyGrid so that I can use it for other class functions.

    I can get the different sizes by having MyGrid.at(r).size() after each line is printed out (the rows), and I can
    get the number of colums by having MyGrid.size()

    How can I make it so that I can have those values and reference them in the header file?
    Will a simple function returned by value work? I tried that, but the way I did it, it would not work for me.

    Thanks.

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Adding functions like getNumColumns() and getNumRows() or whatever that return unsigned ints should be fine. What kind of problems were you having?

  9. #9
    Registered User
    Join Date
    Apr 2005
    Posts
    19
    In my header file, I have:

    unsigned int getRows(unsigned int r);

    unsigned int getColumns(unsigned int c);

    And in the code after the vector is displayed, I have:

    Code:
    for(unsigned int r = 0; r < MyGrid.size(); ++r)//Loop through every row
    	{
    	   for(unsigned int c = 0; c < (MyGrid[ r ]).size(); ++c) //Loop through every word in the row.
    	   {
    		  cout << (MyGrid[ r ])[ c ] << " "; //Print the word.
    		}
    	   cout << endl;//After each row has been printed, skip to the next line.
    	   getRows(MyGrid.at(r).size());
    	}
    And:
    Code:
    unsigned int class Name::getRows(unsigned int r){
    return r
    }
    And something similar for the getColumns, but those aren't working (although it makes sense, I just can't do any more thinking). I'm not sure how to use the function so that I can get the value and use it in other member functions.

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Why are you calling getRows in the constructor? There is no need to call it there, right? Just have other code call getRows (or getColumns) when it needs to know how many rows or how many columns.

    The MyGrid variable is a member of the class, right? So it will be available to member functions like getRows to use.

  11. #11
    Registered User
    Join Date
    Apr 2005
    Posts
    19
    Ok, so I have the getColumn function working.

    Now, I'm trying to use that to print out a board through the main() function, but I get 2 errors.

    In my header file, I have:
    Code:
    void PrintBoard();
    In the .cpp file associated with the header file, I have:
    Code:
    void class name :: PrintBoard(){
    ...
    }
    Then, in the main function, I created an instance of my class and called it Board.

    Then, I tried Board.PrintBoard, but I received:
    Code:
    unresolved external symbol "public: __thiscall MatchingTile::MatchingTile(void)" (??0MatchingTile@@QAE@XZ) referenced in function _main
    And
    fatal error LNK1120: 1 unresolved externals
    What do those mean? I thought I did everything correctly.

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Did you include the MatchingTile.cpp file in your project/makefile/command line? Usually that's what the unresolved external symbol means, the compiler cannot link to the source file that has that function definition.

    Another possibility is that you just didn't implement the constructor with no arguments. I notice in the code earlier in this thread your constructor for MatchingTile takes a string parameter, but the error is looking for a constructor with no parameters. Either you meant to send a string filename to the constructor in main, or you forgot to implement the constructor that doesn't take any parameters.

Popular pages Recent additions subscribe to a feed