So the question is: How am I going to extract only the data I wanted from different lines(only the names, ids and phone numbers without other unwanted words)
Coz I just know how to extract whole line from a text file...
I need the concept in detail and if can some code examples will help me alot
Employee e;
while ( in >> e ) {
// add e to collection
}
The question is, how to in >> e, which requires an operator: std::istream& operator>> ( std::istream& lhs, Empoyee& rhs );
What should that operator do?
1. Read lines from lhs until it gets a line that starts with "Emp Id ="
2. You do know how many characters are before the ID, so use substr() to get the suffix part of the line
3. Copy suffix into rhs.id
4. Get next line. You should check that it starts with "Name ="
5. Again, copy suffix into rhs.name
6. Get next line. You should check that it starts with "Phone Number ="
7. Again, copy suffix into rhs.phone_num
8. return the lhs
Honestly I am just a fresh college student and honestly this is one of the problems I met when I am doing my assignment....(but I'm not copying the whole question here!! I'm just wanna ask for the concept coz I am really confused)
Is there other any method besides this, which only requires basic knowledge of fstream, strings, structure and pointer?
Coz I really dont know what do you mean in your answer and even if I know the concept it might not be accepted by my college in this semester tho.......
The "ignore" statements will get you past everything including the space after the (=) allowing you to store what is left in the variable.
In the struct you might want to increase the size of the arrays by +1 to leave room for the (\0) at the end of the string. As an example the ID would read 8 - 1 giving you 7 characters for the ID + the (\0) at the end.
*The id[7] has been edited to id[12], sry my typo T^T
Andy: Thanks for the answer!! Your answer is more understandable to me than the first ans given by keskiverto
Also, this is a c++ program indeed, but I also dunno why we have to use char array instead of strings....Maybe there are other reasons that i dont know?
salem c:
> Coz I just know how to extract whole line from a text file...
What i mean here is as a newbie in C++ I only know how to getline(inFile,line) to read the whole line from a text file.... That is why I am stuck here
Hint: You can edit your post, highlight your code and press the <> formatting button. This will not automatically indent your code. That part is up to you.
You can use the preview button at the bottom to see how it looks.
I looked through your code and found out there are some limits and vectors which I believe that it is forbidden in my current subject.....but I might take this as a new method to solve this kind of problem
Thank you for spending your time to type such long code for me tho
Andy:
Thanks for the reminder
This is my first time posting discussions here so I still dont know how to post codes heheh
Luckily your answer is understandable and applicable to me
Note that <limits> is used for .ignore(). If you don't want to use limits, just replace std::numeric.... with say 1000. It's just to skip over chars to the next \n.
#include <iostream>
#include <string>
#include <fstream>
constexprunsigned MAXSIZE{ 10 };
struct Employee
{
char id[12]{};
char name[30]{};
char phone_num[10]{};
};
int main()
{
const std::string inFileName{ "employee.txt" }; // <--- Put File name here.
std::ifstream inFile(inFileName);
if (!inFile)
{
//return std::cout << "\n\n File " << std::quoted(inFileName) << " did not open.\n", 1;
return std::cout << "\n\n File \"" << inFileName << "\" did not open.\n", 1;
}
unsigned records{}, idx{}; // <--- ALWAYS initialize all your variables.
Employee employees[MAXSIZE];
while (inFile.ignore(9) && inFile >> employees[idx].id)
{
inFile.ignore(8);
inFile.get(employees[idx].name, 31);
inFile.ignore(16);
inFile.get(employees[idx++].phone_num, 11);
inFile.ignore(); // <--- Eats the blank line between records.
records++;
}
for (unsigned idx{}; idx < records; idx++)
{
std::cout
<< "Emp Id = " << employees[idx].id << '\n'
<< "Name = " << employees[idx].name << '\n'
<< "Phone Number = " << employees[idx].phone_num << "\n\n";
}
// <--- Keeps console window open when running in debug mode on Visual Studio. Or a good way to pause the program.
// The next line may not be needed. If you have to press enter to see the prompt it is not needed.
//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
std::cout << "\n\n Press Enter to continue: ";
std::cin.get();
return 0; // <--- Not required, but makes a good break point for testing.
}
This gives the output of:
Emp Id = 1290229
Name = Luke Skywalker
Phone Number = 736-6587
Emp Id = 1201195
Name = Alice Watson
Phone Number = 789-4652
Emp Id = 1924899
Name = Jake Muller
Phone Number = 790-0658
Press Enter to continue:
What happens if the amount of data is greater than the size of the char array? That's why I have the extra .ignore() after to remove anything left. See above.
Good point, but I feel this is a school assignment to cover what has been covered so far. There for the struct may have been given with the size of the arrays to cover what might occur and the chances of any line being larger than the array would be small.
Having to deal with anything larger than any array may be for a future class or OJT.
Strange thing is when I tested the name "Jake Muller Alice Watson Luke Skywalker" it stored the whole name and the for loop printed it out with no problem.
My understanding of the above reference page here input should have only taken this much
"Jake Muller Alice Watson Luke ".
If it does that then there is nothing left but the (\n) to ignore.
3) Same as get(s, count, widen('\n')), that is, reads at most count-1 characters and stores them into character string pointed to by s until '\n' is found.
Since it is taking the whole string one would thing that there would be a run time error when the string exceeds the character array.