CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14

Hybrid View

  1. #1
    Join Date
    Nov 2011
    Posts
    3

    Exclamation Reading a text file into a vector

    I have an assignment where I have to write a program to prompt the user for a file name and location (it is a text file), once the user has entered that, a menu pops up and gives the user 4 options and asks which one they would like to do. Option 1 is to display all the names in the text file (there are 3 names, which have a first and last name with a space in between). The second option is to add a name to the file, the third option is to delete a name from the file and the fourth option is to exit and save the program, saving whatever names were added to or deleted from the file.

    Now I have written out the code for the program, using 6 functions (including int main) the other five functions are: the read file into vector function, the display all names function, the add a name function, the delete a name function and finally the exit and save program function.

    I seem to be having a problem with reading the names from the file into the vector, I am not exactly sure why either, seeing as I have followed how the teacher did it in class.

    I will start by posting the readFile function and see if you guys can give me any help on it, I am desperate! I will take any help I can get, thank you!

    void readFile(string strFile, vector<string> vecNames, ifstream &iFile) //Read the file into the vector function definition
    {
    string strFName, strLName; //First and last name

    iFile.open(strFile.c_str()); //Opens file

    while (iFile >> strFName >> strLName) //While the file is copying into the first and last names
    {

    vecNames.push_back(strFName + " " + strLName); //Push the names onto the back of the of the vector
    }

    iFile.close(); //Close the input file
    }

  2. #2
    Join Date
    Nov 2011
    Posts
    3

    Re: Reading a text file into a vector

    Here is the rest of my code for reference:

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

    using namespace std;

    void readFile(string, vector<string>, ifstream &); //Function prototype for the reading the file function
    void displayNames(vector<string>); //Function prototype for the displaying the names function
    void addName(string, ofstream &, vector<string>); //Funtion protoype for the adding a name to the list function
    void deleteName(string, ofstream &, vector<string>); //Function prototype for the deleting a name from the list function
    void quitProgram(); //Funtion prototype for the exiting function

    int main()
    {
    char cInput; //Menu input
    ifstream inFile; //Input file
    ofstream outFile; //Outut file
    string strFileName; //File name
    vector<string> vecStudent; //Vector holding student names

    cout << "Please enter the data file name (with location): "; //Asks the user for a file location and the name of file
    cin >> strFileName; //User enters the file location and name

    while (inFile.fail()) //While the file does not open display error message and asks for another file name and location
    {
    cout << "--------------------------------------------------\n";
    cout << "Input file error!\n";
    cout << "Please enter the data file name (with location): ";
    cin >> strFileName;
    }

    readFile(strFileName, vecStudent, inFile); //Calls readFile function to read the file into the vector

    while (true)
    {
    cout << "----------------------------------------\n";
    cout << " Grade Report Program - Main Menu\n";
    cout << "----------------------------------------\n";
    cout << " Enter 1 to display ALL students names\n";
    cout << " Enter 2 to add a student name\n";
    cout << " Enter 3 to delete a student name\n";
    cout << " Enter 4 to SAVE and quit the program\n";
    cout << "----------------------------------------\n";
    cout << "Enter menu option: "; //Asks user for menu option
    cin >> cInput; //User inputs menu option

    switch (cInput)
    {
    case '1':
    displayNames(vecStudent); //call a function to handle this option
    break;
    case '2':
    addName(strFileName, outFile, vecStudent); //call a function to handle this option
    break;
    case '3':
    deleteName(strFileName, outFile, vecStudent);//call a function to handle this option
    break;
    case '4':
    quitProgram();//call a function to handle this option
    return 0;
    default:
    cout << "invalid input" << endl;
    break;
    }
    }
    return 0; //Return 0 to exit program
    }

    void readFile(string strFile, vector<string> vecNames, ifstream &iFile) //Read the file into the vector function definition
    {
    string strFName, strLName; //First and last name

    iFile.open(strFile.c_str()); //Opens file

    while (iFile >> strFName >> strLName) //While the file is copying into the first and last names
    {

    vecNames.push_back(strFName + " " + strLName); //Push the names onto the back of the of the vector
    }

    iFile.close(); //Close the input file
    }

    void displayNames(vector<string> vecNames) //Display the names funtion definition
    {
    cout << "--------------------------------------------------\n";
    cout << "Display all student names...\n";

    for (int i = 0; i < vecNames.size(); i++)
    cout << vecNames[i] << endl; //Displays the names from the vector

    cout << "---- A total of " << vecNames.size() << " names ----\n";
    }

    void addName(string strFile, ofstream &oFile, vector<string> vecNames) //Add the name function definition
    {
    string strFName; //First name
    string strLName; //Last name

    oFile.open(strFile.c_str()); //Opens the output file

    while (oFile.fail()) //While the output file does not open display error message and prompt user again for a first and last name
    {
    cout << "----------------------------------------\n";
    cout << "Output file error!\n";
    cout << "Enter the name to be added <First and Last Name>: ";
    cin >> strFName >> strLName;

    oFile.open(strFile.c_str()); //Tries to open file again
    }

    cout << "----------------------------------------\n";
    cout << "Enter the name to be added <First and Last Name>: "; //Asks user for the first and last name to be added
    cin >> strFName >> strLName; //User enters first and last name to be added

    vecNames.push_back(strFName+" "+strLName); //Adds the name entered into the vector

    for (int i = 0; i < vecNames.size(); i++)
    oFile << vecNames[i] << endl; //Put the names from the vector into the output file

    oFile.close(); //Closes the output file

    cout << "---- Name '" << strFName << " " << strLName << "' has been added.\n"; //Displays that the name has been added
    }

    void deleteName(string strFile, ofstream &oFile, vector<string> vecNames) //Delete the name funtion definition
    {
    string strFName; //Initialize first name variable
    string strLName; //Initialize last name variable

    cout << "----------------------------------------\n";
    cout << "Enter the name to be deleted <First and Last Name>: "; //Ask use what name they want to delete
    cin >> strFName >> strLName;

    vecNames.pop_back(); //Take that name off of the vector

    oFile.open(strFile.c_str()); //Open the output file

    while (oFile.fail()) //While the output while does not open display and error message and ask the user again
    {
    cout << "----------------------------------------\n";
    cout << "Output file error!\n";
    cout << "Enter the name to be deleted <First and Last Name>: ";
    cin >> strFName >> strLName;

    oFile.open(strFile.c_str());
    }

    for (int i = 0; i < vecNames.size(); i++)
    oFile << vecNames[i] << endl; //Put the names from the vector into the output file

    oFile.close(); //Close the output file

    cout << "---- Name '" << strFName << " " << strLName << "' has been deleted.\n";
    }

    void quitProgram() //Quitting the program function definition
    {
    cout << "--------------------------------------------------\n";
    cout << "Thanks for using the program. Program terminated.\n"; //Displays that the program has terminated
    }

  3. #3
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Reading a text file into a vector

    Quote Originally Posted by lolwut25 View Post
    ...
    I seem to be having a problem with reading the names from the file into the vector, I am not exactly sure why either, seeing as I have followed how the teacher did it in class...
    Code:
    void readFile(string strFile, vector<string> vecNames, ifstream &iFile) //Read the file into the vector function definition
    {
    	string strFName, strLName; //First and last name
    
    	iFile.open(strFile.c_str()); //Opens file
    
    	while (iFile >> strFName >> strLName) //While the file is copying into the first and last names 
    	{
    		
    		vecNames.push_back(strFName + " " + strLName); //Push the names onto the back of the of the vector
    	}
    
    	iFile.close(); //Close the input file
    }
    Your very serious mistake is you are passing the vector<string> vecNames by value, that means a copy of the vector is created within a function... but after function returns this copy is destroyed and all the read data gets lost!
    You have to pass this vector by reference instead! (BTW, it is better to pass by const reference the string strFile parameter too):
    Code:
    void readFile(const string &strFile, vector<string> &vecNames, ifstream &iFile)
    Besides, your code is very hard to read/understand because you didn't use the Code tags. Please, read the Announcement: Before you post....
    Victor Nijegorodov

  4. #4
    Join Date
    Nov 2011
    Posts
    3

    Re: Reading a text file into a vector

    Hey, sorry I wasn't sure how to do that on this site, I am sort of a noob with forums...
    But thank you so much! I fixed those and now it's working great.

    Although, the only problem I am having still is with my deleting a name function, in which I used pop.back, and it takes the last names off of the vector, I knew it wouldn't work but I wasn't sure how else to do it?. If I wanted to take a name off that is let's say in the middle of the vector, how would I do that?

    Here is the code for the function:

    Code:
    void deleteName(string strFile, ofstream &oFile, vector<string> &vecNames) //Delete the name funtion definition
    {
    	string strFName; //Initialize first name variable
    	string strLName; //Initialize last name variable
    
    	cout << "----------------------------------------\n";
    	cout << "Enter the name to be deleted <First and Last Name>: "; //Ask use what name they want to delete
    	cin >> strFName >> strLName;
    
    	vecNames.pop_back(); //Take that name off of the vector
    
    	oFile.open(strFile.c_str()); //Open the output file
    
    	while (oFile.fail()) //While the output while does not open display and error message and ask the user again
    	{
    		cout << "----------------------------------------\n";
    		cout << "Output file error!\n";
    		cout << "Enter the name to be deleted <First and Last Name>: ";
    		cin >> strFName >> strLName;
    
    		oFile.open(strFile.c_str());
    	}
    
    	for (int i = 0; i < vecNames.size(); i++)
    		oFile << vecNames[i] << endl; //Put the names from the vector into the output file
    
    	oFile.close(); //Close the output file
    
    	cout << "---- Name '" << strFName << " " << strLName << "' has been deleted.\n";
    }

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Reading a text file into a vector

    Quote Originally Posted by lolwut25 View Post
    Hey, sorry I wasn't sure how to do that on this site, I am sort of a noob with forums...
    But thank you so much! I fixed those and now it's working great.
    You are still passing the string by value instead of const reference.
    Although, the only problem I am having still is with my deleting a name function, in which I used pop.back, and it takes the last names off of the vector, I knew it wouldn't work but I wasn't sure how else to do it?.
    First, when the name to delete is inputted, you should make sure that the name inputted is in the exact format as the names in the vector. In other words, you have to ensure that it's in this format:
    Code:
    strFName + " " + strLName;
    Since that is how you are storing the names in the vector.

    Once you ensure that the name inputted is in the same format, then the function you want to call is std::find(). This function returns an iterator to the found item, or vector::end() if not found. There is no need to write loops as you've done.

    Then when it's found, then you call vector.erase() with the iterator returned from find.

    http://www.cplusplus.com/reference/algorithm/find/
    http://www.cplusplus.com/reference/stl/vector/erase/

    The page above describes the algorithm find() function, and the vector::erase() function. Please look at the sample programs, and if you need to, write a simple main() program to get familiar with these two functions and the concepts of algorithms.

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Oct 2011
    Posts
    23

    Re: Reading a text file into a vector

    This isn't exactly what you are doing, but it has all the same parts . . .

    Code:
    //in the .h file
    #include <vector>
    
    using namespace std;
    
    typedef vector<CString> vec;
    typedef vec::iterator _vec;
    
    //in the .cpp file in a function somewhere . . .
      char
        szData[MAX_PATH];
      FILE
        *pInFile,
        *pOutFile;
      CString
        strOutMask  = NIX,
        strInFile   = "Source.txt",
        strBackup   = "Source.bak",
        strOutFile  = "Source.tmp";
      vec
        vecStr;
      _vec
        vecit;
      errno_t
    	err;
    
    
        err = fopen_s(&pInFile,  strInFile,  "r");
        err = fopen_s(&pOutFile, strOutFile, "w");
    
        while (!feof(pInFile))
        {
            fgets(szData, MAX_PATH, pInFile);
            strVal = CString(szData);
    		vecStr.push_back(strVal);
       }
    
        for (vecit = vecStr.begin(); vecit != vecStr.end(); vecit++)
        {
            strVal = (*vecit);
    		
            strOutMask = "%s";
            fprintf(pOutFile, strOutMask, strVal);
        }
    
        fclose(pInFile);
        fclose(pOutFile);
        remove(strBackup);
        rename(strInFile, strBackup);
        rename(strOutFile, strInFile);

  7. #7
    Join Date
    Jun 2012
    Posts
    37

    Re: Reading a text file into a vector

    Purpose of MFC SDI: read a text file having floating values with tab separated not comma

    I added a menu Contour plot menu and 1. colour and 2. Gray Scale as sub menu. On pressing Colour a dialog box appears, whose purpose is to browse a text file. I browse and selct it and the path is visible in an EDIT box beside the browse button
    and a plot button in dialog box to plot on the SDI window.

    I am successful in browsing and selecting the text file. When I click plot button it should read and further porcess it which i am not able to implement. I ahve the logic to process it. I need to read the text file and store the floating point values in an 2D array. Anyone can help me please. its urgent!!
    Dialog box picture looks somewhat like this

    --------------------------------------------------------------------------|
    |
    -----------------------------------------------| |
    |C://Mytext.txt | Browse Button |
    | | |
    ------------------------------------------------

    PLOT BUTTON
    --------------------------------------------------------------------------








    The dialog class i am attaching the code


    void CColourdlg::OnBrowse() //BROWSE BUTTON
    {
    // TODO: Add your control notification handler code here

    //Code to Browse Button and display in the edit box
    CFileDialog FileDialog(TRUE,
    "*.*",
    NULL,
    OFN_HIDEREADONLY,
    "Text Files: (*.txt)|*.txt||");

    if(FileDialog.DoModal() == IDOK)
    {
    CString path = FileDialog.GetPathName();
    SetWindowText (path);
    CEdit* cedit;
    cedit = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT1));
    cedit->SetWindowText(path);



    }
    }

    void CColourdlg::OnPlot() //PLOT BUTTON
    {
    // TODO: Add your control notification handler code here
    int i=0;
    double array[10];
    char cNum[10];
    ifstream ifs;
    ofstream ofs;

    ifs.open(m_path,ios::nocreate); //m_Path is a variable atached
    //to edit box but i am not able
    // to get the path of the txt fil
    while (ifs.good())
    {
    ifs.getline(cNum,256,' ');
    array[i]= atof(cNum);
    i++;

    }
    //OnOK();


    }

  8. #8
    Join Date
    Apr 2010
    Posts
    172

    Re: Reading a text file into a vector

    In the delete function:

    Code:
     
    cin >> strFName >> strLName;
    vecNames.pop_back(); //Take that name off of the vector
    
    oFile.open(strFile.c_str()); //Open the output file
    include
    Create an iterator for your vecName vector.
    Code:
    cin >> strFName >> strLName;
    
    vecNames.pop_back(); //Remove
    for(itr = vecNames.begin(); itr <= vecNames.end();++itr)
    {
         if(*itr == strFName)
    {
        itr = vecNames.erase(itr); //reassigning the itr to stop it becoming invalid. 
        break;
    }
    
    }//Do the same for strLName.
    
    oFile.open(strFile.c_str()); //Open the output file

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Reading a text file into a vector

    Quote Originally Posted by gaar321 View Post
    Create an iterator for your vecName vector.
    Code:
    cin >> strFName >> strLName;
    
    vecNames.pop_back(); //Remove
    for(itr = vecNames.begin(); itr <= vecNames.end();++itr)
    {
         if(*itr == strFName)
    {
        itr = vecNames.erase(itr); //reassigning the itr to stop it becoming invalid. 
        break;
    }
    First:
    Code:
    for(itr = vecNames.begin(); itr != vecNames.end();++itr)
    A vector iterator should be compared with != or ==.

    Also, this same code does everything your code does to erase:
    Code:
    #include <algorithm>
    //...
    vector<string>::iterator it = std::find(vecNames.begin(), vecNames.end(), strFName);
    if ( it != vecNames.end() )
        vecNames.erase(it);
    This always works, and avoids the iffy for loop with the <= comparison.

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Apr 2010
    Posts
    172

    Thumbs up Re: Reading a text file into a vector

    Paul this user may want to know the internal workings of how to actually find a middle value in the vector not just to know that a function does it for you, in this case std::find, also the for loop will always work if you code it correctly??

  11. #11
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Reading a text file into a vector

    Quote Originally Posted by gaar321 View Post
    Paul this user may want to know the internal workings of how to actually find a middle value in the vector not just to know that a function does it for you, in this case std::find, also the for loop will always work if you code it correctly??
    Everything works if they're coded correctly. The keyword is if.

    To ensure that there is no "if", find() makes sure there are no mistakes.

    Regards,

    Paul McKenzie

Tags for this Thread

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured