C++ Program crashes while reading from file using fstream fin - c++

Final project for programming class due tomorrow, any help appreciated, program crashes in this module, after accepting file name. By crash I mean it outputs "This application has requested runtime to terminate it in an unusual way" and then the usual windows "CotD.exe has stopped working":
void load(vector<Fish>& stock)
{
char c;
do {
cout << "Welcome to Catch of The Day, enter (f) to choose a file to load from, otherwise enter anything else to load from default file.\n";
cin >> c;
if (c == 'f' || c == 'F')
{
cout << "Enter file name\n";
cin >> file;
}
ifstream fin(file.c_str());
if (fin.fail())
{
cout << "Could not open " << file << " Check the directory location of CotD.exe and try again\n";
}
else
{
while (!fin.eof())
{
Fish f;
string blank;
fin >> f.amt;
fin >> f.prc;
fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
getline(fin, blank);
stock.push_back(f);
}
fin.close();
break;
}
} while (true);
}
EDIT other relevant code:
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
using namespace std;
//
string file = "default.txt"; //Global variable used to store name of save file.
//It is global so that load() and save() can both access it.
struct Fish
{
string type;
double amt;
double prc;
double val;
};
void addType(vector<Fish>&);
void editStock(vector<Fish>&);
void sortBy(vector<Fish>&);
void sortAsc(vector<Fish>&,char);
void sortDesc(vector<Fish>&,char);
void display(vector<Fish>&);
int search(vector<Fish>&);
void save(vector<Fish>&);
void load(vector<Fish>&);
string getType();
int dispType(string,vector<Fish>&);
int find(string,vector<Fish>&);
double getAmt();
void delType(string,vector<Fish>&);
void menu(vector<Fish>&);
double getPrc();
int main(){
std::vector<Fish> stock;
load(stock);
menu(stock);
save(stock);
cout<<endl<<endl
<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
<<"|Thank you for using Catch of the Day|\n"
<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
system("Pause");
return 0;
}
I recently wrote this program which seems very similar to me, and ran perfectly I can't see the difference:
void load(vector<string>& names)
{
string file, name, bad;
while (true)
{
cout << "Input file name\n";
getline(cin, file);
ifstream fin(file.c_str());
if (fin.fail())
{
cout << "Could not open " << file << ", try again.\n";
}
else break;
}
ifstream fin(file.c_str());
while (!fin.eof())
{
fin >> bad;
fin >> name;
cout << "\"" << name << "\"" << endl;
}
system("Pause");
fin.close();
ifstream fin(file.c_str());
while (!fin.eof())
{
getline(fin, name);
names.push_back(name);
}
system("Pause");
fin.close();
cout << "Names added to list\n";
}

I've edited your code, this is what I got:
void load(vector<Fish>& stock)
{
char c;
do {
cout << "Welcome to Catch of The Day, enter (f) to choose a file to load from, otherwise enter anything else to load from default file.\n";
cin >> c;
if (c == 'f' || c == 'F')
{
cout << "Enter file name\n";
cin >> file;
}
ifstream fin(file.c_str());
if (fin.fail())
{
cout << "Could not open " << file << " Check the directory location of CotD.exe and try again\n";
}
else
{
Fish f;
string blank;
if (fin>>f.amt)
{
if (fin>>f.prc)
{
getline(fin,blank);
stock.pushback(f);
}
}
fin.close();
break;
}
} while (true);
}
Of course, this is without knowing what is in the file and what the heck Fish is, so I do not know if this is what you are looking for.
EDIT:If you could include the file, or just a section of one "fish" as I assume that is what the contents of the file are, it would be alot easier to help.

Related

Getting an Xstring error in VS in a C++ login program

I am a beginner C++ programmer. I'm trying to create a program that takes logs a user into a program, Everything compiled perfectly, but when I try to run it I get an Xstring error saying this was 0x7FF6F0AACFF0".
I suppose the error could have come from the fact that I am very new to using files in code, and I needed to use them in this program as they were the only way the login and password data could be permanently saved.
I have rewritten this project over 5 times and this is the most functional variant so far. I tried using the ofstream and ifstream but I abandoned them because only one password & login was saved per file; so I think that the main error is probably contained in the Processing and Array_filler functions, all I need is a point in the right direction and I'll probably be able to resolve it.
C++:
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
using namespace std;
//bug_1 need to fix the error where the code doesn't recognize a returning user
//Project_1 need to implement a subsystem that recommends a random password & Login
//Project_2 need to implement a subsystem that requires a strong password
string Word_blip[90] = {};
string Pass_blop[90] = {};
string password;
string logWord;
string Login_1;
string Pass_1;
int KILL_SWITCH = 1;
int y = 0;
void Array_filler();
void Start_up();
void Yupper_pupper();
void processing();
void New_Login();
int main() {
Start_up();
if (KILL_SWITCH == 0) {
return EXIT_SUCCESS;
}
Yupper_pupper();
processing();
}
void Start_up() {
Array_filler();
cout << "Login:";
cin >> logWord;
cout << "Password:";
cin >> password;
for (y; y >= 90; y++) {
cout << "Preparing" << endl;
}
system("cls");
if (Word_blip[y] == logWord) {
cout << "Login accepted, welcome user:" << endl;
} else if (Word_blip[y] != logWord) {
New_Login();
}
}
void New_Login() {
string i_1_5;
cout << "Login not recognized, would you like to sign up?" << endl;
cin >> i_1_5;
if (i_1_5 == "yes") {
void Yupper_pupper();
} else if (i_1_5 == "no") {
cout << "Have a good day!" << endl;
KILL_SWITCH = 0;
} else {
cout << "That's not a valid answer ;-) please retry" << endl;
New_Login();
}
}
void Yupper_pupper() {
system("cls");
cout << "Please Sign in with your new username & Password." << endl;
cout << "New Login:";
cin >> Login_1;
cout << "New password:";
cin >> Pass_1;
void processing();
}
void processing() {
/* acts like "ofstream" or "ifstream combined; with the
ios::in and ios::out replacing the sort of "read out file"
ofstream meant with "ios::in"and the "input into file" that
ifstream provided with ios::out*/
fstream Urfile("Logins.txt", ios:: in );
string Placeholder_1;
if (Urfile.is_open()) {
getline(Urfile, Placeholder_1);
/* While Urfile = "While the file is open" Urfile = true
When the file runs out of information the file will close
making the statement false and ending the loop ;-)*/
while (Urfile) {
Placeholder_1 = Word_blip[0];
}
Urfile.close();
} else {
cout << "ERROR_OPENING_URFILE_ABORTING_PROGRAM_1" << endl;
abort();
}
fstream Myfile("Passwords.txt", ios:: in );
string Placeholder_2;
if (Myfile.is_open()) {
getline(Myfile, Placeholder_2);
while (Myfile) {
Placeholder_2 = Pass_blop[0];
}
Myfile.close();
} else {
cout << "ERROR_OPENING_MYFILE_ABORTING_PROGRAM_1" << endl;
abort();
}
Start_up();
}
void Array_filler() {
/*This function is responsible for clearing out the file
and replacing everything inside with the contents of Pass_blip and Word_blop
. Don't worry! none of the data will be lost because it was all written to the
arrays to be processed alongside the new inputs*/
fstream Urfile("Login.txt", ios::out);
if (Urfile.is_open()) {
for (int i = 0; Word_blip[i] != "\n"; i++) {
Urfile << Word_blip[i] << endl;
}
Urfile.close();
} else {
cout << "ERROR_OPENING_URFILE_ABORTING_PROGRAM_2" << endl;
abort();
}
fstream Myfile("Passwords.txt", ios::out);
if (Myfile.is_open()) {
for (int i = 0; Pass_blop[i] != "\n"; i++) {
Myfile << Pass_blop[i] << endl;
}
Myfile.close();
} else {
cout << "ERROR_OPENING_MYFILE_ABORTING_PROGRAM_2" << endl;
abort();
}
}

string is missing when I read data from a text file in binary mode

I have created a class Scholar with attributes: string name, int id, char grade. Then, I had written the data in text file in binary mode using program P1. I had another program P2 which inserts a new data in between previous data.
It shows data (using program P1) when I initially created the text file with some objects. But, when I inserted a new data (using program P2), the attributes id and grade appears but, the attribute name went missing.
The Scholar class code:
#ifndef SCHOLAR_H
#define SCHOLAR_H
#include <iostream>
#include <cstdio>
using namespace std;
class Scholar {
int id;
string name;
char grade;
public:
void read_data() {
cout << "\nEnter ID: ";
cin >> id;
string temp;
getline(cin, temp);
cout << "Enter name: ";
getline(cin, name);
cout << "Enter grade: ";
cin >> grade;
}
void print_data() {
cout << "\nID: " << id << " | Name: " << name << " | Grade: " << grade;
}
int modify_data();
int _id() {
return id;
}
string _name() {
return name;
}
char _grade() {
return grade;
}
};
#endif // SCHOLAR_H
Program P1:
#include "MyHeaderFiles/Scholar.h"
#include <fstream>
#include <cstdlib>
#include <cctype>
int main() {
system("cls");
Scholar sch;
fstream fs;
fs.open("SchDB.txt", ios::out | ios::in | ios::binary | ios::trunc);
if(!fs) {
cerr << "File not found!";
system("PAUSE");
}
char reply;
do {
sch.read_data();
fs.write((char*) &sch, sizeof(sch));
cout << "Do you want to add another scholar (y/n) : ";
cin >> reply;
} while(tolower(reply) == 'y');
fs.seekg(0);
cout << "\nFile content\n------------" << endl;
while(!fs.eof()) {
fs.read((char*) &sch, sizeof(sch));
if(fs.eof()) break;
sch.print_data();
}
fs.close();
cout << endl;
return 0;
}
The initial image of output when I hadn't inserted any new data:
You can see the names!
Program P2:
#include "MyHeaderFiles/Scholar.h"
#include <fstream>
#include <cstdlib>
int main() {
system("cls");
Scholar sch;
Scholar newSch;
ofstream fout;
ifstream fin;
fout.open("Temp.txt", ios::out | ios::binary);
fin.open("SchDB.txt", ios::in | ios::binary);
char last = 'y';
int pos;
cout << "\nYou have to enter data of a new student." << endl;
newSch.read_data();
fin.seekg(0);
cout << "\nFile content\n------------" << endl;
while(!fin.eof()) {
pos = fin.tellg();
fin.read((char*) &sch, sizeof(sch));
if(sch._id() > newSch._id()) {
fout.write((char*) &newSch, sizeof(newSch));
last = 'n';
break;
} else {
fout.write((char*) &sch, sizeof(sch));
}
}
if(last == 'y') {
fout.write((char*) &newSch, sizeof(newSch));
} else if(!fin.eof()) {
fin.seekg(pos);
while(!fin.eof()) {
fin.read((char*) &sch, sizeof(sch));
if(fin.eof()) break;
fout.write((char*) &sch, sizeof(sch));
}
}
fin.close();
fout.close();
remove("SchDB.txt");
rename("Temp.txt", "SchDB.txt");
fin.open("SchDB.txt", ios::in | ios::binary);
fin.seekg(0);
while(!fin.eof()) {
fin.read((char*) &sch, sizeof(sch));
if(fin.eof()) break;
sch.print_data();
}
fin.close();
cout << endl;
return 0;
}
The later image when I used the program P2 to insert new data:
And, now you can see only the name attribute is missing!
I am using Code::Blocks IDE and GNU GCC Compiler.
Can anybody explain me why the string isn't showing up?

I'm only able to input one word into the file

Like my title said, I am having problems with file input.
Here is my code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void CreateNewFile(const string FileName) {
ofstream NewFile;
string FileNamePlaceholder = FileName + ".txt";
NewFile.open(FileNamePlaceholder);
cout << "What would you like to write to the file? ";
string InputForFile;
cin >> InputForFile;
NewFile << InputForFile;
NewFile.close();
cout << "You will now be able to view the file in your computer.\n";
}
void Start() {
char NewFile;
cout << "Would you like to create a new file? [Y/N] ";
cin >> NewFile;
if (NewFile == 'y' || NewFile == 'Y') {
cout << "What would you like the new file to be named? ";
string NewFileName;
cin >> NewFileName;
CreateNewFile(NewFileName);
}
else if (NewFile == 'n' || NewFile == 'N') {
cout << "Ok, bye.\n";
}
else {
cout << "You did not type y, Y, n, or N!\n";
}
}
int main(void) {
Start();
return 0;
}
For some reason, I can only input one word at a time into the file. I'm sorry if this is an obvious answer. Any help would be appreciated.

My code isn't overwriting the text file, even though it should be?

We did a very similar type of code in C++ class but my version isn't working right, even though it is line-by-line (almost) the same.
My code is meant to save a user's Pokemon and they can add and delete as they please. My display function is working but my add and delete function are not. All the files are opening, but it's not overwriting the file like it's supposed to. Really unsure of what to do, I'm very much a beginner and I don't know much.
Here is what I've got so far:
string name[100];
string type[100];
int level[100];
string newPokemon;
string newType;
int newLevel;
ifstream fin;
ofstream fout;
int numberOfPokemon = 0;
//Input Pokemon Info
cout << "Name of Pokemon: ";
getline(cin, newPokemon);
cin.ignore(100, '\n');
cout << "Pokemon type: ";
getline(cin, newType);
cin.ignore(100, '\n');
cout << "Pokemon level: "; //weird gap between "Pokemon type" and "pokemon level". I have to press enter twice from "pokemon type" to get to "pokemon level"
cin >> newLevel;
cin.ignore(5, '\n');
fin.open("pokemon.txt");
//Put file in array
if (fin.is_open())
{
while (isalnum(fin.peek()) && numberOfPokemon < 100)
{
getline(fin, name[numberOfPokemon]);
getline(fin, type[numberOfPokemon]);
fin >> level[numberOfPokemon];
fin.ignore(100, '\n');
if (name[numberOfPokemon] != newPokemon)
numberOfPokemon++;
}
fin.close();
}
//Output file
fout.open("pokemon.txt");
if (fout.is_open())
{
for (int i = 0; i < numberOfPokemon; i++)
{
fout << name[i] << "\n";
fout << type[i] << "\n";
fout << level[i] << "\n";
}
//Tack on new piece
fout << newPokemon << "\n";
fout << newType << "\n";
fout << newLevel << "\n";
fout.close();
cout << "Add Successful\n";
}
else
{
cout << "Add Failure\n";
}
and now my delete function:
string name[100];
string type[100];
int level[100];
int pokemonCount = 0;
string deletedPokemon = "";
bool found = false;
ifstream fin;
cout << "Which Pokemon would you like to delete?" << endl;
getline(cin, deletedPokemon);
cin.ignore(5, '\n');
fin.open("pokemon.txt");
if (fin.is_open())
{
while (isalnum(fin.peek()))
{
getline(fin, name[pokemonCount]);
getline(fin, type[pokemonCount]);
fin >> level[pokemonCount];
fin.clear();
fin.ignore(100, '\n');
if (deletedPokemon == name[pokemonCount])
{
pokemonCount--;
found = true;
}
pokemonCount++;
}
fin.close();
cout << "ya the file opened" << endl; //always appears
}
ofstream fout;
fout.open("pokemon.txt");
if (fout.is_open())
{
for (int i = 0; i < pokemonCount; i++)
{
fout << name[i] << "\n";
fout << type[i] << "\n";
fout << level[i] << endl;
}
fout.close();
cout << "pokemon removed\n";
cout << "the file opened."; //it is returning that the file opened in both occasions in this function but nothing is happening!
}
else
{
cout << "removal failure";
cout << "The file didn't open";
}
return found;
at the end of this function (if I chose to delete one), it will offer the "Would you like to add a Pokemon?" but it wont let me input an answer and it will just end the program.
The default behaviour of ofstream::open is to simply open the file for reading and writing. If you want to overwrite the file, you need to specify it in your call to open.
fout.open("pokemon.txt", ios_base::in|ios_base::out|ios_base::trunc);
Make sure your file is not marked as read-only under properties.
Also, there is a bug in your delete function:
The bfound should be replace with nDelete pokemon and when you write out the file:
if (deletedPokemon == name[pokemonCount])
{
pokemonCount--;
found = true;
nDeleteIndex = i;
}
....
for (int i = 0; i < pokemonCount; i++)
{
if(i == nDeleteIndex)
continue;
fout << name[i] << "\n";
fout << type[i] << "\n";
fout << level[i] << endl;
}
Right now it will re-write all your pokemons without skipping the one you want to delete!
Also, what happens if the user has 155 pokemons for a full index. You want to use:
std::vector<string> names;
....
string szPokemon;
getline(fin, name[numberOfPokemon]);
names.push_back(szPokemon);
Thus you no longer have a limit !
Here is much cleaner code, its much more maintainable and whenever you add/remove a field from the pokemon (Shiny? Male/Female ? Unique ?) you will be able to easily do it inside the CPokemonObject instead of having to copy paste the code 100 times.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
#define POKEMON_FILE "Pokemon.txt"
class CPokemon
{
public:
string szName;
string szType;
int nLevel;
CPokemon() : szName("Pika"), nLevel(10), szType("Lightning")
{};
void Read(ifstream &file)
{
file >> szName;
file >> szType;
file >> nLevel;
};
void Write(ofstream &file)
{
file << szName << endl;
file << szType << endl;
file << nLevel << endl;
};
void CreatePokemon()
{
//Input Pokemon Info
cout << "Name of Pokemon: ";
getline(cin, szName);
cout << "Pokemon type: ";
getline(cin, szType);
cout << "Pokemon level: "; //weird gap between "Pokemon type" and "pokemon level". I have to press enter twice from "pokemon type" to get to "pokemon level"
cin >> nLevel;
}
};
void WritePokemons(vector<CPokemon>& Pokemons)
{
ofstream fout;
fout.open(POKEMON_FILE);
//check the file open
if (!fout.is_open())
{
cout << "removal failure";
cout << "The file didn't open";
return;
}
//Write out all the pokemons
for (unsigned int i = 0; i < Pokemons.size(); i++)
Pokemons[i].Write(fout);
fout.close();
}
void ReadPokemons(vector<CPokemon>& Pokemons)
{
ifstream fin;
fin.open(POKEMON_FILE);
if (fin.is_open())
{
while (isalnum(fin.peek()))
{
CPokemon Pokemon;
Pokemon.Read(fin);
Pokemons.push_back(Pokemon);
}
fin.close();
cout << "ya the file opened" << endl; //always appears
}
}
bool DeletePokemon()
{
vector<CPokemon> Pokemons;
string szPokemonToDelete = "";
cout << "Which Pokemon would you like to delete?" << endl;
cin >> szPokemonToDelete;
//Read all pokemons
ReadPokemons(Pokemons);
ofstream fout;
fout.open("pokemon.txt");
//check the file open
if (!fout.is_open())
{
cout << "removal failure";
cout << "The file didn't open";
return false;
}
bool bFound = false;
for (unsigned int i = 0; i < Pokemons.size(); i++)
{
//Skip the pokemon to delete
if(Pokemons[i].szName == szPokemonToDelete)
{
bFound = true; //we found the pokemon to delete
continue;
}
Pokemons[i].Write(fout);
}
fout.close();
return bFound;
}
void AddPokemon()
{
vector<CPokemon> Pokemons;
//Read all pokemons from the file
ReadPokemons(Pokemons);
//Create the new porkemon
CPokemon Pokemon;
Pokemon.CreatePokemon();
//Add the pokemon to the list
Pokemons.push_back(Pokemon);
//Output file
WritePokemons(Pokemons);
}

ifstream getline issue (it only reads the first line)

Something is definitely wrong with my loop because after reading and executing the first line the programs ends.
if (infile.is_open())
{
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
cout<< "Output filename: ";
cin>>filename;
outfile.open(filename.c_str());
while(getline(infile,input))
{
string output = "";
for(int x = 0; x < input.length(); x++)
output += cipher(input[x]);
cout<<output<<endl;
outfile<<output;
}
}
Any suggestions on how to make this work?
EDIT
Followed the suggestions and got this:
if (infile.is_open()) {
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
if (!infile.is_open())
{
std::cout << "Failed to open the input file." << std::endl;
return -1;
}
cout<< "Output filename: ";
cin>>filename;
outfile.open(ofilename.c_str());
if (!outfile.is_open())
{
std::cout << "Failed to open the output file." << std::endl;
return -1;
}
while(getline(infile,line)){
string output = "";
for(int x = 0; x < input.length(); x++) {
output += cipher(input[x]);
}
}
BUT it still reads only the first line...everything else is working perfectly fine....just can't read anything beyond the first line..
It seems that you misunderstood the point of the fstream's is_open() method, since this code:
if (infile.is_open())
{
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
...
}
checks whether the infile has been successfully opened (i.e. if either a previous call to member open succeeded or if the object was successfully constructed using the parameterized constructor,
and close has not been called since) and in case it is open it retrieves the name of the input file from cin and opens the file.
Good start would be the program that reads from the input file line by line and writes these lines to the output file without processing them:
// retrieve the name of the input file and open it:
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
if (!infile.is_open())
{
std::cout << "Failed to open the input file." << std::endl;
return -1;
}
// retrieve the name of the output file and open it:
cout << "Output filename: ";
cin >> filename;
outfile.open(filename.c_str());
if (!outfile.is_open())
{
std::cout << "Failed to open the output file." << std::endl;
return -1;
}
std::string line;
while(getline(infile,line))
{
std::cout << line << std::endl;
outfile << line;
}
So I suggest this.
Write char cipher(char ch) to return enciphered input for anything. if you don't want to encipher whitespace, then don't. But always return the enciphered character or unmodifed character.
Use std::transform , std::istream_iterator , and std::ostream_iterator to transform your input and output files.
Check your file states at the correct times.
An example appears below:
#include <iostream>
#include <fstream>
#include <iteraor>
#include <string>
using namespace std;
char cipher(char ch)
{
if (std::isalpha(ch))
{
// TODO: change ch to whatever you want here.
}
// but always return it, whether you changed it or not.
return ch;
}
int main()
{
int res = EXIT_SUCCESS;
string in_filename, out_filename;
cout << "Input filename: ";
cin >> in_filename;
cout << "Output filename: ";
cin >> out_filename;
// don't skip whitespace
ifstream infile(in_filename);
ofstream outfile(out_filename);
if ((infile >> noskipws) && outfile)
{
std::transform(istream_iterator<char>(infile),
istream_iterator<char>(),
ostream_iterator<char>(outfile),
cipher);
}
else
{
perror("Failed to open files.");
res = EXIT_FAILURE;
}
return res;
}