i am trying to print 10 lines from a text file, and print another 10 based on user input or stop. My code print 10 lines but the first line is blank each time.
cin>>input;
ifstream file("midterm.txt");
while(input != sentinel && file >> output ) {
for(int i = 0; i < 10; i++) {
getline(file, output);
cout<<output<<endl;
}
cout<<"\nEnter any key to continue reading, enter # to stop"<<endl;
cin>>input;
}
file.close();
cout<<"File End";
return 0;
In your code, you should add ios::ate to make the lines working and you should also show what type are the used variables. Try that:
string input;
string sentinel = "#";
string output;
cin>>input;
ifstream file("midterm.txt",ios::ate);
while(input != sentinel && file >> output ) {
for(int i = 0; i < 10; i++) {
getline(file, output);
cout<<output<<endl;
}
cout<<"\nEnter any key to continue reading, enter # to stop"<<endl;
cin>>input;
}
file.close();
cout<<"File End";
return 0;
Related
im a Student and new to this site. I want to split my txt file with my highscore data back to my Highscore List.
The txt file stores my Highscore like name:score
My parsing is not working and i dont know why?
I just want to split it to name and score again and then put it in my HighscoreList.
If you have any question about the code just ask :)
#include "highscore.h"
highscore::highscore(){
}
struct highscore::Player{
string spielerName;
int score;
};
void highscore::writeHighscore(string name, int score ,int playerNumberx){
Player HighscoreListe[100];
for(int i=0;i<=99;i++){
HighscoreListe[i].score = {0};
}
for(int i=0;i<=99;i++){
HighscoreListe[i].spielerName = "leer";
}
HighscoreListe[playerNumberx].spielerName = name;
HighscoreListe[playerNumberx].score = score;
int i, j,temp;
string temp1;
ifstream myfile("scores.txt");
string line;
//heres the point where i need help!!
if (myfile.is_open()){
int z=0;
while(getline(myfile, line)){
string name1;
string score1;
int d = 20;
while(line[z] != ':'){
name1 += line[z];
z++;
}
z = z+2;
while(line[z] != '\0'){
score1 += line[z];
z++;
}
HighscoreListe[d].spielerName = name;
HighscoreListe[d].score = score;
d++;
}
myfile.close();
}else cout << "Unable to open file" << endl;
for(i = 0; i<100; i++) {
for(j = i+1; j<100; j++)
{
if(HighscoreListe[j].score < HighscoreListe[i].score) {
temp = HighscoreListe[i].score;
temp1 = HighscoreListe[i].spielerName;
HighscoreListe[i].score = HighscoreListe[j].score;
HighscoreListe[i].spielerName = HighscoreListe[j].spielerName;
HighscoreListe[j].score = temp;
HighscoreListe[j].spielerName = temp1;
}
}
}
ofstream myfilex("scores.txt");
if (myfilex.is_open()){
for(int i = 99;i>89;i--){
myfilex << HighscoreListe[i].spielerName << ":" << HighscoreListe[i].score<<endl;
}
myfilex.close();
}
else cout << "Unable to open file" << endl;
}
void highscore::readHighscore(){
string line;
ifstream myfile("scores.txt");
if (myfile.is_open()){
while(getline(myfile, line)){
cout << line << endl;
}
}
else cout << "Unable to open file" << endl;
}
Make a >> overload for highscore::Player.
In the >> overload
Use std::getline to read a line from the input stream.
Create a std::istringstream out of the line.
Use std::getline to read up to the : from the istringstream into a local string name;.
Use another std::getline to read the rest of the line into a string.
Convert the string into an int with std::stoi and store into a local int score;. Make sure you provide a pos argument.
Ensure that the entire string was converted by comparting the pos argument with the string's length.
If nothing went wrong, store name and score into the highscore::Player passed by the caller. Otherwise, set the failbit on the input stream with setstate
return the input stream.
Now the reading code should be something simple like
int scorecount = 0;
while (myfile >> HighscoreListe[scorecount])
{
scorecount++;
}
Using getline to store information, I want to have an array which store a whole column in a text file, using a '/' as the delimiter, but when creating a loop which goes through the first line and stores that in a[i] etc, then moves onto the next line.`
const int MAX = 20;
int main(){
string menuname;
string a[MAX];
string d[MAX];
string b[MAX];
string c[MAX];
string line;
bool error = false;
ifstream openFile;
int counter = 0;
do{
cout << "Please enter the name of the menu you would like to open: ";
cin >> menuname;
menuname += ".txt";
openFile.open(menuname.c_str());
if(openFile.fail()){
cerr << "Unable to open file, please re-enter the name.\n";
error = true;
}
//Determine how many lines long the text file is
while(getline(openFile, line)){
++counter;
}
//Testing the counter
cout << counter;
}while(error == true);
while(! openFile.eof()){
for(int i = 0; i < counter; i++){
getline( openFile, a[i], '/');
getline( openFile, b[i], '/');
getline( openFile, c[i], '/');
getline( openFile, d[i]);
}
}
for(int i = 0; i < counter; i++){
cout << a[i] << b[i];
}
}
There is currently no errors when i run the program, and I have tested the counter variable by just showing an output, which is working correctly, but at the bottom of the program I have created a small test which should print some 2 of the arrays I store, but it prints nothing and the program just ends after displaying the value of counter.
The problem is you are at the end of the file when you go to actually store the data.
while(getline(openFile, line)){
++counter;
}
Reads the file all the way to the end and then sets the EOF flag on the string. Then you get to
while(! openFile.eof()){
for(int i = 0; i < counter; i++){
getline( openFile, a[i], '/');
getline( openFile, b[i], '/');
getline( openFile, c[i], '/');
getline( openFile, d[i]);
}
}
And since the EOF flag is set the while loop is never executed. Since all you really need counter for is the the display loop at the end we can combine the counter loop and the reading loop into one loop like
while(getline( openFile, a[counter], '/') && getline( openFile, b[counter], '/') &&
getline( openFile, c[counter], '/') && getline( openFile, d[counter])){
counter++;
}
And now we read in the full file and get a count of the number of lines read.
When I enter "1", for loop should run one time. but it just prints "0". I don't know why.
I think the problem is with "getline(cin, input)" but i dont know the problem.
Here is the code:
int main()
{
string input;
int t, output, occured_length, lenght, match;
char occured[26];
cin>>t;
for(int i=0; i<t; i++) //I am talking about this loop
{
occured_length = 0;
getline(cin, input); //This might be causing the problem
lenght = input.size();
for(int j=0; j<lenght; j++)
{
if(occured_length == 25)
{
cout<<"\n"<<occured_length+1;
break;
}
match = 0;
for(int k=0; k<occured_length; k++)
{
if(input[j] == occured[k])
{
match= 1;
break;
}
}
if(match == 0)
{
occured_length++;
occured[occured_length] = input[i];
}
}
cout<<"\n"<<occured_length;
}
return 0;
}
input is empty & length is 0
istream& getline (istream& is, string& str);
Gets line from input stream into string. It extracts characters from is and stores them into str until the the newline character, '\n' is found.
\n remains in the input stream, you need to another dummy input reading, otherwise you will get input = "" on next getline
cin>>t;
char c;
cin >> c;
The problem is that after the input with using operator >>
cin>>t;
the input buffer will contain new line character. And next statement with getline
getline(cin, input);
reads an empty string.
You have to remove the new line character from the input buffer usig method ignore. For example
#include <limits>
//...
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
The call of ignore should be before getline and after operator >>.
char fname[20];
char lname[20];
int grade[10];
double avg=0.00;
fstream infile("C:\\Users\\Hady Zn\\Desktop\\hady.txt", ios::in);
fstream outfile("C:\\Users\\Hady Zn\\Desktop\\hady1.txt", ios::out);
while(infile>>fname>>lname)
{
outfile<<fname<<" "<<lname<<" ";
for(int i=0; i<10; i++)
grade[i]=0;
for(int i=0; i<10; i++)
{
infile>>grade[i];
if(grade[i]>=0 && grade[i]<=100)
{
outfile<<grade[i]<<" ";
avg+=grade[i];
}
}
outfile<<avg/10.00<<endl;
avg=0.00;
}
So the question is that i need to read from a text file a last name(space) first name(space) then 10 quiz grades(space between each grade) and write the same data into an output file with the average of 10 quizzes at each end of a line. The problem that im facing is that if i had less than 10 quizzes on one line it will not display the remaining lines.(I want it to still give me the average of the grades given considering for example if i was given 7 grades 3 will be zeros) I tried solving it but it just won't work. Any ideas that can solve this? Please help. Thank you
In order to perform such checks, it's better to read the text from the input file line by line and process each line to extract the data.
string line
while ( getline(infile, line) )
{
istringstream sstream(line);
sstream >> fname >> lname;
if (!sstream )
{
continue;
}
outfile<<fname<<" "<<lname<<" ";
for(int i=0; i<10; i++)
{
grade[i]=0;
sstream>>grade[i];
if ( !sstream )
{
break;
}
if(grade[i]>=0 && grade[i]<=100)
{
outfile<<grade[i]<<" ";
avg+=grade[i];
}
}
}
Update, in response to comment by OP:
You can avoid reading the input file line by line and processing each line. Here's my suggested changes to the loop.
while(infile>>fname>>lname)
{
outfile<<fname<<" "<<lname<<" ";
for(int i=0; i<10; i++)
{
grade[i]=0;
infile>>grade[i];
if ( !infile )
{
infile.clear();
break;
}
if(grade[i]>=0 && grade[i]<=100)
{
outfile<<grade[i]<<" ";
avg+=grade[i];
}
}
outfile<<avg/10.00<<endl;
avg=0.00;
}
I am trying to get a file location from the user. I've used the same getfile function on dozens of programs with no issues. For some strange reason this one always returns a cannot open file on the 1st try but then accepts it on the 2nd try. I have tried a cin.clear(); before the getline where I get the file location but that was no help. I cant figure out why this is acting so weird. Here is my getfile function:
void maze::getfile()
{
string filename;
char X;
cout << "please enter the location of the file you wish to input: " << endl;
getline(cin, filename);
cin.ignore(100, '\n');
inData.open(filename.c_str()); //opens file
while (!inData) //while the file is accesible
{
cout << "The file could not be opened.\nPlease try again: " << endl;
//error message for input validation
getline(cin, filename);
cin.ignore(100, '\n');
inData.open(filename.c_str());
}
for(int i = 1; i < 11; i++)
{
for(int u = 1; u < 11; u++)
{
inData >> X >>ws;
if(X == '1')
X = 219;
if(X == '0')
X = ' ';
floor[i][u] = X;
}
}
floor[0][0] = 201;
floor[0][11] = 187;
floor[11][0] = 200;
floor[11][11] = 188;
for(int i=1; i < 11; i++)
{
floor[0][i] = 205;
floor[11][i] = 205;
floor[i][0] = 186;
floor[i][11] = 186;
}
inData.close();
}
The only thing that happens before this is the main menu call. I set a variable choice = to a main menu function that returns a char, in this case '1'. Any ideas why it's failing on the first file input and not the 2nd try with the same file?
I'm sure you left a newline(maybe scanf(), cin>>, gets() left in) in the stream before you call std::getline first time, so that it gives you an empty string for the filename, after that, newline is eaten, so it works fine second time.