First, thank for you all your help!
The error I am getting is:
Unhandled exception at 0x7c812afb
(kernel32.dll) in Readerboard.exe:
Microsoft C++ exception:
std::out_of_range at memory location
0x0012f8a8..
I have found the problem to be with this line:
str.replace(str.find(sought), sought.size(), replacement);
It is located in this procedure:
void DisplayMessages() {
ifstream myReadFile;
string str;
static string myMessages[10];
static int i; // of course my famous i
static int MyPosition;
string sought;
string replacement;
myReadFile.open("C:\\Documents and Settings\\agerho000\\Desktop\\cms_export_test\\outages.htm",ios::in);
i = 0; //the start of my array
sought = "</td>"; // value that I want to replace with nothing
replacement.clear();
if(!myReadFile) // is there any error?
{
cout << "Error opening the file! Aborting…\n";
exit(1);
}
if (myReadFile.is_open())
{
cout << endl;
while (!myReadFile.eof())
{
getline(myReadFile, str);
if (str == "<tr>")
{
myReadFile.seekg(4,ios::cur);
getline(myReadFile, str);
str.replace(str.find(sought), sought.size(), replacement);
cout << str;
myMessages[i]=str;
i++;
}
}
}
i=0;
while (i < 10)
{
cout << i << ") " << myMessages[i] << endl;
i++;
if (myMessages[i]=="")
{
break;
}
}
myReadFile.close();
mainMenu();
}
The whole cpp file is displayed below:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void mainMenu();
void DisplayMessages();
void AddMessage();
void DeleteMessage();
void EditMessage();
void RunTests();
void CheckFile();
void CreateHtmlFile(string myMessages[10]);
/*
#define MIN 1
#define MAX 100
#define TRUE 1
#define FALSE 0
*/
int main() {
cout << endl;
cout << endl;
cout << "Hello Andrew.\n";
cout << "First you need some sort of menu.\n";
mainMenu();
return 0;
}
void mainMenu() {
int Command;
cout << endl;
cout << endl;
cout << endl;
cout << "What would you like to do?\n";
// cout << "1) Check that tests work!\n";
// cout << "2) Check that the file exists\n";
cout << "3) Display Messages\n";
// cout << "4) Edit a message\n";
// cout << "5) Add a message\n";
// cout << "6) Delete a message\n";
cout << "7) Exit\n";
cout << "Enter a number: ";
cin >> Command;
if (Command == 3)
{
DisplayMessages();
}
if (Command == 7)
{
cout << "Exiting...";
exit(EXIT_SUCCESS);
}
if (Command == 6)
{
DisplayMessages();
}
}
void DisplayMessages() {
ifstream myReadFile;
string str;
static string myMessages[10];
static int i; // of course my famous i
static int MyPosition;
string sought;
string replacement;
myReadFile.open("C:\\Documents and Settings\\agerho000\\Desktop\\cms_export_test\\outages.htm",ios::in);
i = 0; //the start of my array
sought = "</td>"; // value that I want to replace with nothing
replacement.clear();
if(!myReadFile) // is there any error?
{
cout << "Error opening the file! Aborting…\n";
exit(1);
}
if (myReadFile.is_open())
{
cout << endl;
while (!myReadFile.eof())
{
getline(myReadFile, str);
if (str == "<tr>")
{
myReadFile.seekg(4,ios::cur);
getline(myReadFile, str);
str.replace(str.find(sought), sought.size(), replacement);
cout << str;
myMessages[i]=str;
i++;
}
}
}
i=0;
while (i < 10)
{
cout << i << ") " << myMessages[i] << endl;
i++;
if (myMessages[i]=="")
{
break;
}
}
myReadFile.close();
mainMenu();
}
void AddMessage() {
}
/*
void DeleteMessage() {
ifstream myReadFile;
string str;
static string myMessages[10];
static int i; // of course my famous i
static int MyPosition;
string sought;
string replacement;
static int Command;
myReadFile.open("C:\\Documents and Settings\\agerho000\\Desktop\\cms_export_test\\outages.htm",ios::in);
i = 0; //the start of my array
sought = "</b></td>"; // value that I want to replace with nothing
replacement.clear();
if(!myReadFile) // is there any error?
{
cout << "Error opening the file! Aborting…\n";
exit(1);
}
if (myReadFile.is_open())
{
cout << endl;
while (!myReadFile.eof())
{
getline(myReadFile, str);
if (str == "<tr>")
{
myReadFile.seekg(7,ios::cur);
getline(myReadFile, str);
str.replace(str.find(sought), sought.size(), replacement);
myMessages[i]=str;
i++;
}
}
}
i=0;
while (i < 10)
{
cout << i << ") " << myMessages[i] << endl;
i++;
if (myMessages[i]=="")
{
break;
}
}
myReadFile.close();
cout << "Enter the number of the message you would like to delete?\n";
cout << "Or enter 11 to go back to the main menu.\n";
cin >> Command;
while (Command >= 12)
{
cout << "Invalid number, try again!\n";
cout << endl;
cout << "Enter the number of the message you would like to delete?\n";
cout << "Or enter 11 to go back to the main menu.\n";
cin >> Command;
}
if (Command == 11)
{
mainMenu();
}
myMessages[Command].clear();
//clear the string
//now rebuild the htm file with the new array
CreateHtmlFile(myMessages);
}
void EditMessage() {
}
void RunTests() {
}
void CheckFile() {
}
void CreateHtmlFile(string myMessages[])
{
}
//File.seekg(-5); moves the inside pointer 5 characters back
//File.seekg(40); moves the inside pointer 40 characters forward
//tellg() Returns an int type, that shows the current position of the inside-pointer for reading
//tellp() same as above but for writing
//seekp() just like seekg() but for writing
*/
Please help I am so stumped!
str.replace(str.find(sought), sought.size(), replacement); is wrong when str.find() doesn't find what it's looking for. str.find() will return str::npos, which will not be a valid location in the string. Hence, the call to replace fails with the index out of range exception you're seeing.
Change that to:
std::size_t foundIndex = str.find(sought);
if (foundIndex != str.npos)
str.replace(foundIndex, sought.size(), replacement);
else
std::cout << "Oops.. didn't find " << sought << std::endl;
and let us know if that helps you.
EDIT: You might also want to consider using boost::algorithm::replace_all from the Boost String Algorithms Library
A complete function for replacing strings:
std::string ReplaceString(std::string subject, const std::string& search,
const std::string& replace) {
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
return subject;
}
If you need performance, here is an optimized function that modifies the input string, it does not create a copy of the string:
void ReplaceStringInPlace(std::string& subject, const std::string& search,
const std::string& replace) {
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
}
Tests:
std::string input = "abc abc def";
std::cout << "Input string: " << input << std::endl;
std::cout << "ReplaceString() return value: "
<< ReplaceString(input, "bc", "!!") << std::endl;
std::cout << "ReplaceString() input string not modified: "
<< input << std::endl;
ReplaceStringInPlace(input, "bc", "??");
std::cout << "ReplaceStringInPlace() input string modified: "
<< input << std::endl;
Output:
Input string: abc abc def
ReplaceString() return value: a!! a!! def
ReplaceString() input string not modified: abc abc def
ReplaceStringInPlace() input string modified: a?? a?? def
Related
I got a function but i can't define any variable inside and global too. This function gets a char value from user. I need to define this value to main function. How can i do it? Thanks for helping guys.
This is my code. I made it like this but I define variables in global but I need to define this variables in only main.
#include <iostream>
using namespace std;
char cName[255], cSurname[255];
bool nameFunc() {
cout << "Whats Your Name ?\n";
cin >> cName;
if (cName != NULL && cName[0] == '\0') {
return false;
}
else {
return true;
}
}
bool surnameFunc() {
cout << "Whats Your Surname ?\n";
cin >> cSurname;
if (cSurname != NULL && cSurname[0] == '\0') {
return false;
}
else {
return true;
}
}
int main() {
if (nameFunc() and surnameFunc()) {
cout << "Hello, " << cName << " " << cSurname << "." << endl;
}
else {
cout << "Error! Name or Surname is empty." << endl;
}
system("PAUSE");
return 0;
}
You could pass references to your variables to the functions. Since the char[] have a fixed length, you need to make sure that you don't write out-of-bounds which complicates things.
Example:
#include <iostream>
template<size_t N>
bool nameFunc(char (&cName)[N]) {
std::cout << "Whats Your Name ?\n";
std::cin.getline(cName, N); // read at most N chars
return cName[0] != '\0';
}
template<size_t N>
bool surnameFunc(char (&cSurname)[N]) {
std::cout << "Whats Your Surname ?\n";
std::cin.getline(cSurname, N); // read at most N chars
return cSurname[0] != '\0';
}
int main() {
char cName[255], cSurname[255];
if (nameFunc(cName) and surnameFunc(cSurname)) {
std::cout << "Hello, " << cName << " " << cSurname << ".\n";
}
else {
std::cout << "Error! Name or Surname is empty.\n";
}
}
A much easier option would be to use std::strings and pass them by reference to the functions.
Is it what you're looking for?
#include <iostream>
using namespace std;
bool nameFunc(char* cName) {
cout << "Whats Your Name ?\n";
cin >> cName;
if (cName != NULL && cName[0] == '\0') {
return false;
}
else {
return true;
}
}
bool surnameFunc(char* cSurname) {
cout << "Whats Your Surname ?\n";
cin >> cSurname;
if (cSurname != NULL && cSurname[0] == '\0') {
return false;
}
else {
return true;
}
}
int main() {
char cName[255], cSurname[255];
if (nameFunc(cName) and surnameFunc(cSurname)) {
cout << "Hello, " << cName << " " << cSurname << "." << endl;
}
else {
cout << "Error! Name or Surname is empty." << endl;
}
system("PAUSE");
return 0;
}
I asked this question a couple of hours ago; I want to see if someone can now explain the problem.
One code is about separating items in a grocery; in the end you'll have two(2) bags; a fragileBag and a normalBag.
Other code separates passengers depending on the office they go for pickup; in the end you'll have three(3) types of passengers; ones that go to rio, ones that go to maya, and ones that request elsewhere.
Both codes use the same logic but the passenger code gives an error on a line that works perfectly on the grocery code.
Just to be clear, BOTH CODES RETURN VALUES OF STRING.
ERROR FROM THE PASSENGER CODE:
Error (active) E0304 no instance of overloaded function "std::vector<_Ty,_Alloc>::push_back [with _Ty=trans, _Alloc=std::allocator<trans>]" matches the argument list dataPractice2 C:\Users\javye\source\repos\dataPractice2\dataPractice2\main.cpp 82
and also:
Error C2664 'void std::vector<trans,std::allocator<_Ty>>::push_back(_Ty &&)': cannot convert argument 1 from 'std::string' to 'const _Ty &' dataPractice2 c:\users\javye\source\repos\datapractice2\datapractice2\main.cpp 82
//GROCERY FUNCTION
//separate function
void separateItems(vector<myBag>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getItem() == "eggs" || newMyVector[x].getItem() == "bread") {
fragileBag.push_back(newMyVector[x].getItem()); //NO PROBLEM HERE
newMyVector.pop_back();
}
else {
normalBag.push_back(newMyVector[x].getItem()); //OR HERE
newMyVector.pop_back();
}
}
}
//PASSENGER FUNCTION
//separate function
void separateP(vector<trans>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getXoLoc() == "rio") {
rioLoc.push_back(newMyVector[x].getXoLoc()); //PROBLEM HERE
newMyVector.pop_back();
}
else
if (newMyVector[x].getXoLoc() == "maya") {
mayaLoc.push_back(newMyVector[x].getXoLoc()); //HERE
newMyVector.pop_back();
}
else
elseLoc.push_back(newMyVector[x].getXoLoc()); //HERE
newMyVector.pop_back();
}
}
//GROCERY FULL CODE
//HEADER
#pragma once
#include<iostream>
#include<vector>
#include<string>
using namespace std;
#ifndef BAG_H
#define BAG_H
class myBag {
public:
myBag(); //default constructor
myBag(string anItemName); //overload constructor
void addItem(string anItemName); //mutator
string getItem();//accessor
private:
string itemName;
};
#endif
//SOURCE
#include"bag.h"
myBag::myBag() {
addItem("");
}
myBag::myBag(string anItemName) {
addItem(anItemName);
}
void myBag::addItem(string anItemName) {
itemName = anItemName;
}
string myBag::getItem() {
return itemName;
}
//MAIN
#include"bag.h"
void inputItems(vector<myBag>&); //input data function prototype
void displayQuantity(vector<myBag>&); //display data function prototype
void separateItems(vector<myBag>&); //function that separates items; func prototype
void fragBag(vector<myBag>&); //fragile bag function prototype
void norBag(vector<myBag>&); //normal bag function prototype
vector<myBag> myVector; //main vector
vector<myBag> fragileBag, normalBag; //seconday vectors
string item; //global item variable
int main() {
int option;
try {
do {
cout << "\tMENU"
<< endl << "1) Input Items"
<< endl << "2) Display Quantity"
<< endl << "3) Separate (IMPORTANT)"
<< endl << "4) Display Items in Fragile Bag"
<< endl << "5) Display Items in Normal Bag"
<< endl << "6) Exit Program"
<< endl << endl << "Choose: ";
cin >> option;
if (option > 6) {
throw 404;
}
switch (option) {
case 1: //input
system("cls");
inputItems(myVector);
system("pause");
system("cls");
break;
case 2://display
system("cls");
displayQuantity(myVector);
system("pause");
system("cls");
break;
case 3: //separate
system("cls");
separateItems(myVector);
system("pause");
system("cls");
break;
case 4: //fragile
system("cls");
fragBag(myVector);
system("pause");
system("cls");
break;
case 5: //normal
system("cls");
norBag(myVector);
system("pause");
system("cls");
break;
case 6: //exit
exit(0);
}
} while (option != 6);
}
catch(int x){
cout << "ERROR, OPTION DOESN'T EXITS" << endl;
system("pause");
}
}
//input function
void inputItems(vector<myBag>& newMyVector) {
do {
cout << "Enter grocery items || enter letter X to stop: ";
cin >> item;
if (item != "x")
newMyVector.push_back(myBag(item));
} while (item != "x");
}
//display function
void displayQuantity(vector<myBag>& newMyVector) {
try {
for (int x = 0; x < newMyVector.size(); ++x) {
if (x == 0) {
cout << "Store bag has " << newMyVector.size() << " items in it. These are: " << endl;
}
cout << newMyVector[x].getItem() << endl;
}
if (newMyVector.empty())
throw 404;
}
catch (int x) {
cout << "ERROR " << x << " ,QUANTITY NOT FOUND" << endl;
}
}
//separate function
void separateItems(vector<myBag>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getItem() == "eggs" || newMyVector[x].getItem() == "bread") {
fragileBag.push_back(newMyVector[x].getItem()); //PROBLEM WOULD APPEAR HERE, BUT DOESN'T, UNLIKE THE OTHER CODE
newMyVector.pop_back();
}
else {
normalBag.push_back(newMyVector[x].getItem());
newMyVector.pop_back();
}
}
}
//fragile bag function
void fragBag(vector<myBag>& newMyVector) {
try {
for (int x = 0; x < fragileBag.size(); ++x) {
if (x == 0) {
cout << "The fragile bag has " << fragileBag.size() << " items in it. These are: " << endl;
}
cout << fragileBag[x].getItem() << endl;
}
if (fragileBag.empty()) {
throw 404;
}
}
catch (int x) {
cout << "ERROR " << x << " ,FRAGILE BAG EMPTY" << endl;
}
}
//normal bag function
void norBag(vector<myBag>& newMyVector) {
try {
for (int x = 0; x < normalBag.size(); ++x) {
if (x == 0) {
cout << "The normal bag has " << normalBag.size() << " items in it. These are: " << endl;
}
cout << normalBag[x].getItem() << endl;
}
if (normalBag.empty()) {
throw 404;
}
}
catch (int x) {
cout << "ERROR " << x <<" , NORMAL BAG EMPTY" << endl;
}
}
//PASSENGER FULL CODE
//HEADER
#pragma once
#include<iostream>
#include<vector>
#include<string>
using namespace std;
#ifndef TRANSPORT_H
#define TRANSPORT_H
class trans {
public:
trans();
trans(string aName, string anXoLoc, string anXfLoc, string aTime, string aCellNum);
void setName(string aName);
void setXoLoc(string anXoLoc);
void setXfLoc(string anXfLoc);
void setTime(string aTime);
void setCellNum(string aCellNum);
string getName();
string getXoLoc();
string getXfLoc();
string getTime();
string getCellNum();
private:
string name;
string xoLoc; //offices
string xfLoc; //destination
string time;
string cellNum;
};
//SOURCE
#include"transport.h"
trans::trans() {
setName("");
setXoLoc("");
setXfLoc("");
setTime("");
setCellNum("");
}
trans::trans(string aName, string anXoLoc, string anXfLoc, string aTime, string aCellNum) {
setName(aName);
setXoLoc(anXoLoc);
setXfLoc(anXfLoc);
setTime(aTime);
setCellNum(aCellNum);
}
void trans::setName(string aName) {
name = aName;
}
void trans::setXoLoc(string anXoLoc) {
xoLoc = anXoLoc;
}
void trans::setXfLoc(string anXfLoc) {
xfLoc = anXfLoc;
}
void trans::setTime(string aTime) {
time = aTime;
}
void trans::setCellNum(string aCellNum) {
cellNum = aCellNum;
}
string trans::getName() {
return name;
}
string trans::getXoLoc() {
return xoLoc;
}
string trans::getXfLoc() {
return xfLoc;
}
string trans::getTime() {
return time;
}
string trans::getCellNum() {
return cellNum;
}
#endif
//MAIN
#include"transport.h"
void inputInfo(vector<trans> &);
void displayInput(vector<trans>&);
void separateP(vector<trans>&);
void rio(vector<trans>&);
void maya(vector<trans>&);
void elsewhere(vector<trans>&);
vector<trans> myVector;
vector<trans> rioLoc, mayaLoc, elseLoc;
string newName;
string newXoLoc; //offices
string newXfLoc; //destination
string newTime;
string newCellNum;
//main not ready. Creating each function one by one to them make it look nice
int main() {
int option;
do {
cout << "MENU"
<< endl << "1) input "
<< endl << "2) output "
<< endl << "3) separate"
<< endl << "4) rio passengers"
<< endl << "5) maya passengers"
<< endl << "6) elsewhere passengers";
cin >> option;
switch(option){
case 1:
inputInfo(myVector);
break;
case 2:
displayInput(myVector);
break;
case 3:
separateP(myVector);
break;
case 4:
rio(myVector);
break;
case 5:
maya(myVector);
break;
case 6:
elsewhere(myVector);
break;
case 7:
exit(0);
}
} while (option != 7);
system("pause");
}
void inputInfo(vector<trans> &newMyVector) {
int charSize;
cout << "How many passangers to register: ";
cin >> charSize;
for (int x = 0; x < charSize; ++x) {
cout << "Name of passanger: ";
cin >> newName;
cout << "Office: ";
cin >> newXoLoc;
cout << "Destination: ";
cin >> newXfLoc;
cout << "Time of pickup: ";
cin >> newTime;
cout << "Cellphone: ";
cin >> newCellNum;
if (charSize != 0)
newMyVector.push_back(trans(newName, newXoLoc, newXfLoc, newTime, newCellNum));
}
}
void displayInput(vector<trans>& newMyVector) {
for (int x = 0; x < newMyVector.size(); ++x) {
if (x == 0) {
cout << "There are " << newMyVector.size() << " passengers. These are: " << endl;
}
cout << "-----------------------------Passenger #" << x + 1 << endl;
cout << newMyVector[x].getName() << endl;
cout << newMyVector[x].getXoLoc() << endl;
cout << newMyVector[x].getXfLoc() << endl;
cout << newMyVector[x].getTime() << endl;
cout << newMyVector[x].getCellNum() << endl;
}
}
void separateP(vector<trans>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getXoLoc() == "rio") {
rioLoc.push_back(newMyVector[x]);
newMyVector.pop_back();
}
else
if (newMyVector[x].getXoLoc() == "maya") {
mayaLoc.push_back(newMyVector[x]);
newMyVector.pop_back();
}
else
elseLoc.push_back(newMyVector[x]);
newMyVector.pop_back();
}
}
void rio(vector<trans>& newMyVector) {
for (int x = 0; x < rioLoc.size(); ++x) {
if (x == 0) {
cout << "Num. of passangers to pickup in Rio Piedras is " << rioLoc.size() << " , these are: " << endl;
}
cout << rioLoc[x].getName() << endl;
cout << rioLoc[x].getXoLoc() << endl;
cout << rioLoc[x].getXfLoc() << endl;
cout << rioLoc[x].getTime() << endl;
cout << rioLoc[x].getCellNum() << endl;
}
}
void maya(vector<trans>& newMyVector) {
for (int x = 0; x < mayaLoc.size(); ++x) {
if (x == 0) {
cout << "Num. of passangers to pickup in Mayaguez is " << mayaLoc.size() << " , these are: " << endl;
}
cout << mayaLoc[x].getName() << endl;
cout << mayaLoc[x].getXoLoc() << endl;
cout << mayaLoc[x].getXfLoc() << endl;
cout << mayaLoc[x].getTime() << endl;
cout << mayaLoc[x].getCellNum() << endl;
}
}
void elsewhere(vector<trans>& newMyVector) {
for (int x = 0; x < elseLoc.size(); ++x) {
if (x == 0) {
cout << "Num. of passangers to pickup in elsewhere is " << elseLoc.size() << " , these are: " << endl;
}
cout << elseLoc[x].getName() << endl;
cout << elseLoc[x].getXoLoc() << endl;
cout << elseLoc[x].getXfLoc() << endl;
cout << elseLoc[x].getTime() << endl;
cout << elseLoc[x].getCellNum() << endl;
}
}
To explain why the second code does not work I first have to explain why the first code appears to work.
myBag::myBag(string anItemName)
can make a bag out of a string. It is a Conversion Constructor. So when
fragileBag.push_back(newMyVector[x].getItem());
is compiled, the compiler quietly inserts a call to the myBag(string) constructor and you get something more like
fragileBag.push_back(myBag(newMyVector[x].getItem()));
which makes no sense logically. It says turn an item in a bag into a bag with one item and insert this new bag into still another bag, fragileBag.
When you look more closely at myBag, you see that it isn't a bag at all. It is a single item and should be renamed to myItem or discarded all together in favour of an all-new all-different myBag that is a wrapper around a vector of string where the strings represent items. This makes
myBag fragileBag;
the real bag.
In other words, the only reason the working code works is it doesn't actually do what the naming implies it does. The code compiles and produces the expected result, but is semantically troubled.
This leads to the confusion with
rioLoc.push_back(newMyVector[x].getXoLoc());
rioLoc is a vector<trans> and can only hold trans. There is no trans::trans(string) to convert a string to a trans so the faulty logic of the grocery code is exposed. As bag and item have been intertwined in grocery, passenger and transport are combined here.
The fix for grocery described above is relatively straight forward. Passenger will need a slightly different solution with both a passenger class to describe the passengers and a transport class to describe the means of transport. transport will have a vector<passenger> member to contain its passengers as well as methods to add and remove the passengers and possibly book-keeping to track the location of the transport, details incompletely specified by the question.
Both codes are pushing string values into a vector that does not hold string values.
Your grocery code uses a vector of myBag objects. The code works because myBag has a non-explicit constructor that takes a single string as input, so the compiler is able to implicitly construct a temporary myBag object to push into the vector.
Your passenger code uses a vector of trans objects. The code fails because trans does not have a constructor that takes a single string as input, so the compiler cannot construct a temporary trans to push into the vector.
ERRORS:
error messages
mainFun.cpp:
#include <iostream>
#include <string>
#include "userCheckFunH.h"
using namespace std;
int yesNo;
string passName;
string userName;
string userRetrieve()
{
if (userName == "")
{
cin >> userName;
}
else
{
if (userName == "devin772" || userName == "guestacc")
{
yesNo = 1;
}
else
{
yesNo = 0;
}
}
return userName;
}
int userCheck()
{
return yesNo;
}
int main()
{
do
{
string userN;
system("cls");
// ui
cout << " DH DB " << endl;
cout << "x----------------x" << endl;
//username
cout << "username: " << endl;
cout << "> ";
// fun call
userRetrieve();
int continueP = userCheck();
cout << "" << endl;
// password
if (continueP = 1 && userRetrieve() == "devin772")
{
cout << "password:" << endl;
cout << "> ";
cin >> passName;
if (passName == "12qwaszx")
{
cout << "" << endl;
system("pause");
system("cls");
// run program
dataBaseRunP("admin");
npOpen();
cout << "" << endl;
system("pause");
return 0;
}
}
else if (continueP = 1 && userRetrieve() == "guestacc")
{
cout << "password:" << endl;
cout << "> ";
cin >> passName;
if (passName == "guestguest")
{
cout << "" << endl;
system("pause");
system("cls");
// run program
dataBaseRunP("regUser");
npOpen();
cout << "" << endl;
system("pause");
return 0;
}
}
else
{
cout << "Invalid username." << endl;
cout << "" << endl;
system("pause");
userRetrieve() = "";
userName = "";
yesNo = 0;
passName = "";
}
} while (true);
system("pause");
}
nextFun.cpp :
#include <iostream>
#include "userCheckFunH.h"
using namespace std;
string userLevel;
int dataBaseRunP(string authLevel)
{
string fileName;
if (authLevel == "regUser")
{
fileName = "user.txt";
userLevel = fileName;
}
else if (authLevel == "admin")
{
fileName = "admin.txt";
userLevel = fileName;
}
else
{
cout << "ERROR - user level not found." << endl;
system("pause");
exit(EXIT_FAILURE);
return 0;
}
exit(EXIT_SUCCESS);
return 0;
}
void npOpen()
{
string fileNpName;
fileNpName = userLevel;
fileNpName = "notepad \"" + fileNpName + "\"";
system(fileNpName.c_str());
}
userCheckFunH.h:
#ifndef USERCHECKFUN_H
#define USERCHECKFUN_H
#include "nextFun.cpp"
int dataBaseRunP();
void npOpen();
#endif
i'm attempting to make a basic program that allows you to open files hidden through windows in a basic c++ program. keep getting this error. tried different header guards, variable names, function names, file names. i also delete nextFun.cpp and the program ran fine. i can't get past this error, please help.
thanks! :)
It is highly unusual to include a cpp file, which you do in userCheckFunH.h, with
#include "nextFun.cpp"
Your nextFun.cpp file includes this very header:
#include "userCheckFunH.h"
Since you cpp file doesn't have an include guard (which is fine) you end up with the functions in the cpp file twice.
Don't include the cpp file in the header.
While working on this project for my younger cousin, I encountered many difficulties. I was wondering if someone could help me use char to output complete sentences (or help me fix these bugs.) I'm a relatively new programmer (about 8 months). Here's my code/ what I have attempted. Most of the bugs cause the program to freeze once a sentence is imputed, or the files not responding when opened.
#include<iostream>
#include<fstream>
#include<cctype>
#include<iomanip>
class legoset
{
char setcatname[25];
char name[50];
char legoinclude[25];
char legotype[25];
public:
void create_category();
void show_category() const;
void modify();
void report() const;
int retacno() const;
};
void legoset::create_category()
{
std::cout << "Please enter a category name : \n";
std::cin >> setcatname;
//std::cin.getline(setcatname, 25);
std::cout << "Please enter your username! \n";
std::cin >> name;
std::cin.ignore();
std::cin.getline(name, 50);
std::cout << name << " , is it a vehicle or building (V/B)?\n";
std::cin >> legotype;
legotype[25] = toupper(legotype[25]);
std::cin.getline(legotype, 25);
std::cout << "\n Please enter the name of the lego set. \n";
std::cin >> legoinclude;
//std::cin.getline(legoinclude, 25);
std::cout << "\n\n Category Created Successfully!!!";
return;
}
void legoset::show_category() const
{
std::cout << "Category : \n" << setcatname;
std::cout << "Username Of Holder \n: " << name;
std::cout << " Lego type (B/V) : " << legotype;
std::cout << " Lego set (with details) : " << legoinclude;
return;
}
void legoset::modify()
{
std::cout << "Category : \n" << setcatname[25];
std::cout << "\nModify Holder's name : ";
std::cin.ignore();
std::cin.getline(name, 50);
std::cout << "\nModify A Building or vehicle class ( B/V ) : ";
std::cin >> legotype[25];
legotype[25] = toupper(legotype[25]);
std::cout << "\nModify Lego set (with details) : ";
std::cin >> legoinclude[25];
}
void legoset::report() const
{
std::cout << setcatname[25] << std::setw(10) << " " << name << std::setw(10) << " " << legotype[25] << std::setw(6) << legoinclude[25] << std::endl;
}
int legoset::retacno() const
{
return setcatname[25];
}
void write_legoset(); //function to write record in binary file
void display_sp(int); //function to display account details given by user
void modify_set(int); //function to modify record of file
void delete_set(int); //function to delete record of file
void display_all(); //function to display all account details
void intro(); //introductory screen function
int main()
{
char choice;
int num;
intro();
do
{
system("cls");
std::cout << "\n\n\n\tMAIN MENU";
std::cout << "\n\n\t01. New Category";
std::cout << "\n\n\t02. ADD A NEW SET";
std::cout << "\n\n\t03. ALL USERS HOLDER LIST";
std::cout << "\n\n\t04. DELETE A CATEGORY";
std::cout << "\n\n\t05. MODIFY A CATEGORY";
std::cout << "\n\n\t06. EXIT";
std::cout << "\n\n\tSelect Your Option (1-6) ";
std::cin >> choice;
system("cls");
switch (choice)
{
case '1':
write_legoset();
break;
case '2':
std::cout << "\n\n\tEnter The category Name : "; std::cin >> num;
display_sp(num);
break;
case '3':
display_all();
break;
case '4':
std::cout << "\n\n\tEnter The Category Name : "; std::cin >> num;
delete_set(num);
break;
case '5':
std::cout << "\n\n\tEnter The Category Name : "; std::cin >> num;
modify_set(num);
break;
case '6':
std::cout << "\n\n\tThanks for using lego managemnt system!";
std::exit;
break;
default: std::cout << "\a";
}
std::cin.ignore();
std::cin.get();
} while (choice != '6');
return 0;
}
//***************************************************************
// function to write in file
//****************************************************************
void write_legoset()
{
legoset lego;
std::ofstream outFile;
outFile.open("legoset.dat", std::ios::binary | std::ios::app);
lego.create_category();
outFile.write(reinterpret_cast<char *> (&lego), sizeof(legoset));
outFile.close();
}
//***************************************************************
// function to read specific record from file
//****************************************************************
void display_sp(int n)
{
legoset lego;
bool flag = false;
std::ifstream inFile;
inFile.open("legoset.dat", std::ios::binary);
if (!inFile)
{
std::cout << "File could not be open !! Press any Key...";
return;
}
std::cout << "\nLEGOSET DETAILS\n";
while (inFile.read(reinterpret_cast<char *> (&lego), sizeof(legoset)))
{
if (lego.retacno() == n)
{
lego.show_category();
flag = true;
}
}
inFile.close();
if (flag == false)
std::cout << "\n\nLego set does not exist in this file";
}
//***************************************************************
// function to modify record of file
//****************************************************************
void modify_set(int n)
{
bool found = false;
legoset lego;
std::fstream File;
File.open("legoset.dat", std::ios::binary | std::ios::in | std::ios::out);
if (!File)
{
std::cout << "File could not be open !! Press any Key...";
return;
}
while (!File.eof() && found == false)
{
File.read(reinterpret_cast<char *> (&lego), sizeof(legoset));
if (lego.retacno() == n)
{
lego.show_category();
std::cout << "\n\nPlease Enter The New Details For This Category." << std::endl;
lego.modify();
int pos = (-1)*static_cast<int>(sizeof(legoset));
File.seekp(pos, std::ios::cur);
File.write(reinterpret_cast<char *> (&lego), sizeof(legoset));
std::cout << "\n\n\t Category Updated!";
found = true;
}
}
File.close();
if (found == false)
std::cout << "\n\n Category Not Found ";
}
//***************************************************************
// function to delete record of file
//****************************************************************
void delete_set(int n)
{
legoset lego;
std::ifstream inFile;
std::ofstream outFile;
inFile.open("legoset.dat", std::ios::binary);
if (!inFile)
{
std::cout << "File could not be open !! Press any Key...";
return;
}
outFile.open("Temp.dat", std::ios::binary);
inFile.seekg(0, std::ios::beg);
while (inFile.read(reinterpret_cast<char *> (&lego), sizeof(legoset)))
{
if (lego.retacno() != n)
{
outFile.write(reinterpret_cast<char *> (&lego), sizeof(legoset));
}
}
inFile.close();
outFile.close();
remove("legoset.dat");
rename("Temp.dat", "legoset.dat");
std::cout << "\n\n\tCategory Deleted ..";
}
//***************************************************************
// function to display all accounts deposit list
//****************************************************************
void display_all()
{
legoset lego;
std::ifstream inFile;
inFile.open("legoset.dat", std::ios::binary);
if (!inFile)
{
std::cout << "File could not be open !! Press any Key...";
return;
}
std::cout << "\n\n\t\tUSER HOLDER LIST\n\n";
std::cout << "====================================================\n";
std::cout << "A/c no. NAME Type Balance\n";
std::cout << "====================================================\n";
while (inFile.read(reinterpret_cast<char *> (&lego), sizeof(legoset)))
{
lego.report();
}
inFile.close();
}
void intro()
{
std::cout << "\n\n\n\t LEGOSET";
std::cout << "\n\n\tMANAGEMENT";
std::cout << "\n\n\t SYSTEM";
std::cout << "\n\n\n\nMADE BY : Philippe Barry";
std::cin.get();
}
//***************************************************************
// END OF PROJECT
//***************************************************************
Note that array indices in C++ go from 0 to one less than the array size. Thus index 0 is the first element, index 1 is the second, etc. Thus if you declare a char array to be size 25, then accessing index 25 is past the end of the array and results in undefined behavior — your program may crash, freeze up, or literally anything else. Additionally, accessing index 24 would just give you the “null character” that comes after every string. If you’re sure that the input will be 24 characters long (and you shouldn’t be), then index 23 would contain the last character.
You really shouldn’t be using static-length char arrays in C++, anyway. Your current code, even if it worked most of the time with the char arrays, would fail when the input string was larger than the size of the array. Replace the types of all the char arrays with std::string, and the input function should work.
Furthermore, as Sam Varsavchik nicely put, don’t write an entire program at once. That makes it a nightmare to debug. Write your code in chunks — first write the input function, and a debug function that prints out the values of all the member variables. Debug that bit first, then go on to the rest.
I've been trying to get this Hangman using functions (from Michael Dawson's book) program to work, but I have this one error that I don't really understand. I realize my code code could have a variety of bad practices, but please go easy on me as I am a newb. I feel like I am almost there but I'm having trouble figuring out this one error. I am using CodeBlocks. The error is:
32|error: no match for call to '(std::__cxx11::string {aka std::__cxx11::basic_string}) (std::__cxx11::basic_string::size_type, char)'|
//Hangman from Michael Dawson's code
//Uses functions to create the program
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <ctime>
#include <cctype>
using namespace std;
//FUNCTION DECLARATION
string pickword();
char playerGuess();
void isitinthere();
char guess = 0;
string soFar = "word";
string used = "";
int wrong = 0;
int main()
{
const int MAX_WRONG = 8;
string WORD = pickword();
soFar = WORD;
soFar(WORD.size(), '-');
used = "";
cout << "Welcome to Hangman! Godspeed!" << endl;
while ((wrong < MAX_WRONG) && (soFar != WORD))
{
cout << "\n\nYou have " << (MAX_WRONG - wrong);
cout << " incorrect guesses left.\n";
cout << "\nYou've used the following letters:\n" << used << endl;
cout << "\nSo far, the word is:\n" << soFar << endl;
}
playerGuess();
while (used.find(guess) != string::npos)
{
cout << "\nYou've already guessed " << guess << endl;
cout << "Enter your guess: ";
cin >> guess;
guess = toupper(guess);
}
used += guess;
isitinthere();
if (wrong == MAX_WRONG)
{
cout << "\nYou've been hanged!";
}
else
{
cout << "\nYou guessed it!";
}
cout << "\nThe word was " << WORD << endl;
return 0;
}
//FUNCTION DEFINITION
string pickword()
{
srand(static_cast<unsigned int>(time(0)));
vector<string> words;
words.push_back("INDUBITABLY");
words.push_back("UNDENIABLY");
words.push_back("CRUSTACEAN");
words.push_back("RESPONSIBILITY");
words.push_back("MISDEMEANOR");
words.push_back("FORENSIC");
words.push_back("BALLISTIC");
words.push_back("PARADIGM");
words.push_back("TROUBARDOR");
words.push_back("SUPERCALIFRAGILISTICEXPIALLADOCIOUS")
random_shuffle(words.begin(), words.end());
theword = words[0];
return theword;
}
char playerGuess()
{
cout << "\n\nEnter your guess: ";
cin >> guess;
guess = toupper(guess);
return guess;
}
void isitinthere()
{
if (WORD.find(guess) != string::npos)
{
cout << "That's right! " << guess << " is in the word.\n";
for (int i = 0; i < WORD.length(); ++i)
{
if (WORD[i] == guess)
{
soFar[i] = guess;
}
}
}
else
{
cout << "Sorry, " << guess << "isn't in the word. \n";
++wrong;
}
}
Thanks in advance for your help!
Here is a simple program that should solve your question.
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <cctype>
// since you must have function here are some
bool removeGuessFromWord(std::string& word, const char guess);
bool isGuessInWord(const std::string& word, const char guess);
bool hasAlreadyGuessed(const std::vector<char>& gussList, const char guess);
// this is a simple program that should solve your question. It is not optimized for speed or efficency.
int main()
{
std::vector<std::string> wordList = {"dog","cat","rat"}; // vector of words to select from and use as the word in hangman
std::vector<char> guessList; // empty vector of gusses
// Note that I assume a MAX_GUESS_COUNT of 0 means no guesses are allowed
const unsigned int MAX_GUESS_COUNT = 4U; // number of guesses your allowed
std::srand(time(0)); // use current time as seed for random generator
std::string word = wordList.at(std::rand()%wordList.size()); // get a random word in the list
std::string letersLeft = word; // keep track of what letters will still need to remove
std::cout << "Welcome to Hangman! Godspeed!" << std::endl;
char guess = 0;
for(unsigned int numBadGusses=0U; numBadGusses<MAX_GUESS_COUNT && letersLeft.size()>0U; guess = 0)
{
std::cin>>guess;
if(std::isprint(guess) == 0)
{
// may want more error checking
std::cout << "You ented a non-printable charecter" << std::endl;
}
else if(isGuessInWord(word, guess))
{
// this was a good guess because the charecter is still in the word
// so remove all the remaining chars of this type from the word
if( removeGuessFromWord(letersLeft,guess) )
{
std::cout << guess << " was a good guess" << std::endl;
}
else
{
std::cout << guess << " was a good guess, but you already guessed it once" << std::endl;
}
}
else if(hasAlreadyGuessed(guessList, guess))
{
std::cout << "You've already guessed " << guess << std::endl;
}
else
{
// this was a new bad guess
guessList.push_back(guess);
numBadGusses++; // Note that this isn't technicly needed and could use size of vector
std::cout << guess << " was a bad guess" << std::endl;
}
}
if(letersLeft.size() == 0U)
{
std::cout<<"You Win"<<std::endl;
}
else
{
std::cout<<"You Lose"<<std::endl;
}
std::cout << "The word was "<< word << std::endl;
return 0;
}
bool removeGuessFromWord(std::string& word, const char guess)
{
return word.erase(std::remove(word.begin(), word.end(), guess), word.end()) != word.end() ? true : false;
}
bool isGuessInWord(const std::string& word, const char guess)
{
return word.find(guess) != std::string::npos ? true: false;
}
bool hasAlreadyGuessed(const std::vector<char>& gussList, const char guess)
{
return std::find(gussList.begin(), gussList.end(), guess) != gussList.end() ? true: false;
}