So I'm really stuck trying to figured this bug on the program that is preventing me from displaying the text of my program..
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <stdio.h>
using namespace std;
int main ()
{
ifstream infile;
ofstream offile;
char text[1024];
cout <<"Please enter the name of the file: \n";
cin >> text;
infile.open(text);
string scores; // this lines...
getline(infile, scores, '\0'); // is what I'm using...
cout << scores << endl; // to display the file...
string name1;
int name2;
string name3;
int name4;
infile >> name1;
infile >> name2;
infile >> name3;
infile >> name4;
cout << "these two individual with their age add are" << name2 + name4 <<endl;
// 23 + 27
//the result I get is a bunch of numbers...
return 0;
}
Is there any way cleaner or simple method i can used to display the file ?
All the method in the internet are difficult to understand or keep track due to
the file is open in loop..
I want a program that you type the name of the file and displays the file
the file will contain the following...
jack 23
smith 27
Also I need to obtain data from the file now I'm using the above code to obtain that information from the file...
loop is probably the best thing you can do.
so if you know the format you could simply do it like this
#include <iostream>
#include <fstream>
using namespace std;
int printParsedFile(string fileName) { // declaration of a function that reads from file passed as argument
fstream f; // file stream
f.open(fileName.c_str(), ios_base::in); // open file for reading
if (f.good()) { // check if the file can be read
string tmp; // temp variable we will use for getting chunked data
while(!f.eof()) { // read data until the end of file is reached
f >> tmp; // get first chunk of data
cout << tmp << "\t"; // and print it to the console
f >> tmp; // get another chunk
cout << tmp << endl; // and print it as well
} else {
return -1; // failed to open the file
}
return 0; // file opened and read successfully
}
you can call then this function for example in your main() function to read and display file passed as argument
int main(int argc, char** argv) {
string file;
cout << "enter name of the file to read from: "
cin >> file;
printParsedFile(file);
return 0;
}
I personally use stringstreams for reading one line at a time and parsing it:
For example:
#include <fstream>
#include <stringstream>
#include <string>
std::string filename;
// Get name of your file
std::cout << "Enter the name of your file ";
std::cin >> filename;
// Open it
std::ifstream infs( filename );
std::string line;
getline( infs, line );
while( infs.good() ) {
std::istringstream lineStream( line );
std::string name;
int age;
lineStream >> name >> age;
std::cout << "Name = " << name << " age = " << age << std::endl;
getline( infs, line );
}
Related
i want to receive an input from user and search a file for that input. when i found a line that includes that specific word, i want to print it and get another input to change a part of that line based on second user input with third user input. (I'm writing a hospital management app and this is a part of project that patients and edit their document).
i completed 90 percent of the project but i don't know how to replace it. check out following code:
#include <iostream>
#include <stream>
#include <string.h>
#include <string>
using namespace std;
int main(){
string srch;
string line;
fstream Myfile;
string word, replacement, name;
int counter;
Myfile.open("Patientlist.txt", ios::in|ios::out);
cout << "\nEnter your Name: ";
cin.ignore();
getline(cin, srch);
if(Myfile.is_open())
{
while(getline(Myfile, line)){
if (line.find(srch) != string::npos){
cout << "\nYour details are: \n" << line << endl << "What do you want to change? *type it's word and then type the replacement!*" << endl;
cin >> word >> replacement;
}
// i want to change in here
}
}else
{
cout << "\nSearch Failed... Patient not found!" << endl;
}
Myfile.close();
}
for example my file contains this line ( David , ha , 2002 ) and user wants to change 2002 to 2003
You cannot replace the string directly in the file. You have to:
Write to a temporary file what you read & changed.
Rename the original one (or delete it if you are sure everything went fine).
Rename the temporary file to the original one.
Ideally, the rename part should be done in one step. For instance, you do not want to end up with no file because the original file was deleted but the temporary one was not renamed due to some error - see your OS documentation for this.
Here's an idea:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
using namespace std;
void replace(string& s, const string& old_str, const string& new_str)
{
for (size_t off = 0, found_idx = s.find(old_str, off); found_idx != string::npos; off += new_str.length(), found_idx = s.find(old_str, off))
s.replace(found_idx, old_str.length(), new_str);
}
int main()
{
const char* in_fn = "c:/temp/in.txt";
const char* bak_fn = "c:/temp/in.bak";
const char* tmp_fn = "c:/temp/tmp.txt";
const char* out_fn = "c:/temp/out.txt";
string old_str{ "2002" };
string new_str{ "2003" };
// read, rename, write
{
ifstream in{ in_fn };
if (!in)
return -1; // could not open
ofstream tmp{ tmp_fn };
if (!tmp)
return -2; // could not open
string line;
while (getline(in, line))
{
replace(line, old_str, new_str);
tmp << line << endl;
}
} // in & tmp are closed here
// this should be done in one step
{
remove(bak_fn);
rename(in_fn, bak_fn);
remove(out_fn);
rename(tmp_fn, in_fn);
remove(tmp_fn);
}
return 0;
}
One possible way:
Close the file after you read it into "line" variable, then:
std::replace(0, line.length(), "2002", "2003")
Then overwrite the old file.
Note that std::replace is different from string::replace!!
The header is supposed to be <fstream> rather than <stream>
you can't read and write to a file simultaneously so I have closed the file after reading before reopening the file for writing.
instead of updating text inside the file, your line can be updated and then written to file.
#include <iostream>
#include <fstream>
#include <string.h>
#include <string>
using namespace std;
int main(){
string srch;
string line, line2;
fstream Myfile;
string word, replacement, name;
int counter;
Myfile.open("Patientlist.txt", ios::in);
cout << "\nEnter your Name: ";
cin.ignore();
getline(cin, srch);
if(Myfile.is_open())
{
while(getline(Myfile, line)){
if (line.find(srch) != string::npos){
cout << "\nYour details are: \n" << line << endl << "What do you want to change? *type it's word and then type the replacement!*" << endl;
cin >> word >> replacement;
int index = line.find(word);
if (index != string::npos){
Myfile.close();
Myfile.open("Patientlist.txt", ios::out);
line.replace(index, word.length(), replacement);
Myfile.write(line.data(), line.size());
Myfile.close();
}
}
// i want to change in here
}
}else
{
cout << "\nSearch Failed... Patient not found!" << endl;
}
}
I am working on a C++ compiler called Online GDB. I need to write a program that asks the user for a file name then reads from this data to calculate an average then displays the data.
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <cstdlib>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
// functions
string getFileInfo();
double calculateMean (string fileName);
// main
int main ()
{
string filename = getFileInfo(); // getting file name
double mean = calculateMean( filename); // avg
cout << "The mean was" << endl;
return 0;
}
// function for getting file
string getFileInfo() {
string filename;
ifstream inputFile; // varibles
// asking user for the name
cout << "Please enter a file name to read from: ";
cin >> filename;
inputFile.open(filename);
// opening name and checking if its good.
if (inputFile)
{
inputFile.close();
}
// if the file is not good
else
{
cout << "Error: Please enter a file name to read from: ";
cin >> filename;
}
return 0;
}
// funtion for mean
double calculateMean(string fileName)
{
ifstream infile;
float num=0;
float total = 0.0;
int count = 0;
infile.open(fileName);
// While infile successfully extracted numbers from the stream
while(infile >> num) {
total += num;
++count;
}
// don't need the file anymore, close it
infile.close();
// give the average
return total/count;
}
My part for finding the average is working but I am having trouble with the naming of the file.
It runs and it asks me for the name and when I enter it goes straight to the error and input again and then it displays this:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Aborted.
I have never seen this before and I have tried creating a file and if I don't then nothing displays.
This code is fully working
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <cstdlib>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
//int calculatorMin(string fileName);
//void displayInfo(double mean, int main);
string getFileInfo();
double calculateMean (string fileName);
// main
int main ()
{
string filename = getFileInfo(); // getting file name
double mean = calculateMean( filename); // avg
return 0;
}
// function for getting file
string getFileInfo() {
string filename;
ifstream inputFile;
cout << "Please enter a file name to read from: ";
cin >> filename;
inputFile.open(filename);
if (inputFile)
{
inputFile.close();
}
else
{
cout << "Error: Please enter a file name to read from: ";
cin >> filename;
}
//if it opens then name is good and close file then return name
//if it didn't open, ask for a new name.
return filename;
}
// funtion for mean
double calculateMean(string fileName)
{
ifstream infile;
float num=0;
float total = 0.0;
int count = 0;
infile.open(fileName);
// While infile successfully extracted numbers from the stream
while(infile >> num) {
total += num;
++count;
}
// don't need the file anymore, close it
infile.close();
cout << "The mean was " << total/count << endl;
// give the average
return total/count;
}
My skills are very basic. I'm trying to make save and load functions for a text game. This is my code:
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>
#include "variables.h"
// CORE FUNCTIONS
void save_game()
{
std::ofstream file((savefile_path + "/" + player_name + ".txt").c_str());
if (file.is_open())
{
file << engine_switch << std::endl; //int
file << map_switch << std::endl; // int
file << sub_map_switch << std::endl; // int
file << player_name << std::endl; //string
file << player_class << std::endl; // string
//file << << endl;
file.close();
}
else
{
std::cout << "A PROBLEM OCCURED";
system("pause");
}
return;
}
void load_game()
{
system("cls");
std::cout << "ENTER THE SAVE FILE NAME (SAME AS YOUR CHARACTER NAME)\nOR PRESS ENTER TO GO BACK TO MAIN MENU: ";
fflush(stdin);
getline(std::cin, player_name);
std::string name=player_name;
std::ifstream file((savefile_path + "/" + player_name + ".txt").c_str());
if(file)
{
file >> engine_switch; // this is int
file >> map_switch; // this is int
file >> sub_map_switch; /this is int
file >> player_name; //string
file >> player_class; //string
//file >> ;
return;
}
else
{
if(player_name=="\0")
{
engine_switch=1;
return;
}
else
{
system("cls");
std::cout << "COULDN'T OPEN THE SAVE FILE" << std::endl;
system("pause");
load_game();
}
}
engine_switch=1;
return;
}
The problem happens when I enter a player_name compound of multiple words separated with a space. For example when I enter "name name" the player_name becomes name and the player_class becomes name and the actual player_class is not put into any variable.
I tried the rdbuf() function, but didn't work and I don't even understand it yet. I tried it with stream, string, c.str(), everything I found on the web and could comprehend, but it always comes out wrong.
When you extract a string from a stream, spaces are considered as separators.
It's even worse: in your code, the player_name is followed by player_class which is also a string. How should your program interpret this :
10 15 20 John William Doe hero B
How would your program guess that John William Doe is a composed name and hero B the category ?
The simplest solution is to write all your strings on a separate line in the file. When you load it you can then read it with getline():
file >> engine_switch; // this is int
file >> map_switch; // this is int
file >> sub_map_switch; /this is int
getline (file, player_name); //string
getline (file, player_class; //string
You need to use getline instead of the >> operator in your load-game function.
Instead of doing file >> player_name do getline(file, player_name)
This should be used in replacement of every occurrence of file >> someVar
EDIT: I didn't realize the others were integer values. For those you should still be using the >> operator.
I want to read from a file.txt that looks like this:
process_id run_time
T1 23
T2 75
Read each line and store integers of run time (tab separation)in an array
My problem now is to read the content of the file .. and how to get the integer after the tab separation?
thanks
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main ()
{
int process_id[100];
int run_time[100];
int arrival_time[100];
char quantum[50];
int switching;
char filename[50];
ifstream ManageFile; //object to open,read,write files
cout<< "Please enter your input file";
cin.getline(filename, 50);
ManageFile.open(filename); //open file using our file object
if(! ManageFile.is_open())
{
cout<< "File does not exist! Please enter a valid path";
cin.getline(filename, 50);
ManageFile.open(filename);
}
while (!ManageFile.eof())
{
ManageFile>>quantum;
cout << quantum;
}
//ManageFile.close();
return 0;
}
use C++, not C
don't use std::cin.getline, use std::getline (it works with std::string and is safer)
use a vector instead of hard-dimensioned arrays
use a vector of struct instead of "corresponding arrays"
don't use while (!stream.eof())
Here's a sample that might be helpful:
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
struct Record {
int process_id;
int run_time;
int arrival_time;
};
int main() {
std::vector<Record> records;
int switching;
std::string filename;
ifstream infile;
while (!infile.is_open()) {
cout << "Please enter your input file: ";
std::getline(std::cin, filename);
infile.open(filename); // open file using our file object
cout << "File cannot be opened.\n";
}
std::string quantum;
std::getline (infile, quantum); // skip header row
while (std::getline(infile, quantum)) {
// e.g.
Record current;
std::istringstream iss(quantum);
if (iss >> current.process_id >> current.run_time >> current.arrival_time)
records.push_back(current);
else
std::cout << "Invalid line ignored: '" << quantum << "'\n";
}
}
You can try something like this:
while (!ManageFile.eof())
{
quantum[0] = 0;
ManageFile>>quantum;
if (strcmp(quantum, "0") == 0 || atoi(quantum) != 0)
cout << quantum << endl;
}
Of course, you need to include in the head
Use function ignore from istream [http://www.cplusplus.com/reference/istream/istream/ignore/]
while (!ManageFile.eof())
{
std::string process_id;
int run_time;
ManageFile >> process_id;
ManageFile.ignore (256, '\t');
ManageFile >> run_time;
}
Using fscanf instead of ifstream can make the job a lot easier.
char str[100];
int n;
....
fscanf(FILE * stream,"%s %d", str, &n);
You will get the string in str and integer in n.
So I've been playing with code and I'm stuck with finding how to replace the line found. I'm able to find the name and add the 'new_gpa' to the section but it outputs the final result in the same file but without replacing the original score and name.
how could I remove the original line found along with the gpa? and also store the new values to the file.
cristian 2.1
rachel 3.0
name search: cristian
new file:
cristian 2.1
rachel 3.0
cristian 4.1
The code is below.
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <fstream>
#include <sstream>
#include <cstring>
using namespace std;
int main()
{
string name;
int offset;
string line;
ifstream read_file;
read_file.open("alpha.dat", std::ios_base::app);
cout << "Please enter your name: \n";
cin>> name;
if (read_file.is_open())
{
while(!read_file.eof())
{
getline(read_file,line);
if((offset = line.find(name)) != string::npos)
{
cout <<"the word has been found: \n";
//cout << line //example to display
//new code
istringstream iss ( line );
string thisname;
double gpa;
double new_gpa = 2.1;
if( iss >> thisname >> gpa)
{
if (thisname == name)
{
cout << name <<endl;
cout << gpa <<endl;
ofstream myfile;
myfile.open("alpha.dat",std::ios_base::app);
myfile << " \n" << name << " " << gpa+ new_gpa;
myfile.close();
read_file.close();
}
}
}
}
}
return 0;
}
You open file with std::ios_base::app, which means all you output operations are performed at the end of file, appending the content to the current file. But what you want to do is modify the data at the original place. So you should open file with std::ios_base::in, and function seekp can help you in the next step.