Print User Selected Line - c++

In the program, each line of the text file is read into an array. I need to have the user input a line number, then that line of the text file will be printed. How is this done? Thanks!
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void file()
{
string array[2990];
short loop=0;
string line;
ifstream myfile ("weblog.txt");
if (myfile.is_open())
{
while (! myfile.eof() )
{
getline (myfile,line);
array[loop] = line;
cout << array[loop] << endl;
loop++;
}
myfile.close();
}
else cout << "file not available";
}
int main ()
{
file();
return 0;
}

I am assuming that you wanted to print the line that the user inputs to so for example if user input line 3, then you will print the third line. If that is so, the following will work.
#include<bits/stdc++.h>
using namespace std;
struct OpenFailException : public exception{
const char* what() const throw (){
return "Cannot open file";
}
};
class FileIO{
public:
FileIO(const string& Path,const bool &ToMemory){
_Path = Path;
_File.open(_Path);
_Load = ToMemory;
if(_File.is_open()){
if(ToMemory){
while(!_File.eof()){
string Input;
getline(_File, Input, '\n');
_Memory.push_back(Input);
}
}
}
else{
cout<<"File Err";
exit;
}
}
string Data(const int &Line){
return _Memory[Line - 1];
}
private:
string _Path;
fstream _File;
vector <string> _Memory;
bool _Load;
};
int main(){
FileIO A("CMS.cpp", true);
int Input;
cin>>Input;
cout<<A.Data(Input);
}
you can either turn the array into a global variable or you can simply structure a new class for it. Here, I try to abstract the codes for you.

To take in input from an user, what you can do is use the cin function. Below is the reference website.
http://www.cplusplus.com/reference/iostream/cin/
Using the cin function you can direct the userinput into a variable, and use that variable to access your array.
Here is an example of the code, assuming your result is zero-indexed (i.e. array[0] is equal to line number 0), if you want your index to start at 1 (i.e. array[0] is equal to line number 1), then just do array[lineNum-1]:
int lineNum;
cout << "Please enter a line number";
cin >> lineNum;
cout << array[lineNum];

Related

streams as function arguments, c++

Can someone tell me what is wrong in this code? Particularly the function longestLine.
When I run the code without that funcion (only using the inside of it) the program runs with no problems, but when I do it with the function it does not compile.
I dont understand the error the compiler gives but I think it has something to do with the argument of the funcion.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
string longestLine(ifstream infile);
string promptUserForFile(ifstream & infile, string prompt="");
int main() {
ifstream infile;
promptUserForFile(infile);
cout << "The longest line of the file is: " << endl;
cout << longestLine(infile);
return 0;
}
string promptUserForFile(ifstream & infile, string prompt) {
while (true) {
cout << prompt;
string filename;
getline(cin, filename);
infile.open(filename.c_str());
if (!infile.fail())
return filename;
infile.clear();
cout << "Unable to open that file. Try again." << endl;
if (prompt == "")
prompt = "Input file: ";
}
}
string longestLine(ifstream infile) {
int length = 0;
string longest_line;
string line;
while (getline(infile, line)) {
if (line.length() > length) {
length = line.length();
longest_line=line;
}
}
return longest_line;
}
I think you should pass ifstream by reference
string longestLine(ifstream& infile);
ifstream derive from ios_base, the copy constructor of stream is deleted: because streams are not copyable.
If you pass ifstream by value, the compiler will try to call the copy constructor of ifstream when you call longestLine, the compiler will definitely complain this error.
cppreference: basic_ifstream

replacing string based on user input c++

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;
}
}

How to print related lines in c++?

In my code, I want to have a function called search that goes through each line in a .txt file and prints out the line if the first number in the sentence contains the number given by the user. For example:
Format of the .txt file:
Each word is separated by a space.
17 35 "door"
40 19 "wall"
17 34 "car"
3 9 "window"
Output:
Enter a desired number:17
17 35 "door"
17 34 "car"
How would I go about doing this? In java, I would normally use the .split() function to split the sentence into a list then see if the first index matches the desired input, but I can't find how to do this, and what I can find, I don't understand. My attempts are listed below, but if you have better methods, please list them...I'm still learning. My attempt are located under the search function below:
#include<iostream>
using std::cerr;
using std::endl;
#include <list>
using namespace std;
#include <fstream>
using std::ofstream;
#include <cstdlib> // for exit function
#include <sstream>
using namespace std;
class Item{
//Access specifer
public: //todo, private with get/set
string item;
int meshNum;
int mNum;
//constructor
public:
Item( string item,int mNum, int meshNum ){
this->item=item;
this-> mNum= mNum;
this-> meshNum= meshNum;
}
//Memeber functions
public:
string getItem(){
return item;
}
void setItem(string item){
this->item = item;
}
int getMeshNum(){
return this->meshNum;
}
void setMeshNum(int meshNum){
this->meshNum= meshNum;
}
int getMNum(){
return this->mNum;
}
void setMNum(int mNum){
this-> mNum= mNum;
}
};
//____________________________________________
class materialList{
// Access specifer
private:
list <Item> items;
//constructor
public:
/* materialList(){
this->items = new list<Item>;
} */
// Memeber fucntions
public:
void add(Item &item)
{
items.push_back(item);
}
//print my list
void Print()
{
ofstream outdata; // outdata is like cin
outdata.open("example2.dat"); // opens the file
if( !outdata ) { // file couldn't be opened
cerr << "Error: file could not be opened" << endl;
exit(1);
}
for (auto &i : items)
outdata << i.getItem() << " "<<i.getMeshNum()<< " "<<i.getMNum()<<endl;
outdata.close();
}
void search(ifstream& inFile){ //this function is where I need help on =<
string line,word;
int materialNum;
istringstream iss;
cout<< "Enter a material number:";
cin>>materialNum;
int**arr= (int**)malloc(20*sizeof(int*));
int i=0;
while(!inFile.eof()){
// read line by line from the file
getline(inFile,line);
if(inFile.good()){
// read word by word in line and place words in arr
iss.clear(); // clear out state
iss.str(line);
iss>> word;
arr[i]=word;
}
if (word==cin){
cout>>line;
}
}
}
};
int main(){
bool value = true;
string objectName;
int Mnum;
int Meshnum;
materialList ml; //(list<Item> test);
while(value){
cout<< "Enter Object name: ";
cin>> objectName;
cout<<" Enter M#: ";
cin>> Mnum;
cout<<"Enter Mesh#: ";
cin>> Meshnum;
//Item second= Item(objectName,Mnum,Meshnum);
ml.add(Item(objectName,Mnum,Meshnum));
ml.Print();
}
//Item test= Item("door",34,50);
//itemList =
//ml.add(test);
//ml.Print();
}
Errors:
material_characterizationf.cpp:105:20: error: assigning to 'int *' from incompatible type 'std::__1::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >')
arr[i]=word;
^~~~
material_characterizationf.cpp:134:17: error: non-const lvalue reference to type 'Item' cannot bind to a temporary of type 'Item'
ml.add(Item(objectName,Mnum,Meshnum));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I know the first error comes from my failed attempts, but I have no idea where the second error came from. The code was working fine until I tried to add a search function.
In your search function, I don't think you need to use the arr array as not only does it cause memory leak due to it not being freed at the end of the function but also it doesn't serve any purposes in the function. You can simply parse the first argument of the input lines from the file as int type into the word variable by setting the word variable as int type instead of string.
That way you can use word to check if it is equal to the materialNum (not equal to cin in your original code as it is an istream object and can't be compared with an integer) input by the user at line (cin >> materialNum;). If word is equal to materialNum, then you can print out the file line using out << line << ends;.
void search(ifstream& inFile){
string line;
int word;
int materialNum;
istringstream iss;
cout << "Enter a material number:";
cin >> materialNum;
int i=0;
while(!inFile.eof()){
// read line by line from the file
getline(inFile,line);
if(inFile.good()){
// read word by word in line and place words in arr
iss.clear(); // clear out state
iss.str(line);
iss >> word;
}
if (word == materialNum){
cout << line << endl;
}
}
}
Update: If you know the file name, you can create a ifstream object (inFile) to open it, and then pass it as an argument to your search function. For example, you can do something like this in your main function
string filename = "example2.dat";
ifstream inFile;
inFile.open(filename, std::ifstream::in);
ml.search(inFile);

Reading from input file and storing in array c++

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.

How to get the whole line where a given word is and store it in a variable?

i am a beginner in the C++ world, i need to get the whole line where a given word is and store it into a variable.
my TXt file has this structure :
clients.txt
085958485 Roland Spellman rolandl#gmail.com
090545874 KATHLEEN spellman kathleen1#hotmail.com
056688741 Gabrielle Solis desperate#aol.com
so the program requests to the user to enter the id of the person, the id is always the first number or word in the line.
the user enters then
090545874
the program has to be able to find the 090545874 in the text file and then get the whole line where it is stored into a variable.
i know how to find a word in a text file but i don't know how to get the whole line into a variable. so at the end my variable has to store
variable = 090545874 KATHLEEN spellman kathleen1#hotmail.com 4878554
after that, i am able to delete the entire line or record.
i use this code to enter the data into the txt file
struct person{
char id[10];
char name[20];
char lastname[20];
char email[10];
} clientdata;
ofstream clientsfile;
clientsfile.open ("clientes.dat" , ios::out | ios::app);
if (clientsfile.is_open())
{
cout<<" ENTER THE ID"<<endl;
cin>>clientdata.id;
clientsfile<<clientdata.id<<" ";
cout<<" ENTER THE NAME"<<endl;
cin>>datoscliente.name;
clientsfile<<clientdata.name<<" ";
cout<<" ENTER THE LAST NAME"<<endl;
cin>>clientdata.lastname;
clientsfile<<clientdata.lastname<<" ";
cout<<" ENTER THE LAST EMAIL"<<endl;
cin>>clientdata.email;
clientsfile<<clientdata.email<<" ";
then i request to the eu to enter the id
and what i need to do is not to find the id only, it's to get the whole line where the id is
so if the user enters 090545874 , i need to find it in the text file , but i need to get teh whole line in this case 090545874 KATHLEEN spellman kathleen1#hotmail.com
so i need to store that into a new variable
string newvariable;
newvariable = 090545874 KATHLEEN spellman kathleen1#hotmail.com
To read files one line at a time, you can use the std::getline function defined in the <string> header (I'm assuming you're using the fstream library as well):
#include <fstream>
#include <string>
int main(int argc, char** argv) {
std::ifstream input_file("file.txt");
std::string line;
while (true) {
std::getline(input_file, line);
if (input_file.fail())
break;
// process line now
}
return 0;
}
What's nice about the function std::getline, though, is that it allows for this much cleaner syntax:
#include <fstream>
#include <string>
int main(int argc, char** argv) {
std::ifstream input_file("file.txt");
std::string line;
while (std::getline(input_file, line)) {
// process line now
}
return 0;
}
thank all of you for your answers, I finally figured it out , I used this function :
bool mostshow(int option, string id)
{
if (option== 2 && id== id1)
return true;
if (option== 3 && id== id1)
return true;
return false;
}
and this other one
void showline(string field1, string field2, string field3, string field4, string field5, string field6, string field7)
{
string store;
store = field1+" "+field2+" "+field3+" "+field4+" "+field5+" "+field6+" "+field7;
cout<<endl;
}
and then in the main
ifstream myfile("clients.dat", ios::in);
if (!myfile)
{
cerr <<" CANNOT OPEN THE FILE!!"<<endl;
exit(1);
}
option=2;
myfile >> field1 >> field2 >> field3 >> field4 >>field5 >> field6 >> field7;
while (!myfile.eof())
{
if (mostshow(option, id))
{
showline(field1, field2, field3, field4, field5, field6, field7);
}
myfile >> field1 >> field1 >> field1 >> field1 >>field1 >> field1 >> field1;
}
myfile.close();
option variable is part of a switch statement which asks if you want to delete or modify the record, 2 means modify , 3 delete
You didn't say how you're reading the file, but the fgets function will do what you want.
Use ifstream, getline and unordered_map:
#include <fstream>
#include <string>
#include <sstream>
#include <exception>
#include <unordered_map>
using namespace std;
ifstream infile("mytextfile.txt");
if (!infile) {
cerr << "Failure, cannot open file";
cin.get();
return 0;
}
unordered_map<string, string> id2line;
string id, line;
while (getline(infile, line)) {
stringstream strstm(line);
strstm >> id;
id2line[id] = line;
}
Now you can do
cout << "Please enter an id: " << endl;
string id;
cin >> id;
try {
// unordered_map::at throws an std::out_of_range exception when the key doesn't exist
string line = id2line.at(id);
cout << "Info:\n " << line << endl;
} catch (out_of_range& e) {
cout << "No information by that id." << endl;
}
You could create a structure and have the structure read in its data by overloading the stream extraction operator:
struct Record
{
unsigned int id;
std::string first_name;
std::string last_name;
std::string email_addr;
friend std::istream& operator>>(std::istream& input, Record& r);
};
std::istream& operator>>(std::istream& input, Record&r)
{
input >> r.id;
input >> r.first_name;
input >> r.last_name;
getline(input, r.email_addr);
return input;
}
Edit 1:
Usage:
ifstream input_file("mydata.text");
Record r;
std::map<unsigned int, Record> container;
while (input_file >> r)
{
unsigned int id = r.id;
container[id] = r;
}
As far as storage is concerned look up the std::map structure and copy the ID field and use it as the key.
I still suggest that this work is a better candidate for a database or spreadsheet.