Unable to opening file with ifstream - c++

I'd like to get some assistance regarding the following line of code.
for the function constructArray,I'm unable to run it as shows the !aFile as true message but I have no idea what's the error.
Really appreciative of your assistance
Also how do I create inFile fileName with .txt,i've tried indentation with +".txt" but due to the file type in the argument i'm unable to do so.
Compiler run image: https://imgur.com/a/wkGwL
using namespace std;
enum NumType {Odd, Even};
struct Number
{
int no;
NumType type;
int oddDigits;
int evenDigits;
int sumDigits;
int noDigits;
};
// Create inFile data file with certain number of integers which are randomly generated
void constructInfile (fstream& aFile, char fileName[]);
// Read data from infile txt file and transfer to array of numbers
int constructArray (fstream& aFile,const char fileName[], Number ran[]);
/*
void processArray (Number [ ], int);
// Transfer information from array and store into output file called outfile txt with specific information format
void arrayToOutfile (fstream&, char [ ], Number [ ], int);
*/
const int MAX = 50;
int main()
{
srand(time(NULL));
fstream aFile;
char fileName [MAX];
cout << "Enter designated file name to be created" << endl;
cin >> fileName;
constructInfile (aFile,fileName);
Number ran[MAX];
int recNo = constructArray(aFile,fileName,ran);
cout << recNo << " of records transferred" << endl;
}
// Create inFile data file with certain number of integers which are randomly generated
void constructInfile (fstream& aFile,char fileName[]){
aFile.open(fileName, ios::out);
if(aFile.fail()){
cout << "File open unsuccessful" << endl;
aFile.close();
exit(1);
}
cout << "Begin creation of " << fileName << " file" << endl << endl;
int size = rand()%51+50;
for(int a = 0;a < size;a++){
aFile << rand()%1000+1 << endl;
}
cout << fileName << " file successfully created" << endl;
}
// Read data from infile txt file and transfer to array of numbers
int constructArray (fstream& aFile,const char fileName[], Number ran[]){
aFile.open (fileName, ios::in);
if (!aFile)
{
cout << fileName << " failed to open" << endl;
aFile.close ();
return 0;
}
cout << "Begin from " << fileName << " to array" << endl;
int i = 0;
char tabKey;
while (aFile >> ran[i].no)
{
aFile.get (tabKey); // read and discard
i++;
}
aFile.close ();
cout << fileName << " to array done" << endl;
return i;
}

You are opened a file in ios::out mode and never closed it!
Again you are trying to open the same file in ios::in mode. How a file could be opened twice in 2 different mode without properly closing the fstream?
You need to close the filestream inside the function constructInfile()!!!

You have opened the file but forget to close it. At the end of both of the functions, close the aFile. That should solve the problem.

Related

readFile function not working on second iteration with different argument - c++

I've written a readFile function for a project I'm working on. I call it once, load in a file and read in it's contents - works fine
However, when I try to load it a second time, attempting to change the file name - it loads it in, saves it to a static string 'path' that I access in a different function - but then the function is not printing the data
The question is, how do I change the file name, and read it in successfully on the second iteration? The part that has me stumped is that it works once, but not twice
Ive attempted to use cin.ignore(); cin.clear(); cin.sync() on the second iteration of fileName function - but none of them allow a separate file to be read successfully.
Minimum Reproducible Example:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <vector>
#include <sstream>
#include <iomanip>
#include <iostream>
using namespace std;
static string path;
string opt;
void readFile();
int fileName();
void menu() { // put in while loop - while True
cout << "----------------------" << endl;
cout << "R(ead) -" << "Read File" << endl;
cout << "F(ile) -" << "Set Filename" << endl;
cout << "\nPlease select from the above options" << endl;
cin >> opt;
cout << "\nInput entered: " << opt << endl;
if (opt == "R") {
readFile();
}
if (opt == "F") {
fileName();
}
}
void readFile() { // doing this twice
ifstream readFile;
readFile.open(path);
if (!readFile.is_open()) {
cout << "Could not read file" << endl;
}
string str;
int i = 0;
while (getline(readFile, str))
{
if (str[0] != '/')
{
cout << "DEBUG: Line is - " << str << endl;
}
}
readFile.clear();
readFile.close();
menu();
}
int fileName() {
cout << "File path: ";
if (path != "") {
cin.ignore();
cin.clear();
cin.sync();
}
getline(cin, path);
ifstream file(path.c_str());
if (!file) {
cout << "Error while opening the file" << endl;
return 1;
}
cout << "(File loaded)" << endl;
cout << "Path contains: " << path << endl;
file.clear();
file.close();
menu();
}
int main()
{
fileName();
}
Sample text, saved as txt file and read in using path:
Data1.txt
// standard test file
123,Frodo inc,2006, lyons,"1,021,000.16",0.0,
U2123,Sam Inc,2006, lyons,"21,600.00",13.10,123
A721,Merry Inc,2604, Kingston,"21,600.10",103.00,
U2122,Pippin Inc,2612, reid,"21,600.00",0
U1123,Huckelberry corp,2612, Turner,"21,600.00",13.10,
Data2.txt
7101003,Mike,23 boinig road,2615,48000,12000,0
7201003,Jane Philips,29 boinig cresent,2616,47000,12000,0
7301003,Philip Jane,23 bong road,2615,49000,000,0
7401004,Peta,23 bong bong road,2615,148000,19000,0
7101205,Abdulla,23 Station st,2615,80000,21000,0
The problem comes from reading in one, and trying to read in the other after the first has been executed.
Enter Filename
Hit Readfile
Return to menu, hit Set Filename
Change to Data2.txt
Readfile again. Not working
My tutor told me "That's not how functions work in c++" but didn't elaborate further, and is unavailable for contact.
In general, do not use global variables. The path variable should be passed as a parameter, not kept as a global variable altered between function calls, as this leads to many side effects and is the source of countless bugs. See the following refactoring:
void menu() { // put in while loop - while True
while(true)
{
//Keep this as a local variable!
std::string opt;
std::string filename;
cout << "----------------------\n";
cout << "R(ead) -" << "Read File\n";
cout << "F(ile) -" << "Set Filename\n";
cout << "\nPlease select from the above options\n";
cin >> opt;
cout << "\nInput entered: " << opt << '\n';
if (opt == "R") {
readFile(filename);
}
if (opt == "F") {
filename = getFileName();
}
}
}
void readFile(const std::string & filename) {
ifstream readFile;
readFile.open(filename);
if (!readFile.is_open()) {
cout << "Could not read file " << filename << '\n';
}
string str;
int i = 0;
while (getline(readFile, str))
{
if (str[0] != '/')
{
cout << "DEBUG: Line is - " << str << '\n';
}
}
readFile.close();
//just return to get back to menu
return;
}
std::string getFileName() {
cout << "File path: ";
std::string path;
getline(cin, path);
ifstream file(path.c_str());
if (!file) {
cout << "Error while opening the file" << '\n';
//Instead of returning an error code use an exception preferably
}
cout << "(File loaded)" << '\n';
cout << "Path contains: " << path << '\n';
file.close();
return path;
}
Other notes:
Ideally, do input in output in just one function, not all three as it gets confusing exactly what each function is responsible for.
If you want something to hold a file and print the contents, you can use an class.
The file is checked if it is openable twice, not really any reason to do this just delegate that responsibility to one function.
One of the best things about C++ is RAII and deterministic lifecycles for objects and primitives - use it!! Do not give everything a long life with global variables - use smart parameters and return values instead.

function to stream certain name and number from txt file

i made a file named clientFile.txt
the file contain this clientFile.txt. Content:
abcd abcd 123 1607325695
A AI 123 1607327861
the function below should show the content of the text file when the function called.
void displayFile()
{
string str1;
string str2;
string fileN = "clientFile.txt";
ifstream myfilein;
myfilein.open("clientFile.txt");
double balance;
int numAct = 0;
time_t transTime;
if(!myfilein){
cerr << "FIle could not be opened" << endl;
exit(1);
}
while(myfilein >> str1 >> str2 >> balance >> transTime){
cout << setw(15) << str1 << ' ' << setw(15) << str2 << ' '
<< setw(7) << balance << " " << ctime(&transTime);
numAct++;
}
myfilein.close();
cout << "Number of records in the file " << fileN << ": " << numAct << endl;
}
but when i call it on this int main:
int main(){
ofstream myfileout;
ifstream myfilein;
string firstName,lastName;
int i=0;
string FN[1000],LN[1000];
double actBalance,AB[1000];
time_t currentTime,CT[1000];
myfilein.open ("clientFile.txt");
void displayFile();
if(myfilein.fail()){
cout<<"Creating new files"<<endl;
myfileout.open ("clientFile.txt",ios::out);
myfileout.close();
exit(1);
}
while(myfilein>>firstName>>lastName>>actBalance>>currentTime){
FN[i]=firstName;
LN[i]=lastName;
AB[i]=actBalance;
CT[i]=currentTime;
i++;
}
myfileout.open("clientFile.txt",ios::app);
cout<<"Enter first name, last name, and balance:"<<endl;
while(cin>>firstName>>lastName>>actBalance){
createRecord(myfileout, firstName,lastName,actBalance);
}
void displayFile();
myfileout.close();
}
it didnt show me any of the file content.
can you guys help me?
im using dev c++ with TDM-GCC 4.9.2 64-bit release
In last lines of main() you just need to change
void displayFile();
to
displayFile();
Because with void you're declaring a function, not calling it.

Output from file using function

the title says it all
This is my code:
I have a class called House, where i define the values.
class HOUSE
{
public:
int id;
string 1;
string 2;
string 3;
int an;
};
template<class Type>
class table
{
public:
vector<Type> V;
//double inceput;
//double sfirsit;
//int comparatii;
//int interschimbari;
public:
table();
void print();
void liniar();
};
template<class Type>
table<Type>::table()
{
ifstream file("file.txt");
ifstream file1("file1.txt");
if (file.fail() || file1.fail())
{
cerr << "Eroare la deschiderea fisierului!" << endl;
_getch();
exit(1);
}
HOUSE* value = new HOUSE;
while (!file.eof() || file1.fail())
{
file >> value->id;
file >> value->tara;
file >> value->brand;
file >> value->culoare;
file >> value->an;
this->V.push_back(*value);
}
file.close();
}
The print function for the values
template<class Type>
void table<Type>::print()
{
cout << endl << setw(50) << "AFISAREA DATELOR" << endl;
cout << setw(5) << "Id" << setw(15) << "1" << setw(20) << "2" << setw(17) << "3" << setw(20) << "an" << endl << endl;
for (int i = 0; i < this->V.size(); i++)
{
cout << setw(5) << this->V.at(i).id << setw(15)
<< this->V.at(i).1<< setw(17)
<< this->V.at(i).2<< setw(17)
<< this->V.at(i).3<< setw(25)
<< this->V.at(i).an << endl;
}
cout << endl << "Dimensiunea tabelului n= " << V.size() << endl;
}
{
file >> value->id;
file >> value->1;
file >> value->2;
file >> value->3;
file >> value->an;
this->V.push_back(*value);
}
file.close();
}
in main
int main() {
table<MOBILE>* file = new table<MOBILE>();
table<MOBILE>* file1 = new table<MOBILE>();
file ->print();
file1 ->print();
This is full code as requested.
Need make it somehow print the data from file1 and file2 .
thx
The problem is idk if called right. Because
file ->print();
file1 ->print();
both print data from the file only
There are no errors at all
There's lots and lots wrong with your code. but I'm going to ignore that and just answer what I think is your actual question.
You want two table objects, one of which reads from file.txt and the other reads from file1.txt. To do that you should pass the file name into the table::table constructor, so it knows which file to read from. Like this
template<class Type>
class table
{
...
public:
table(const char* filename); // constructor takes filename parameter
...
};
template<class Type>
table<Type>::table(const char* filename)
{
ifstream file(filename); // open filename
if (file.fail())
...
int main() {
table<MOBILE>* file = new table<MOBILE>("file.txt"); // read from file.txt
table<MOBILE>* file1 = new table<MOBILE>("file1.txt"); // read from file1.txt
file ->print();
file1 ->print();
}

C++ Function to Search for A Numeric Value in a File

I have an assignment where I must create a function that takes a filename as a parameter, opens the file, asks a user to enter a value to be searched for, and then searches the file for that value. The file I was given to use for this assignment is a file with a list of revenue and expense values. I have tried just about everything and keep receiving the "value not found" prompt even when I enter a value that i know is in the file.
The code is
void numberSearch(string fileName)
{
string searchVal;
cout << "\nWhat value would you like to search for?\n";
cin.ignore();
getline(cin, searchVal);
ifstream file; //create input file object that will be read from
file.open(fileName); //"ifstream file (fileName)"
if (!file)
{
cout << "\nUnable to open file.\n";
exit(1);
}
string words;
int curLine = 0; //file line counter
while (getline(file, words))
{
++curLine; //counts each line in the file
if (words.find(searchVal) != string::npos)
{
cout << "\nLine " << curLine << " contains " << searchVal << endl;
file.close();
return;
}
else
{
cout << "\nThe value " << searchVal << " was not found.\n";
file.close();
return;
}
}
}
Any help is greatly appreciated
You need to put the else part out side of while loop. Otherwise your function will only search for the first line.
I was bored so I decided to do it too. I'll post mine, even though its already solved. (upvoted the question for the fun of solving ;) )
using namespace std;
int testfile(string filename, int &line, int &character)
{
ifstream is(filename, std::ios::in);
if (!is.is_open()) return 1; //1 = no file
cout << "Search for what value?" << endl;
string value;
cin >> value;
string buf;
while (getline(is,buf))
{
++line;
if (buf.find(value) != buf.npos)
{
character=buf.find(value); //the part that got lost in edit
return 0; //value found, returning 0
}
}
return 2; //return 2 since no value was found
}
which is called under main():
main()
{
int line=0; //what line it is
int character=0; //what character on that line
int result=testfile("test.txt", line, character); //debug+passing as reference
if (result == 1)cout << "could not find file" << endl;
if (result == 2)cout << "could not find value" << endl;
if (result == 0)
cout << "found at line# " << line << " character# " << character << endl;
return 0;
}
Passing values by reference lets us make use of them in our original scope. Therefore the function can both give errors for debugging, and allow useful results for our scopes purpose.
Closing the fstream is not necessary, as leaving the scope will take care of that for us: see here
Hehe, almost like being at school ;)

How to seek and read from binary file?

I'm still new to advance file and structures. I'm just having trouble figuring out how to seek and read specific records from a file. and how to display the information of a specific record through it's record number?
#include <iostream>
#include <fstream>
using namespace std;
struct catalog
{
char title[50];
char author[50];
char publisher[30];
int yearpublish;
double price;
};
void showRec(catalog);
long byteNum(int);
int main()
{
catalog book;
fstream fbook("book.dat",ios::in|ios::binary);
if (!fbook)
{
cout <<"Error opening file";
return 0;
}
//Seek and read record 2 (the third record)
showRec(book); // Display record 2
//Seek and read record 0 (the first record)
showRec(book); // Display record 0
fbook.close();
return 0;
}
void showRec(catalog record)
{
cout << "Title:" << record.title << endl;
cout << "Author:" << record.author << endl;
cout << "Publisher name:" << record.publisher << endl;
cout << "Year publish:" << record.yearpublish << endl;
cout << "Price:" << record.price << endl << endl;
}
long byteNum(int recNum)
{
return sizeof(catalog) * recNum;
}
Please Help. Thank you.
The C++ istream methods you need for this are seekg and read.
// Seek and read record 2
fbook.seekg(byteNum(2));
fbook.read((char*)&book, sizeof(book));