Infile incomplete type error - c++

I am building a program that takes an input file in this format:
title author
title author
etc
and outputs to screen
title (author)
title (author)
etc
The Problem I am currently getting is a error:
"ifstream infile has incomplete type and cannot be defined"
Following is the program:
#include <iostream>
#include <string>
#include <ifstream>
using namespace std;
string bookTitle [14];
string bookAuthor [14];
int loadData (string pathname);
void showall (int counter);
int main ()
{
int counter;
string pathname;
cout<<"Input the name of the file to be accessed: ";
cin>>pathname;
loadData (pathname);
showall (counter);
}
int loadData (string pathname) // Loads data from infile into arrays
{
ifstream infile;
int counter = 0;
infile.open(pathname); //Opens file from user input in main
if( infile.fail() )
{
cout << "File failed to open";
return 0;
}
while (!infile.eof())
{
infile >> bookTitle [14]; //takes input and puts into parallel arrays
infile >> bookAuthor [14];
counter++;
}
infile.close;
}
void showall (int counter) // shows input in title(author) format
{
cout<<bookTitle<<"("<<bookAuthor<<")";
}

File streams are defined in the header <fstream> and you are not including it.
You should add:
#include <fstream>

Here is my code with the previous error fixed Now I get a problem of the program crashing after I input the name of the text file.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
string bookTitle [14];
string bookAuthor [14];
int loadData (string pathname);
void showall (int counter);
int main ()
{
int counter;
string pathname;
cout<<"Input the name of the file to be accessed: ";
cin>>pathname;
loadData (pathname);
showall (counter);
}
int loadData (string pathname) // Loads data from infile into arrays
{
fstream infile;
int counter = 0;
infile.open(pathname.c_str()); //Opens file from user input in main
if( infile.fail() )
{
cout << "File failed to open";
return 0;
}
while (!infile.eof())
{
infile >> bookTitle [14]; //takes input and puts into parallel arrays
infile >> bookAuthor [14];
counter++;
}
infile.close();
}
void showall (int counter) // shows input in title(author) format
{
cout<<bookTitle<<"("<<bookAuthor<<")";
}

Related

Print User Selected Line

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

Naming a text file and the having it display a average using functions

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

Arrays and Searching Them

I am trying to finish my final debugging tonight. My problem is that I have been writing this code for a couple days and it has a few problems. Previous Post
It now compiles and does not crash, but there are a few issues with my functions not working properly (or at all).
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
string bookTitle [50];
string bookAuthor [50];
int loadData (string pathname);
int showall (int counter);
int authorSearch (string bookAuthor [50]);
int main ()
{
string pathname;
int counter=0;
char choice;
cout<<"Input the name of the file to be accessed: ";
cin>>pathname;
loadData (pathname);
showall (counter);
cout<<"\n\n\n\n What would you like to do \n (A for Author Search , T for Title Search, Q to quit):";
cin>>choice;
while (choice != 'Q' , choice != 'q')
{
if (choice == 'A', choice == 'a')
{
int authorSearch (string bookAuthor [50], char choice);
}
if (choice == 'T', choice == 't')
{
int titleSearch (string bookTitle [50], char choice);
}
}
cout<<"Press <Enter> to Exit";
cin.ignore();
cin.get();
return 0;
cout<<"Press <Enter> to Exit";
cin.ignore();
cin.get();
return 0;
}
int loadData (string pathname) // Loads data from infile into arrays
{
fstream infile;
int counter = 0;
infile.open(pathname.c_str()); //Opens file from user input in main
if( infile.fail() )
{
cout << "File failed to open";
return 0;
}
while (!infile.eof())
{
infile >> bookTitle [counter] ; //takes input and puts into parallel arrays
infile >> bookAuthor [counter];
counter++;
}
infile.close();
}
int showall (int counter) // shows input in title(author) format
{
cout<<bookTitle<<"("<<bookAuthor<<")";
}
void authorSearch (string bookAuthor [50], char choice) // Function to search Author Array
{
string target = "";
cout<<"Which author would you like to search for: "<<target; //input
for (int count = 0; count++;)
{
if(bookAuthor[count] == target) //tests input against array and outputs result
{
cout<<bookTitle[count]<<bookAuthor[count];
}
}
}
void titleSearch (string bookTitle [50], char choice) // Function to Serch Title Array
{
string target = "";
cout<<"Which author would you like to search for: "<<target; //input
for (int count = 0; count++;)
{
if(bookAuthor[count] == target) //tests input against array and outputs result
{
cout<<bookTitle[count]<<bookAuthor[count];
}
}
}
Latest Version , no major improvements. I am having trouble getting the functions to work after the menu selection. ShowAll seems to work but outputs hex. Thanks again everyone!
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
string bookTitle [50];
string bookAuthor [50];
int loadData (string pathname);
int showall (int counter);
void authorSearch (string bookAuthor [50]);
void titleSearch (string bookTitle [50]);
int main ()
{
string pathname;
int counter=0;
char choice;
cout<<"Input the name of the file to be accessed: ";
cin>>pathname;
loadData (pathname);
showall (counter);
cout<<"\n\n\n\n What would you like to do \n (A for Author Search , T for Title Search, Q to quit):";
cin>>choice;
while (choice != 'Q'|| choice != 'q')
{
if (choice == 'A'|| choice == 'a')
{
void authorSearch (string bookAuthor [50], char choice);
}
if (choice == 'T'|| choice == 't')
{
void titleSearch (string bookTitle [50], char choice);
}
}
cout<<"Press <Enter> to Exit";
cin.ignore();
cin.get();
return 0;
}
int loadData (string pathname) // Loads data from infile into arrays
{
fstream infile;
int counter = 0;
infile.open(pathname.c_str()); //Opens file from user input in main
if( infile.fail() )
{
cout << "File failed to open";
return 0;
}
while (!infile.eof())
{
infile >> bookTitle [counter] ; //takes input and puts into parallel arrays
infile >> bookAuthor [counter];
counter++;
}
infile.close();
}
int showall (int counter) // shows input in title(author) format
{
cout<<bookTitle<<"("<<bookAuthor<<")";
}
void authorSearch (string bookAuthor [50], char choice) // Function to search Author Array
{
string target = "";
cout<<"Which author would you like to search for: "<<target; //input
for (int count = 0; count++;)
{
if(bookAuthor[count] == target)
{
cout<<bookTitle[count]<<bookAuthor[count];
}
}
}
void titleSearch (string bookTitle [50], char choice) // Function to Serch Title Array
{
string target = "";
cout<<"Which title would you like to search for: "<<target; //input
for (int count = 0; count++;)
{
if(bookAuthor[count] == target) //tests input against array and outputs reults
{
cout<<bookTitle[count]<<bookAuthor[count];
}
}
}
The comma operator should be replaced with logical and or or, && and || respectively. See uses of the comma operator. Also, authorSearch is a void function. If you want to call authorSearch, simple write authorSearch(...) instead of int authorSearch(...).
Additionally, you need to make sure your prototypes are consistent with your implementations. int authorSearch (string bookAuthor [50]) is not the same as void authorSearch (string bookAuthor [50], char choice). You've mismatched their types and their parameters.
1) The showall() function outputs hex because you can't display arrays that way, you need some kind of loop. It's just printing the starting address of each array.
2) In your search functions you never read the target string from the user.
3) These for() loops will never execute:
for (int count = 0; count++;)
{
...
}
You set count to 0 and then test the value before incrementing. The test fails and the loop body isn't executed.
4) Take care when you fix the for() loops. I don't see any tests to prevent using an invalid index past the (hardcoded) size of your arrays.

How to fix Error that leads to program Crash

For some reason or another I cannot figure out why the data when opened does not get put into arrays and the program crashes. I have searched around for a answer to no avail. I get the feeling I will be posting a here a few more times before I finish this program!
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
string bookTitle [14];
string bookAuthor [14];
int loadData (string pathname);
void showall (int counter);
int main ()
{
int counter;
string pathname;
cout<<"Input the name of the file to be accessed: ";
cin>>pathname;
loadData (pathname);
showall (counter);
cout<<"Press <Enter> to Exit";
cin.ignore();
cin.get();
return 0;
}
int loadData (string pathname) // Loads data from infile into arrays
{
fstream infile;
int counter = 0;
infile.open(pathname.c_str()); //Opens file from user input in main
if( infile.fail() )
{
cout << "File failed to open";
return 0;
}
while (!infile.eof())
{
cout<<"File Opened"; // I get the "File Opened" text and then a crash
infile >> bookTitle [14] ; //takes input and puts into parallel arrays
infile >> bookAuthor [14];
cout<<"Data Put in Arrays";
counter++;
}
infile.close();
}
void showall (int counter) // shows input in title(author) format
{
cout<<bookTitle<<"("<<bookAuthor<<")";
}
Edit: The assignment is to take a file with names in a format such as title
author
title
author
Then it must output the arrays to screen in a title(author) format.
After this I must make it a looping program so a search can be chosen of one of the arrays and returns the entry in a title(author) format.
Here is how the code stands now;
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
string bookTitle [50];
string bookAuthor [50];
int loadData (string pathname);
int showall (int counter);
int main ()
{
string pathname;
int counter=0;
cout<<"Input the name of the file to be accessed: ";
cin>>pathname;
loadData (pathname);
showall (counter);
cout<<"Press <Enter> to Exit";
cin.ignore();
cin.get();
return 0;
}
int loadData (string pathname) // Loads data from infile into arrays
{
fstream infile;
int counter = 0;
infile.open(pathname.c_str()); //Opens file from user input in main
if( infile.fail() )
{
cout << "File failed to open";
return 0;
}
while (!infile.eof())
{
infile >> bookTitle [counter] ; //takes input and puts into parallel arrays
infile >> bookAuthor [counter];
counter++;
}
infile.close();
}
int showall (int counter) // shows input in title(author) format
{
cout<<bookTitle<<"("<<bookAuthor<<")";
return 0;
}
A Quick problem I see is:
infile >> bookTitle [14] ;
infile >> bookAuthor [14];
Is incorrect, What you need is:
infile >> bookTitle[counter];
infile >> bookAuthor [counter];
Also,
The counter variable declared in main() and in loadData() are two different variables. The one declared in main()is never iniitalized at all.
There are many problems with this code.
Main problem
These lines write only into 14th elements of the arrays
infile >> bookTitle [14] ; //takes input and puts into parallel arrays
infile >> bookAuthor [14];
In order to fill the entire array you need to use the counter variable for index:
infile >> bookTitle [counter] ; //takes input and puts into parallel arrays
infile >> bookAuthor [counter];
BTW: if array's size is 14 then the maximum index is 13. So you can't access an element with index 14. And that's probably causes the crash.
Other problems I noticed
counter in main() is not initialized
showall() function takes an argument but does not use it, which is probably the index.
showall() call in main() probably needs to be in a loop, to show all elements.

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.