ofstream creates a file but can't write to it - c++

REVISED: Here is my entire compilable program. It is menu driven, but the part that I am stuck on is option DECRYPT, to decrypt a caesar cyphered file, or number 5 (either could be typed in at the initial question, the decrypt could be lower case, upper case, or camel case). The ofstream variable outFile creates a file named by the user (must be a non-existing file). The problem is that it only creates the empty file, and does not print any of the data into it. All of the variables store the correct values. cout works, but outFile does not. Is there something that I am not doing correctly? I have tried to test for bad, fail, and is_open and none of them have any trouble. I do not think that file permissions would prevent anything either, since the other options in the program create and write to a file just fine. Can anyone help me?
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>
#include <vector>
using namespace std;
int main() {
string inputFileName, outputFileName, inData, outData, inWord, outWord, trash;
ifstream inFile, testStream;
ofstream outFile;
bool outPutOpened = false, isLowerCase = false;
char outChar, inChar;
int shiftNum = 0, idx = 0, total = 0, max = 0, shiftValue = 0;
map<char,int> charMap;
map<char,int>::iterator mapIt;
vector<char> alphabet(26);
vector<char>::iterator shiftIt;
do {
inWord.clear();
outWord.clear();
cout << "Available options: " << endl;
cout << "1. ENCRYPT - Encrypt a file using Caesar Cypher" << endl
<< "2. CHARFREQ - display character frequency table for file"
<< endl << "3. Quit - Exit the program" << endl
<< "5. DECRYPT - decrypt a cyphered file" << endl << endl;
cout << " Enter keyword or option index: ";
getline(cin, inWord);
outWord.resize(inWord.length());
transform(inWord.begin(), inWord.end(), outWord.begin(), ::toupper);
if (outWord.compare("ENCRYPT") == 0 || outWord.compare("1") == 0) {
cout << "CAESAR CYPHER PROGRAM" << endl
<< "======================" << endl << endl;
do {
cout << "Provide the input file name: ";
getline(cin, inputFileName);
inFile.open(inputFileName.c_str());
if (inFile.fail()) {
cout << "Cannot open file, please try again!" << endl;
inFile.clear();
}
}
while (!inFile.is_open());
do {
cout << "Provide the output file name: ";
cin >> outputFileName;
getline(cin, trash);
testStream.clear();
testStream.open(outputFileName.c_str());
if(testStream.good()) {
cout << "That file already exists, choose another" << endl;
testStream.clear();
testStream.close();
}
else {
testStream.clear();
testStream.close();
outFile.open(outputFileName.c_str());
if (outFile.good()) {
outPutOpened = true;
}
}
}
while (!outPutOpened);
cout << "Enter the shift number: ";
cin >> shiftNum;
getline(cin, trash );
while(getline(inFile, inData)) {
for (idx = 0; idx <= inData.length() - 1; idx++) {
if (inData[idx] >= 'a' && inData[idx] <= 'z') {
outChar = (((inData[idx] - 'a') + shiftNum) % 26) + 'a';
outFile.put(outChar);
}
else if (inData[idx] >= 'A' && inData[idx] <= 'Z'){
outChar = (((inData[idx] - 'A') + shiftNum) % 26) + 'A';
outFile.put(outChar);
}
else {
outFile.put(inData[idx]);
}
}
}
inFile.clear();
inFile.close();
outFile.clear();
outFile.close();
}
else if (outWord.compare("2") == 0 || outWord.compare("CHARFREQ") == 0){
cout << "Enter input file name: ";
getline(cin, inputFileName);
inFile.open(inputFileName.c_str());
while (inFile.get(inChar)) {
if (charMap.find(inChar) == charMap.end()) {
charMap[inChar] = 1 ;
}
else {
++charMap[inChar];
}
}
cout << "Character Frequencies For \"" << inputFileName << "\""
<< endl;
for (mapIt = charMap.begin(); mapIt != charMap.end(); mapIt++) {
total += (*mapIt).second;
}
cout << "Total bytes read: " << total << endl;
for (mapIt = charMap.begin(); mapIt != charMap.end(); mapIt++) {
cout << " ('" << (*mapIt).first << "') occurs "
<< (*mapIt).second << " times ("
<< static_cast<double> ((*mapIt).second)
/ static_cast<double> (total) << "% of all characters)" << endl;
}
inFile.clear();
inFile.close();
}
else if (outWord.compare("5") == 0|| outWord.compare("DECRYPT") == 0) {
outPutOpened = false;
do {
cout << "Provide the input file name: ";
getline(cin, inputFileName);
inFile.open(inputFileName.c_str());
if (inFile.fail()) {
cout << "Cannot open file, please try again!" << endl;
inFile.clear();
}
}
while (!inFile.is_open());
while (inFile.get(inChar)) {
if (inChar < 'a' || inChar > 'z') {
inFile.ignore();
}
else {
inChar -= 'a';
alphabet[static_cast<int> (inChar)]++;
}
}
for (idx = 0; idx < alphabet.size(); idx++) {
if(max < alphabet[idx]){
max = alphabet[idx];
}
}
shiftIt = find(alphabet.begin(), alphabet.end(), max);
shiftValue = (distance(alphabet.begin(), shiftIt) - 4);
if (shiftValue < 0) {
shiftValue += 26;
}
inFile.close();
do {
inFile.open(inputFileName.c_str());
if (inFile.fail()) {
cout << "Cannot open file, please try again!" << endl;
inFile.clear();
}
}
while (!inFile.is_open());
outPutOpened = false;
do {
cout << "Provide the output file name: ";
cin >> outputFileName;
getline(cin, trash);
testStream.clear();
testStream.open(outputFileName.c_str());
if(testStream.good()) {
cout << "That file already exists, choose another" << endl;
testStream.clear();
testStream.close();
}
else {
testStream.clear();
testStream.close();
outFile.open(outputFileName.c_str());
if (!outFile.good()) {
cout << "bad output"<< endl;
outFile.clear();
}
if (outFile.good()) {
outPutOpened = true;
}
}
}
while(!outPutOpened);
while((inFile.get(inChar))) {
if (inChar >= 'a' && inChar <= 'z') {
inChar -= shiftValue;
if (inChar < 'a') {
inChar += 26;
}
outFile << inChar;
}
else if (inChar >= 'A' && inChar <= 'Z'){
inChar -= shiftValue;
if (inChar < 'A') {
inChar += 26;
}
outFile << inChar;
}
else {
outFile << inChar;
}
}
}
else if (outWord.compare("3") == 0 || outWord.compare("QUIT") == 0) {
break;
}
else {
cout << inWord << " is an unrecognized option, please try again"
<< endl;
}
}
while (outWord.compare("3") || outWord.compare("QUIT"));
return 0;
}

you have to flush the stream in order for the chars to actually be written to file.
after your write-to-outFile-while loop do a:
outFile.flush();
.. and the text will be written fine to the file.

Try outFile.close();. It worked for me.

Related

Why can't I delete list object in C++? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
I tried my best to figure this out but it was unsuccessful :C
PROBLEM
for (Treniruote& t : treniruotes)
{
if (t.data == duotaData)
{
if (t.laikas == duotasLaikas)
{
treniruotes.remove(t);
}
}
}
FULL CODE:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <list>
#include <ctime>
using namespace std;
struct Treniruote
{
string data, laikas, vardas, pavarde, pratimai;
};
void NuskaitytiIsFailo(list<Treniruote>& treniruotes)
{
string line, word;
fstream file("planas.csv", ios::in);
if (file.is_open())
{
while (getline(file, line))
{
stringstream str(line);
Treniruote row;
if (getline(str, word, ','))
row.data = word;
if (getline(str, word, ','))
row.laikas = word;
if (getline(str, word, ','))
row.vardas = word;
if (getline(str, word, ','))
row.pavarde = word;
if (getline(str, word, ','))
row.pratimai = word;
treniruotes.push_back(row);
}
}
else
cout << "Could not open the file";
}
void rastiKlientoInfo(list<Treniruote>& treniruotes)
{
int a;
string fname, pavarde;
cout << "Write clients surname:";
cin >> pavarde;
cout << "Output to the screen press -1\n";
cout << "Output to the file press - 2\n";
cout << "Output all exercise needed to be done in a week - 3\n";
cout << "Your choice:";
cin >> a;
if (a == 2)
{
cout << "Enter the file name: ";
cin >> fname;
}
else if (a == 3)
{
cout << "Enter the file name: ";
cin >> fname;
}
else
{
}
for (Treniruote& t : treniruotes)
{
if (t.pavarde == pavarde)
{
if (a == 1)
{
cout << t.data << endl;
cout << t.laikas << endl;
cout << t.vardas << endl;
cout << t.pavarde << endl;
cout << t.pratimai << endl;
cout << endl;
}
else if (a == 3)
{
fstream file(fname + ".csv", ios::app);
file << t.pratimai << endl;
}
else
{
fstream file(fname + ".csv", ios::app);
file << t.data << endl;
file << t.laikas << endl;
file << t.vardas << endl;
file << t.pavarde << endl;
file << t.pratimai << endl;
file << endl;
}
}
}
}
void PakeistiReiksmes(list<Treniruote>& treniruotes)
{
string duotasLaikas, duotaData;
cout << "irasykite norima data ir laika ,kada norite pakeisti duomenys" << endl;
cout << "data(formatas(XXXX.XX.XX)):";
cin >>duotaData;
cout << endl;
cout << "laikas(formatas(XX:XX-XX:XX)):";
cin >>duotasLaikas;
for (Treniruote& t : treniruotes)
{
if (t.data == duotaData)
{
if (t.laikas == duotasLaikas)
{
t.vardas = t.pavarde = t.pratimai = "obolys";
}
}
}
}
void SukurtiTuscius(list<Treniruote> &treniruotes)
{
for (int i = 27; i <= 30; ++i)
{
stringstream diena;
diena << "2022.11." << i;
for (int j = 8; j <= 19; ++j)
{
stringstream valanda;
valanda << j << ":00-"<< j+1 <<":00";
Treniruote t;
t.data = diena.str();
t.laikas = valanda.str();
t.vardas = t.pavarde = t.pratimai = "nera";
treniruotes.push_back(t);
}
}
}
void ParodytiVisaTvarkarasti(list<Treniruote>& treniruotes)
{
for (Treniruote& t : treniruotes)
{
cout << t.data << endl;
cout << t.laikas << endl;
cout << t.vardas << endl;
cout << t.pavarde << endl;
cout << t.pratimai << endl;
cout << endl;
}
}
void salinti_pridėti(list<Treniruote>& treniruotes)
{
}
void ProgramosPabaiga(list<Treniruote>& treniruotes)
{
fstream file("planas.csv", ios::out);
for (Treniruote& t : treniruotes)
{
file << t.data <<","<< t.laikas << "," << t.vardas << "," << t.pavarde << "," << t.pratimai;
file << endl;
}
cout << "PROGRAMA BAIGTA";
exit(0);
}
int main()
{
int choice;
bool gameOn = true;
list<Treniruote> treniruotes;
struct tm newtime;
time_t now = time(0);
localtime_s(&newtime,&now);
auto month = to_string(1 + newtime.tm_mon);
auto day = to_string(newtime.tm_mday);
auto hour = to_string(newtime.tm_hour);
auto hour_pridėta = to_string(1 + newtime.tm_hour);
//sukuria .csv faila pagal irasyta pavadinima
//string fname;
//cout << "Enter the file name: ";
//cin >> fname;
// fstream file(fname + ".csv", ios::app);
//Menu
while (gameOn != false) {
cout << "*******************************\n";
cout << " 1 - Create empty weekly plan.\n";
cout << " 2 - Show the full schedule.\n";
cout << " 3 - Read the weekly work plan.\n";
cout << " 4 - Change the schedule field information.\n";
cout << " 5 - Find the given client's full weekly workouts\n";
cout << " 7 - Exit.\n";
cout << "*******************************\n";
for (Treniruote& t : treniruotes)
{
if (t.data == "2022." + month + "." + day)
{
if (t.laikas == hour + ":00-" + hour_pridėta + ":00")
{
cout << t.data << endl;
cout << t.laikas << endl;
cout << t.vardas << endl;
cout << t.pavarde << endl;
cout << t.pratimai << endl;
cout << endl;
}
}
}
cout << "*******************************\n";
cout << " Enter your choice and press return: ";
cin >> choice;
switch (choice)
{
case 1:
SukurtiTuscius(treniruotes);
break;
case 2:
ParodytiVisaTvarkarasti(treniruotes);
break;
case 3:
NuskaitytiIsFailo(treniruotes);
break;
case 4:
PakeistiReiksmes(treniruotes);
break;
case 5:
rastiKlientoInfo(treniruotes);
break;
case 6:
{
string duotasLaikas, duotaData;
cout << "irasykite norima data ir laika ,kada norite pakeisti langeli" << endl;
cout << "data(formatas(XXXX.XX.XX)):";
cin >> duotaData;
cout << endl;
cout << "laikas(formatas(XX:XX-XX:XX)):";
cin >> duotasLaikas;
for (Treniruote& t : treniruotes)
{
if (t.data == duotaData)
{
if (t.laikas == duotasLaikas)
{
treniruotes.remove(t);
}
}
}
}
break;
case 7:
{
ofstream file;
file.open("planas.csv", std::ofstream::out | std::ofstream::trunc);
file.close();
ProgramosPabaiga(treniruotes);
break;
}
default:
cout << "Not a Valid Choice. \n";
cout << "Choose again.\n";
cin >> choice;
break;
}
}
return 0;
}
You must not remove items from a list while iterating through a range-based for loop. Under the hood, the loop stores a begin and end iterator of the original list, and iterate all items between them, and attempting to remove items during the loop will make end unreachable.
Instead, you could simply use std::list::remove_if to remove all elements that satisfy a certain condition:
my_list.remove_if([a, b](const auto& element){
return element.a == a && element.b == b;
};

Need help resolving an Unhandled Exception Error

I've been learning to program for a few months now and I've been working on a program to manage student data. Here's the code:
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <stdio.h>
using namespace std;
class Student
{
private:
string name;
string course;
int section;
int grade;
public:
void calcgrade();
void getData();
void showData();
};
void Student::calcgrade()
{
if (grade >= 90)
grade = 'A';
else if (grade >= 80)
grade = 'B';
else if (grade >= 70)
grade = 'C';
else if (grade >= 60)
grade = 'D';
else
grade = 'F';
}
void Student::getData()
{
cout << "Enter the name of the student: ";
cin.ignore();
getline(cin, name);
cout << "Enter the course: ";
cin >> course;
cout << "Enter the section: ";
cin >> section;
cout << "Enter the grade received: ";
cin >> grade;
calcgrade();
}
void Student::showData()
{
cout << ".......Student Information......" << endl;
cout << "Student Name: " << name << endl;
cout << "Course: " << course << endl;
cout << "Section: " << section << endl;
cout << "Grade: " << grade << endl;
cout << endl;
}
void addData()
{
Student st;
ofstream fout;
fout.open("Student.data", ios::binary | ios::out |
ios::app);
st.getData();
fout.write((char*)& st, sizeof(st));
fout.close();
cout << "Data Successfully Saved to File." << endl;
}
void displayData()
{
Student st;
ifstream file;
file.open("Student.data", ios::in | ios::binary);
if (file.is_open())
{
while (file.read((char*)& st, sizeof(st)))
{
st.showData();
}
cout << "Finished Reading Data From File." <<
endl;
}
else
{
cout << "Unable to open file" << endl;
}
file.close();
}
void searchData()
{
Student st;
ifstream file;
file.open("Student.data", ios::in | ios::binary);
string search;
cout << "Please enter the first name of a student to search for: ";
cin >> search;
bool isFound = 0;
while (file.read((char*)& st, sizeof(st)))
{
string temp = " ";
getline(file, temp);
for (int i = 0; i < search.size(); i++)
{
if (temp[i] == search[i])
isFound = 1;
else
{
isFound = 0;
break;
}
}
if (isFound)
{
cout << "The name " << search << " was found in the database." << endl;
break;
}
}
if (file.read((char*)& st, sizeof(st)) && (!isFound))
{
cout << "Name not found." << endl;
}
file.close();
}
void modifyData()
{
Student st;
string stname;
bool isFound = 0;
int pos;
fstream file;
file.open("Student.data", ios::in | ios::out | ios::binary);
cout << "Enter the name of a student whose data you want to modify: ";
cin >> stname;
while (file.read((char*)& st, sizeof(st)))
{
string temp = " ";
getline(file, temp);
for (int i = 0; i < stname.size(); i++)
{
if (temp[i] == stname[i])
isFound = 1;
else
{
isFound = 0;
break;
}
}
if (isFound)
{
pos = file.tellg();
cout << "Current Data" << endl;
st.showData();
cout << "Modified Data" << endl;
st.getData();
file.seekg(pos - sizeof(st));
file.write((char*)& st, sizeof(st));
}
}
if (file.read((char*)& st, sizeof(st)) && (!isFound))
{
cout << "Name not found." << endl;
}
file.close();
}
void deleteData()
{
Student st;
string stname;
bool isFound = 0;
ifstream file;
ofstream fout;
file.open("Student.data", ios::in | ios::binary);
fout.open("Temporary.data", ios::out | ios::app | ios::binary);
cout << "Enter the name of a student whose data you want to delete: ";
cin >> stname;
while (file.read((char*)& st, sizeof(st)))
{
string temp = " ";
getline(file, temp);
for (int i = 0; i < stname.size(); i++)
{
if (temp[i] == stname[i])
isFound = 1;
else
{
isFound = 0;
break;
}
}
if (isFound)
{
cout << "Bleh" << endl;
fout.write((char*)& st, sizeof(st));
}
}
if (file.read((char*)& st, sizeof(st)) && (!isFound))
{
cout << "Name not found." << endl;
}
fout.close();
file.close();
remove("Student.data");
rename("Temporary.data", "Student.data");
}
void printData()
{
ifstream file;
file.open("Student.data", ios::in | ios::binary);
if (file.is_open())
{
cout << file.rdbuf();
}
file.close();
}
int main()
{
int num;
do
{
cout << "...............STUDENT MANAGEMENT SYSTEM..............\n";
cout << "======================================== ==============\n";
cout << "0. Close Program. " << endl;
cout << "1. Add Data. " << endl;
cout << "2. List Data. " << endl;
cout << "3. Modify Data. " << endl;
cout << "4. Search For Data. " << endl;
cout << "5. Print Data. " << endl;
cout << "6. Delete Data. " << endl;
cout << "Choose an option: ";
cin >> num;
if (num == 1)
{
addData();
}
else if (num == 2)
{
displayData();
}
else if (num == 3)
{
modifyData();
}
else if (num == 4)
{
searchData();
}
else if (num == 5)
{
printData();
}
else if (num == 6)
{
deleteData();
}
} while (num > 0);
return 0;
}
Ideally, when the program runs, the user chooses an option, with different function calls depending on the number entered. The Add Data option works fine, but when choosing others, such as List Data or Search Data, I run into an error such as: Unhandled exception thrown: read access violation. _Pnext was 0x10A6A04.
Code in xmemory:
inline void _Container_base12::_Orphan_all() noexcept {
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myproxy != nullptr) { // proxy allocated, drain it
_Lockit _Lock(_LOCK_DEBUG);
for (_Iterator_base12** _Pnext = &_Myproxy->_Myfirstiter; *_Pnext != nullptr;
*_Pnext = (*_Pnext)->_Mynextiter) {
(*_Pnext)->_Myproxy = nullptr;
}
_Myproxy->_Myfirstiter = nullptr;
}
Given there are no obvious errors in the code, I'd like a little help in figuring out what I've done wrong.

Fails to check for string in file

I have this school project of mine and I need some help to troubleshoot; I've debugged as far as if it goes into the while(prod_file.good()) loop and it does, it just fails to find an existing string within a file.
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
#define PROD_SIZE 22
class PRODUCT {
public:
string NAME;
string QUANTITY;
} product;
int main() {
int diff;
string length;
char answer = 0;
string line;
bool foundAndReplaced = false;
cout << product.NAME.length() << endl;
cout << product.NAME;
fstream prod_file("data/available.dat", ios::out | ios::app);
do {
if(prod_file.is_open()) {
cout << "Molq vavedete imeto na produkta: \n";
getline(cin, product.NAME);
if(product.NAME.length() < 30) {
diff = 30 - product.NAME.length();
for(int i = 1; i < diff; i++){
product.NAME.append(".");
}
}
else if(product.NAME.length() > 30) {
cout << "Product name cannot exceed 30 characters.";
return 0;
}
//
cout << "Molq vavedete kolichestvoto na produkta: \n";
getline(cin, product.QUANTITY);
size_t pos;
while(prod_file.good()) {
cout << "asd\n";
getline(prod_file, line);
pos = line.find(product.NAME);
cout << "stignah\n";
if(pos != string::npos) {
prod_file << product.NAME;
prod_file << "-" << product.QUANTITY << "\n";
}
}
}
else {
cout << "Error: File inaccessible. (0x1)";
return 0;
}
cout << "Do you want to add more products? Y/N \n\n";
answer = 0;
while (answer != 'y' && answer != 'Y' && answer != 'n' && answer != 'N') {
answer = _getch();
}
}
while(answer == 'Y' || answer == 'y');
prod_file.close();
cout << "Entries added." << "\n\n";
return 0;
}
The idea of
size_t pos;
while(prod_file.good()) {
cout << "asd\n";
getline(prod_file, line);
pos = line.find(product.NAME);
cout << "stignah\n";
if(pos != string::npos) {
prod_file << product.NAME;
prod_file << "-" << product.QUANTITY << "\n";
}
}
Is to check for a certain string in a file and if it does not find the string to add to the file, if it finds it then it will not add it. Any idea why it fails the if?
You are opening prod_file for output only, not for input, so there is nothing for std::getline() to read from it.
You should NOT be trying to read from and write to the same file using a single stream. Open the original file for reading with one stream, and create a new file for writing with a separate stream. Use the first stream to scan the original file for existing entries, and use the second stream to write entries to the new file. When done, replace the original file with the new file if needed.
Try something like this:
#include <iostream>
#include <string>
#include <fstream>
#include <limits>
#include <cstdio>
using namespace std;
struct Product {
string Name;
int Quantity;
};
int main() {
string line;
char answer;
bool found, added = false, copyLines = true;
Product product;
ifstream prod_file("data/available.dat");
ofstream prod_file_new("data/available_new.dat", ios_base:::trunc);
do {
if (!prod_file || !prod_file_new) {
cerr << "Error: File inaccessible." << endl;
return 0;
}
do {
cout << "Molq vavedete imeto na produkta: " << endl;
if (!getline(cin, product.Name)) {
if (!cin.eof()) {
cerr << "Error: user input failure." << endl;
return 0;
}
break;
}
if (product.Name.length() <= 30) {
break;
}
cerr << "Product name cannot exceed 30 characters." << endl;
}
while (true);
if (cin.eof()) {
break;
}
if (product.Name.length() < 30) {
product.Name.append(30 - product.Name.length(), '.');
}
//
found = false;
do {
if (!getline(prod_file, line)) {
if (!prod_file.eof()) {
cerr << "Error: input file failure." << endl;
return 0;
}
break;
}
if (copyLines) {
if (!(prod_file_new << line << "\n")) {
cerr << "Error: output file failure." << endl;
return 0;
}
}
found = (line.find(product.Name) != string::npos);
}
while (!found);
if (!found) {
cout << "Molq vavedete kolichestvoto na produkta: " << endl;
if (!(cin >> product.Quantity)) {
cerr << "Error: user input failure." << endl;
return 0;
}
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if (!(prod_file_new << product.Name << "-" << product.Quantity << "\n")) {
cerr << "Error: output file failure." << endl;
return 0;
}
added = true;
}
cout << "Do you want to add another product? Y/N" << endl << endl;
cin >> answer;
while (answer != 'y' && answer != 'Y' && answer != 'n' && answer != 'N') {
cin >> answer;
}
if (answer != 'Y' && answer != 'y')
break;
if (!prod_file.seekg(0)) {
cerr << "Error: input file failure." << endl;
return 0;
}
copyLines = false;
}
while (true);
prod_file.close();
prod_file_new.close();
if (added) {
if (remove("data/available.dat") == 0) {
if (rename("data/available_new.dat", "data/available.dat") == 0) {
cout << "Entries added." << endl << endl;
}
else {
cerr << "Error: renaming available_new.dat to available.dat" << endl << endl;
}
}
else {
cerr << "Error: removing available.dat" << endl << endl;
}
}
else {
remove("data/available_new.dat");
cout << "No Entries added." << endl << endl;
}
return 0;
}
Alternatively, read the existing file into memory, and then search and append to that as needed, and then write out a new file only if entries have been added, eg:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <limits>
#include <cstdio>
using namespace std;
struct Product {
string Name;
int Quantity;
};
int main() {
string line;
char answer;
bool found, added = false;
Product product;
vector<Product> products;
ifstream prod_file("data/available.dat");
if (!prod_file) {
cerr << "Error: input file inaccessible." << endl;
return 0;
}
while (getline(prod_file, line)) {
istringstream iss(line);
if (!(getline(iss, product.Name, '-') && (iss >> product.Quantity))) {
cerr << "Error: input file malformed." << endl;
return 0;
}
products.push_back(product);
}
if (!prod_file) {
cerr << "Error: input file failure." << endl;
return 0;
}
prod_file.close();
do {
do {
cout << "Molq vavedete imeto na produkta: " << endl;
if (!getline(cin, product.Name)) {
if (!cin.eof()) {
cerr << "Error: user input failure." << endl;
return 0;
}
break;
}
if (product.Name.length() <= 30) {
break;
cerr << "Product name cannot exceed 30 characters." << endl;
}
while (true);
if (cin.eof()) {
break;
}
if (product.Name.length() < 30) {
product.Name.append(30 - product.Name.length(), '.');
}
//
found = std::find_if(products.begin(), products.end(),
[&](const Product &p){ return (p.Name == product.Name); }
) != products.end();
if (!found) {
cout << "Molq vavedete kolichestvoto na produkta: " << endl;
if (!(cin >> product.Quantity)) {
cerr << "Error: user input failure." << endl;
return 0;
}
cin.ignore(numeric_limits<streamsize>::max(), '\n');
products.push_back(product);
added = true;
}
cout << "Do you want to add another product? Y/N" << endl << endl;
cin >> answer;
while (answer != 'y' && answer != 'Y' && answer != 'n' && answer != 'N') {
cin >> answer;
}
if (answer != 'Y' && answer != 'y')
break;
}
while (true);
if (added) {
ofstream prod_file_new("data/available_new.dat", ios_base:::trunc);
if (!prod_file_new) {
cerr << "Error: output file inaccessible." << endl;
return 0;
}
for (auto &p : products) {
if (!(prod_file_new << p.Name << "-" << p.Quantity << "\n")) {
cerr << "Error: output file failure." << endl;
return 0;
}
}
prod_file_new.close();
if (remove("data/available.dat") == 0) {
if (rename("data/available_new.dat", "data/available.dat") == 0) {
cout << "Entries added." << endl << endl;
}
else {
cerr << "Error: renaming available_new.dat to available.dat" << endl << endl;
}
}
else {
cerr << "Error: removing available.dat" << endl << endl;
}
}
else {
cout << "No Entries added." << endl << endl;
}
return 0;
}

output within compiler and from exe file differs

i am using turbo c++. when i run the following code from compiler i get different answer at marked point in function result(int) then what i get from running .exe file created.
#include<fstream.h>
#include<conio.h>
#include<process.h>
#include<iomanip.h>
#include<string.h>
#include<stdio.h>
#include<dos.h>
ifstream fil;
int pos[50];
char date[11];
void exitt(int times = 0)
{
cout << endl << endl << " Enter 0 to exit." << endl;
if (times == 0)
cout << " Enter L to return to last screen." << endl;
}
void options();
void companychoose();
void companyscreen(int);
void write(int ch, int pos = 0) //add a check for duplicacy
{
ofstream fout;
clrscr();
if (ch == 1)
{
fout.open("database.dat", ios::binary | ios::app | ios::ate);
char companyname[20], temp;
exitt();
cout << " Enter Company name: ";
gets(companyname);
if (strcmp(companyname, "0") == 0)
exit(0);
else if (strcmp(companyname, "l") == 0)
options();
for (int i = 19; i>0; i--)
companyname[i] = companyname[i - 1];
companyname[0] = '%';
fout << endl;
fout << companyname;
fout.close();
cout << " Add data now?(y/n)" << endl;
askagain:
cin >> temp;
switch (temp)
{
case 'y':
fil.close();
write(2);
break;
case 'n':
options();
break;
default:
cout << " Invalid input" << endl;
goto askagain;
break;
}
}
}
void result(int ch)
{
int high[4], low[4], end, i = 0, enough = 0, temp = 0;
char check[20];
fil.open("database.dat", ios::binary);
fil.seekg(pos[ch], ios::beg);
fil >> check;
cout << endl;
if (check[0] == '%')
{
cout << " Not Enough Data!!!" << endl;
fil.close();
return;
}
while (!fil.eof())
{
if (i == 3)
{
i = 0;
enough = 1;
}
fil >> high[i] >> low[i] >> end >> check;
if (check[0] == '%')
break;
i++;
}
low[i] = 0;
temp = low[0];
if (enough == 0)
cout << " Not Enough Data!!!" << endl;
else
{
for (i = 0; i<3; i++)
{
if (low[i]<low[i + 1])
temp = low[i + 1];
}
if (temp>end)
cout << " Stock Running Low!!";
else if (temp = end)
cout << " Stock Is Stable";
else
cout << " Stock is HIGH!!";
cout << " " << end - temp << endl << endl << endl;
}
fil.close();
}
int read(int ch, int find = 0)
{
clrscr();
result(ch);
fil.open("database.dat", ios::binary);
fil.seekg(pos[ch], ios::beg);
char entry[20];
fil >> entry;
cout << setw(20) << "Date" << setw(10) << "High" << setw(10) << "Low" << setw(10) << "Close" << endl;
while (entry[0] != '%')
{
if (find == 1)
{
if (strcmp(entry, date))
return(fil.tellg() - 11);
else
continue;
}
cout << setw(20) << entry;
fil >> entry;
cout << setw(10) << entry;
fil >> entry;
cout << setw(10) << entry;
fil >> entry;
cout << setw(10) << entry << endl;
fil >> entry;
delay(500);
}
fil.close();
getch();
clrscr();
companyscreen(ch);
}
void edit(int ch)
{
cout << "Enter date of data to be edited";
gets(date);
write(2, read(ch, 1));
}
void companyscreen(int ch)
{
int ch1;
askagain:
result(ch);
cout << " 1. Add Data" << endl;
cout << " 2. Show history" << endl;
cout << " 3. Edit Data" << endl;
exitt();
ch1 = getch() - 48;
if (ch1 == 1)
write(2);
else if (ch1 == 2)
read(ch);
else if (ch1 == 3)
{
read(ch);
edit(ch);
}
else if (ch1 == 0)
{
cout << " exiting!!" << endl;
exit(500);
}
else if (ch1 == 60)
companychoose();
else
{
cout << " Invalid option chosen" << endl;
getch();
clrscr();
goto askagain;
}
}
void companychoose()
{
char name[20];
int i, ch;
clrscr();
fil.open("database.dat", ios::binary);
askagain:
fil.seekg(0, ios::beg);
cout << " Choose Company:";
cout << endl;
i = 1;
while (!fil.eof())
{
fil >> name;
if (name[0] == '%')
{
name[0] = ' ';
pos[i] = fil.tellg();
cout << setw(10) << i << "." << name << endl;
i++;
}
}
fil.close();
exitt();
ch = getch() - 48;
if (ch == 0)
exit(0);
else if (ch == 60)
options();
else if (ch>i)
{
cout << "Invalid choice" << endl;
getch();
clrscr();
goto askagain;
}
clrscr();
companyscreen(ch);
}
void options()
{
int ch;
clrscr();
askagain:
cout << endl << endl;
cout << " 1. Add company" << endl;
cout << " 2. Choose company" << endl;
exitt(1);
ch = getch() - 48;
if (ch == 1)
write(1);
else if (ch == 2)
companychoose();
else if (ch == 0)
{
cout << setw(10) << " Exiting!!";
exit(500);
}
else
{
cout << setw(10) << " Invalid choice chosen" << endl;
getch();
clrscr();
goto askagain;
}
}
void main()
{
clrscr();
textbackground(MAGENTA);
textcolor(WHITE);
clrscr();
options();
getch();
}
pls note that program is yet not fully complete so some features dont work.
i don't know how to include dat file data nor screenshot here.
i don't use visual c++ cause my pc is slow.
i don't use codeblocks cause i dont know how to use it. above code give hundreds of error even after adding "using namespace std;"
pls help me solve it. if you need anything else then ask me. thanks
I get different answer (…) in function result(int) then what I get from running .exe file created.
When you execute your program from the IDE a different working directory is used so different files are seemingly present/missing. Usually the working directory is configurable.
By the way, the goto is not needed. Really, it is not.

does not stop at, clearing cin creates infinite loop

I am a beginner at C++ and I have read various problems and solutions, but I still cannot get my code to work! The problem is that if i do not include the commented-out cin.clear() or cin.synch() my code does not stop at the beginning getline. When i do add them, it loops infinitely. Is there something that I am not including? Here is my source code:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string inputFileName, outputFileName, inData, outData, inWord, outWord;
ifstream inFile, testStream;
ofstream outFile;
bool outPutOpened = false;
char outChar;
int shiftNum = 0, idx = 0;
do {
inWord.clear();
outWord.clear();
//cin.clear();
//cin.sync();
cout << "Available options: " << endl;
cout << "1. ENCRYPT - Encrypt a file using Caesar Cypher" << endl // menu
<< "2. Quit - Exit the program" << endl << endl;
cout << " Enter keyword or option index: ";
getline(cin, inWord); // get option
outWord.resize(inWord.length());
transform(inWord.begin(), inWord.end(), outWord.begin(), ::toupper); //capitalize
if (outWord.compare("ENCRYPT") == 0 || outWord.compare("1") == 0) {
cout << "CAESAR CYPHER PROGRAM" << endl
<< "======================" << endl << endl;
do {
cout << "Provide the input file name: ";
getline(cin, inputFileName);
inFile.open(inputFileName.c_str());
if (inFile.fail()) {
cout << "Cannot open file, please try again!" << endl;
inFile.clear();
}
}
while (!inFile.is_open());
getline(inFile, inData);
do {
cout << "Provide the output file name: ";
cin >> outputFileName;
testStream.clear();
testStream.open(outputFileName.c_str());
if(testStream.good()) {
cout << "That file already exists, choose another" << endl;
testStream.clear();
testStream.close();
}
else {
testStream.clear();
testStream.close();
outFile.open(outputFileName.c_str());
if (outFile.good()) {
outPutOpened = true;
}
}
}
while (!outPutOpened);
cout << "Enter the shift number: ";
cin >> shiftNum;
for (idx = 0; idx <= inData.length() - 1; idx++) {
if (inData[idx] >= 'a' && inData[idx] <= 'z') {
outChar = (((inData[idx] - 'a') + shiftNum) % 26) + 'a';
outFile.put(outChar);
}
else if (inData[idx] >= 'A' && inData[idx] <= 'Z'){
outChar = (((inData[idx] - 'A') + shiftNum) % 26) + 'A';
outFile.put(outChar);
}
else {
outFile.put(inData[idx]);
}
}
}
else if (outWord.compare("2") == 0 || outWord.compare("QUIT") == 0) {
break;
}
else {
cout << inWord << " is an unrecognized option, please try again"
<< endl;
}
}
while (outWord.compare("2") || outWord.compare("QUIT"));
return 0;
}
The problem that in all your places where you use something like:
cin >> something;
the new line character remains in cin, so that what you will be reading next. Just every time you are finished reading from a line with this, write
string trash;
getline(cin, trash);
like:
cin >> something;
string trash;
getline(cin, trash);
and then the new line character won't remain in cin and you will start with a fresh line.