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;
}
Related
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;
};
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.
The part of code where I rename the file just won't work. I tried writing it separately in another project, it works. Help me please.
#include <iostream>
#include <stdio.h>
#include <fstream>
using namespace std;
int main () {
char address[] = "";
char newname[] = "";
int action;
char confirm;
int result;
cout << "File Manipulator 1.0" << endl;
cout << "--------------------" << endl << endl;
cout << "Type the full address of a file you wish to manipulate." << endl << endl;
ADDRESS:cin >> address;
fstream file(address);
if (!file.good()) {
cout << "The selected file does not exist! Try again. ";
goto ADDRESS;
} else {
cout << endl << "-----------------------------------" << endl;
cout << "Type 1 to move the selected file." << endl;
cout << "Type 2 to rename the selected file." << endl;
cout << "Type 3 to delete the selected file." << endl;
cout << "-----------------------------------" << endl << endl;
ACTION:cin >> action;
if (action == 1) {
cout << 1;
} else if (action == 2) {
cout << "Enter the new name: ";
cin >> newname;
cout << "Are you sure you want to rename the selected file? Y/N ";
CONFIRM:cin >> confirm;
if (confirm == 'Y' || 'y') {
result = rename(address, newname);
if (result == 0) {
cout << "renamed";
} else {
perror("not renamed");
}
} else if (confirm == 'N' || 'n') {
cout << "No";
} else {
cout << "You typed an invalid command! Try again. ";
goto CONFIRM;
}
} else if (action == 3) {
cout << 3;
} else {
cout << "You typed an invalid command! Try again." << endl;
goto ACTION;
}
}
return 0;
}
BTW the whole code is not finished, so check just the renaming part. Thanks.
Well, this is the solution.
#include <iostream>
#include <cstdio>
#include <fstream>
#include <string>
using namespace std;
int main() {
string address;
string newname;
Here you can see I used strings instead of char arrays.
char input;
int action;
char confirm;
int result;
cout << "File Manipulator 1.0" << endl;
cout << "--------------------" << endl << endl;
cout << "Type the full address of a file you wish to manipulate." << endl << endl;
getline(cin, address);
ifstream myfile(address.c_str());
I used ifstream with c_str() function which passes contents of a std::string into a C style string.
// try to open the file
if (myfile.is_open())
{
When the condition is met, you must close the opened file in order to be able to manipulate/work with it later.
myfile.close();
CREATE:cout << endl << "-----------------------------------" << endl;
cout << "Type 1 to move the selected file." << endl;
cout << "Type 2 to rename the selected file." << endl;
cout << "Type 3 to delete the selected file." << endl;
cout << "-----------------------------------" << endl << endl;
cin >> action;
switch (action)
{
case 1:
{
// do nothing.
}
break;
case 2:
{
// rename file.
cout << "Enter the new name" << endl << endl;
cin.ignore();
I used here the ignore() function to ignores the amount of characters I specify when I call it.
getline(cin, newname);
cout << "Are you sure you want ot rename the selected file ? Y/N" << endl << endl;
cin >> confirm;
if (confirm == 'Y' || confirm == 'y')
{
Same case with c_str() that i explained earlier.
rename(address.c_str(), newname.c_str());
}
}
break;
case 3:
{
// delete file.
remove(address.c_str());
}
break;
default:
{
cout << "You typed an invalid command!" << endl;
}
break;
}
}
else
{
cout << "The selected file does not exist! Would you like to create it? ";
cin >> input;
If the file name you input doesn't exist, you are prompted to create a file with the specified name, then you are redirected with goto to the manipulation menu.
if (input == 'y' || input == 'Y')
{
// create the file.
ofstream output(address.c_str());
output.close();
cout << "File created";
goto CREATE;
}
}
return 0;
}
Thanks for trying anyway :)
This compiles fine and works well with no spaces, but once I put spaces in it either tells me its not a palindrome or times out. Any help would be greatly appreciated!
int main( )
{
queue<char> q;
stack<char> s;
string the_string;
int mismatches = 0;
cout << "Enter a line and I will see if it's a palindrome:" << endl;
cin >> the_string;
int i = 0;
while (cin.peek() != '\n')
{
cin >> the_string[i];
if (isalpha(the_string[i]))
{
q.push(toupper(the_string[i]));
s.push(toupper(the_string[i]));
}
i++;
}
while ((!q.empty()) && (!s.empty()))
{
if (q.front() != s.top())
++mismatches;
q.pop();
s.pop();
}
if (mismatches == 0)
cout << "This is a palindrome" << endl;
else
cout << "This is not a palindrome" << endl;
system("pause");
return EXIT_SUCCESS;
}
Why so complicated?
You could simply do:
#include <string>
#include <algorithm>
bool is_palindrome(std::string const& s)
{
return std::equal(s.begin(), s.begin()+s.length()/2, s.rbegin());
}
Firstly the line
cin >> the_string;
does not get a whole line. Use this instead
getline(cin, the_string);
Secondly, while debugging your algorithm print lots of information out. For example, if you add the line
cout << "You entered: '" << the_string << "'" << endl;
you can easily see what string you're actually testing.
I got this solution to work just fine.
int main( )
{
queue<char> q;
stack<char> s;
string the_string;
int mismatches = 0;
cout << "Enter a line and I will see if it's a palindrome:" << endl;
int i = 0;
while (cin.peek() != '\n')
{
cin >> the_string[i];
if (isalpha(the_string[i]))
{
q.push(toupper(the_string[i]));
s.push(toupper(the_string[i]));
}
i++;
}
while ((!q.empty()) && (!s.empty()))
{
if (q.front() != s.top())
++mismatches;
q.pop();
s.pop();
}
if (mismatches == 0)
cout << "This is a palindrome" << endl;
else
cout << "This is not a palindrome" << endl;
system("pause");
return EXIT_SUCCESS;
}
void main()
{
queue<char> q;
stack<char> s;
char letter;
int mismatches = 0;
cout << "Enter a word and I will see if it's a palindrome:" << endl;
cin >> letter;
q.push(letter);
s.push(letter);
int i = 0;
while (cin.peek() != '\n')
{
cin >> letter;
if (isalpha(letter))
{
q.push(letter);
s.push(letter);
}
i++;
}
while ((!q.empty()) && (!s.empty()))
{
if (q.front() != s.top())
++mismatches;
q.pop();
s.pop();
}
if (mismatches == 0)
{
cout << "This is a palindrome" << endl;
}
else
{
cout << "This is not a palindrome" << endl;
}
cout << endl;
cout << "Homework done!" << endl;
cout << "You are Welcome!" << endl;
system("pause");
}
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.