-
November 25th, 2011, 02:42 AM
#1
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
}
-
November 25th, 2011, 02:43 AM
#2
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
}
-
November 25th, 2011, 05:02 AM
#3
Re: Reading a text file into a vector
 Originally Posted by lolwut25
...
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
-
November 25th, 2011, 03:30 PM
#4
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";
}
-
November 25th, 2011, 04:25 PM
#5
Re: Reading a text file into a vector
 Originally Posted by lolwut25
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
-
December 5th, 2011, 02:57 AM
#6
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);
-
June 2nd, 2012, 07:15 AM
#7
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();
}
-
June 4th, 2012, 04:33 PM
#8
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
-
June 4th, 2012, 04:48 PM
#9
Re: Reading a text file into a vector
 Originally Posted by gaar321
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
-
June 4th, 2012, 05:06 PM
#10
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??
-
June 4th, 2012, 06:29 PM
#11
Re: Reading a text file into a vector
 Originally Posted by gaar321
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
-
June 4th, 2012, 07:43 PM
#12
Re: Reading a text file into a vector
I found the solution the follwing codes reads the tab separated values and stores in a 2D vector and finds the max value in the 2d vector and divides them with largest value to all values in 2d vector. The fractional values which lies between0-1 is stored in text files with tab separated..
I am attaching the code
int j=0,i=0,k=0,l=0,ncols=0, nrows=0;
double array[10][10]={0};
std: fstream ofs;
CEdit *pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);
LPTSTR lpData = new TCHAR[500];
ZeroMemory(lpData,500*sizeof(TCHAR));
pEdit->GetLine(0,lpData,500);
std::string line;
std::ifstream ifs(lpData,ios::nocreate);
//Declare a Matrix pointer
std::vector< std::vector<double> > vec;
//Store in Matrix
//ifs.open(lpData,ios::nocreate);
std::string lin;
while (std::getline(ifs, lin)) // read one line at a time
{
double val;
std::istringstream jss(lin);
std::vector<double> row;
j=0;
while (jss >> val) // read one value at at time from the line
{
row.push_back(val);
j++;
}
vec.push_back(row);
i++;
::MessageBeep((WORD)-1);
}
ncols=j;
nrows=i;
ifs.close();
std::vector<double>::iterator itr;
std::vector<double>::iterator col;
std::vector< std::vector<double> >::iterator row;
std::vector<double> vec_rmax;
for (row = vec.begin(); row != vec.end(); row++)
{
itr=std::max_element( row->begin(), row->end() );
vec_rmax.push_back(*itr);
}
itr=std::max_element( vec_rmax.begin(), vec_rmax.end() );
// Divide with maximum value
for (row = vec.begin(); row != vec.end(); row++)
{
for (col = row->begin(); col != row->end(); col++)
{
*col=(*col/ *itr);;
}
}
ofs.open("Matrix.txt");
//ofs<<vec[1][1];
for (k=0;k<nrows;k++)
{
for (l=0;l<ncols;l++)
{ofs<<vec[k][l]<<'\t';} ofs<<'\n';}
ofs.close();
OnOK();
-
June 4th, 2012, 07:49 PM
#13
Re: Reading a text file into a vector
Ok Now after getting the output text file.. I want make a contour plot of the values. Th value are at each pixel i am having. I have the logic to convert the fractional values to RGB values and plot them pixel in view class.
My question is: Is it possible to generate a bitmap picture by using setpixel fucntion and save that bitmap as a temporary file in the working directory . display using CDC *pDC available fucntion to display bitmap generated in the working directory inthe ondraw() function. It should automatically take the bitmap from the working directory.. What is the way to catch the bitmap directory automatically?
It should e done when i press PLOT BUTTON... Please anyone caould help me out??? Please
-
June 4th, 2012, 09:55 PM
#14
Re: Reading a text file into a vector
 Originally Posted by Paul McKenzie
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
Can u help me .. I have posted a new problem.. can u just help me please...
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|