Invalid use of non-static member function with header files - c++

#define MYSQLPP_MYSQL_HEADERS_BURIED
#include <mysql++/mysql++.h>
#include <iostream>
#include "/home/sulli313/Project4/Film.h"
void Film::showList(){
std::cout << "\n-----------------------------------" << std::endl;
std::cout << " Query Application " << std::endl;
std::cout << "-----------------------------------" << std::endl;
std::cout << " 1 All letter name actors" << std::endl;
std::cout << " 2 First # PG-13 and Above" << std::endl;
std::cout << " 3 All active/inactive users by store" << std::endl;
std::cout << " 4 Actor Movie titles and ids" << std::endl;
std::cout << "-1 Exit" << std::endl;
std::cout << "-----------------------------------" << std::endl;
std::cout << ">> Enter your choice:" << std::endl;
}
void Film::showOne(){
mysqlpp::Connection myDB("cse278F2022", "localhost", "cse278F2022",
"raspberrySeltzer");
// Create a query
mysqlpp::Query query = myDB.query();
std::cout << "Please enter a Letter A-Z!" << std::endl;
std::string letter;
std::cin >> letter;
///////////////////////////////////Do this part/////////////////////////////////////////////
//if(letter)
query << "SELECT first_name, last_name "
<< "FROM actor "
<< "WHERE first_name "
<< "LIKE '" + letter + "%'";
// << "WHERE code = \"IST\"";
query.parse();
mysqlpp::StoreQueryResult result = query.store();
std::cout << "Here is your selection!\n" << std::endl;
std::cout << "--First/Last Names of Actors Whos First ";
std::cout << "Name Stars With " + letter + "--\n" << std::endl;
std::cout << std::left << std::setw(12) << "First Name" <<
std::setw(10) << "Last Name" << std::endl;
std::cout << "------------------------" << std::endl;
for (const auto & row : result) {
std::cout << std::left << std::setw(12) << row[0].c_str();
std::cout << std::setw(5) << row[1] << std::endl;
}
std::cout << "\n" << "to continue, press enter..." << std::endl;
showList();
}
void Film::showTwo(){
mysqlpp::Connection myDB("cse278F2022", "localhost", "cse278F2022",
"raspberrySeltzer");
//Selecting the second option's query
std::cout << "Please type a limit 1-30!" << std::endl;
std::string limit;
std::cin >> limit;
mysqlpp::Query query = myDB.query();
query << "SELECT title "
<< "FROM film "
<< "WHERE rating = 'PG-13' "
<< "OR rating = 'R' "
<< "OR rating = 'NC-17' "
<< "LIMIT " + limit + " ";
query.parse();
mysqlpp::StoreQueryResult result = query.store();
std::cout << "Here is your selection!\n" << std::endl;
std::cout << "--First "+ limit +" Titles PG-13 to NC-17--\n" << std::endl;
std::cout << std::left <<std::setw(20)<< "Title" << std::endl;
std::cout << "------------------------------" <<std::endl;
for (const auto & row : result) {
std::cout << std::left << std::setw(20) << row[0].c_str()<< std::endl;
}
std::cout << "\n" << "to continue, press enter..." << std::endl;
showList();
}
void Film::showThree(){
mysqlpp::Connection myDB("cse278F2022", "localhost", "cse278F2022",
"raspberrySeltzer");
//bind variable
std::cout << "Please type 1 for active and 0 for inactive!" << std::endl;
std::string active;
std::cin >> active;
if(active != "1" && active != "0"){
std::cout << "Wrong!" << std::endl;
std::cout << "Please type 1 for active and 0 for inactive!" << std::endl;
std::cin >> active;
}
//Selecting the second option's query
mysqlpp::Query query = myDB.query();
query << "SELECT Count(*) "
<< "FROM customer "
<< "WHERE active = '"+ active + "' "
<< "GROUP BY store_id";
query.parse();
mysqlpp::StoreQueryResult result = query.store();
std::cout << "Here is your selection!\n" << std::endl;
if(active == "1"){
std::cout << "--Count of All Active Users Grouped by Store Id--\n" << std::endl;
std::cout << std::left <<std::setw(20)<< "Active User Ids" << std::endl;
std::cout << "--------------------" <<std::endl;
} else {
std::cout << "--Count of All Inactive Users Grouped by Store Id--\n" << std::endl;
std::cout << std::left <<std::setw(20)<< "Inactive User Ids" << std::endl;
std::cout << "--------------------" <<std::endl;
}
for (const auto & row : result) {
std::cout << std::left << std::setw(20) << row[0].c_str()<< std::endl;
}
std::cout << "\n" << "to continue, press enter..." << std::endl;
showList();
}
void Film::showFour(){
mysqlpp::Connection myDB("cse278F2022", "localhost", "cse278F2022",
"raspberrySeltzer");
//bind variable
std::cout << "Please type an actor id that is 1-200!" << std::endl;
std::string act_id;
std::cin >> act_id;
//Selecting the second option's query
mysqlpp::Query query = myDB.query();
query << "SELECT film.title, film.film_id, film_actor.actor_id "
<< "FROM film, film_actor "
<< "WHERE film_actor.actor_id = "+ act_id +" "
<< "GROUP BY title "
<< "LIMIT 20";
query.parse();
mysqlpp::StoreQueryResult result = query.store();
std::cout << "Here is your selection!\n" << std::endl;
std::cout << "--First 20 Titles and IDs of Actor Id 25--\n" << std::endl;
std::cout << std::left <<std::setw(22)<< "Title" <<
std::setw(10)<< "Film_id" << std::setw(0)<<"Actor_id" << std::endl;
std::cout << "----------------------------------------" <<std::endl;
for (const auto & row : result) {
std::cout << std::left<<std::setw(22)<< row[0].c_str() << std::setw(10) << row[1] << std::setw(0) << row[2].c_str() << std::endl;
}
std::cout << "\n" << "to continue, press enter..." << std::endl;
showList();
}
#ifndef FILM_H
#define FILM_H
#include <iostream>
#include <string>
class Film {
public:
void showList();
void showOne();
void showTwo();
void showThree();
void showFour();
private:
};
#endif
// Copyright
// Purpose: Project 4
// Date 11/25/2022
// Author: Colton Sullivan
#define MYSQLPP_MYSQL_HEADERS_BURIED
#include <mysql++/mysql++.h>
#include <iostream>
#include "/home/sulli313/Project4/Film.h"
int main() {
int choice;
showList();
std::cin >> choice;
if (choice == -1) {
std::cout << "Bye!" << std::endl;
}
while (choice != -1) {
while ( choice > 4 || choice < -1 || choice == 0 ) {
std::cout << "The wrong choice!!!" << std::endl;
std::cout << "" << std::endl;
std::cout << "to continue, press enter...";
showList();
std::cin >> choice;
}
if ( choice == 1 ) {
showOne();
}
if ( choice == 2 ) {
showTwo;
}
if ( choice == 3 ) {
showThree;
}
if ( choice == 4 ) {
showFour;
}
std::cin >> choice;
if ( choice == -1 ) {
std::cout << "Bye!" << std::endl;
}
}
}
When trying to switch the original program to object oriented programming, I ran into the problem of the error "Invalid use of non-static member function" popping up for the showOne, showTwo, showThree, showFour and showList functions.
If there is a way to access the functions that are created in the Film.cpp/Film.h files and use them in the QueryApp.cpp file to run that as the main, please let me know.
I have tried switching it from Film::showOne, Film::showTwo...etc to showOne(); and Film::showOne(); but either the same Invalid use of non-static member function error will show or it will say that it has not be declared in this scope.

Your showSomething() functions are all member functions of the Film type. In particular, because they are not marked as static, they are non-static member functions. That means they operate on an instance of Film:
class C {
public:
void a(); // <- non-static member function
static void b(); // <- static member function
};
void foo() {
C::b(); // okay, doesn't need an object
C::a(); // not okay, needs an object
C object; // instance of C
object.a(); // okay
object.b(); // also okay
}
Typically you would give your object some state information or it raises the question why you have a non-static member function to begin with. If you don't need state, make them free functions (i.e., functions that are not member functions) or make them static.
In your case, I suppose it would be helpful to create a database connection in your Film's constructor so you can use the database member in all the functions that need a database connection to function.
Something like this:
class Film {
private:
mysqlpp::Connection myDB;
public:
Film() : myDB("x", "localhost", "y", "z") {}
// ...
};

Related

compilation error due to changing function's output data type

Forgive me if this is an obvious fix as I am very much a novice when it comes to C++.
For my assignment, we were given some starter code that simulates a command-line crypto trading platform. Originally, you would be prompted to type in commands 1 to 6 to do things like print exchange stats, make an offer, print the wallet and such. For my assignment, I've been asked to create an advisor bot that takes in string commands such as 'help' and processes this to return the appropriate output.
Naturally, since there was already a system in place to do this with integers as inputs, I tried to tweak the functions (I didn't do a lot yet) so they take string commands instead and output accordingly.
Before anything else, I would like to know why the function getUserOption and input is underlined red in the while loop of the init function, but in the actual function there are no errors:
This is the contents of the header file
#pragma once
#include <vector>
#include "OrderBookEntry.h"
#include "OrderBook.h"
#include "Wallet.h"
#include <string>
using namespace std;
class MerkelMain
{
public:
MerkelMain();
/** Call this to start the sim */
void init();
private:
void advisorBot();
void printHelp();
void printMarketStats();
void enterAsk();
void enterBid();
void printWallet();
void gotoNextTimeframe();
std::string getUserOption();
void processUserOption(string userOption);
void printCurrentTime();
std::string currentTime;
// OrderBook orderBook{"20200317.csv"};
OrderBook orderBook{"20200601.csv"};
Wallet wallet;
};
This is the cpp file
#include "MerkelMain.h"
#include <iostream>
#include <vector>
#include "OrderBookEntry.h"
#include "CSVReader.h"
#include <string>
using namespace std;
MerkelMain::MerkelMain()
{
}
void MerkelMain::init()
{
int input;
currentTime = orderBook.getEarliestTime();
wallet.insertCurrency("BTC", 10);
while(true)
{
advisorBot();
input = getUserOption();
processUserOption(input);
}
}
void MerkelMain::advisorBot()
{
std::cout << "Please enter a command, or help for a list of commands" << std::endl;
std::cout << "============== " << std::endl;
std::cout << "Current time is: " << currentTime << std::endl;
}
/*void MerkelMain::printMenu()
{
// 1 print help
std::cout << "1: Print help " << std::endl;
// 2 print exchange stats
std::cout << "2: Print exchange stats" << std::endl;
// 3 make an offer
std::cout << "3: Make an offer " << std::endl;
// 4 make a bid
std::cout << "4: Make a bid " << std::endl;
// 5 print wallet
std::cout << "5: Print wallet " << std::endl;
// 6 continue
std::cout << "6: Continue " << std::endl;
std::cout << "============== " << std::endl;
std::cout << "Current time is: " << currentTime << std::endl;
}*/
void MerkelMain::printHelp()
{
std::cout << " The available commands are help, help cmd, prod, min, max, avg, predict, time, step " << std::endl;
}
void MerkelMain::printMarketStats()
{
for (std::string const& p : orderBook.getKnownProducts())
{
std::cout << "Product: " << p << std::endl;
std::vector<OrderBookEntry> entries = orderBook.getOrders(OrderBookType::ask,
p, currentTime);
std::cout << "Asks seen: " << entries.size() << std::endl;
std::cout << "Max ask: " << OrderBook::getHighPrice(entries) << std::endl;
std::cout << "Min ask: " << OrderBook::getLowPrice(entries) << std::endl;
}
}
void MerkelMain::enterAsk()
{
std::cout << "Make an ask - enter the amount: product,price, amount, eg ETH/BTC,200,0.5" << std::endl;
std::string input;
std::getline(std::cin, input);
std::vector<std::string> tokens = CSVReader::tokenise(input, ',');
if (tokens.size() != 3)
{
std::cout << "MerkelMain::enterAsk Bad input! " << input << std::endl;
}
else {
try {
OrderBookEntry obe = CSVReader::stringsToOBE(
tokens[1],
tokens[2],
currentTime,
tokens[0],
OrderBookType::ask
);
obe.username = "simuser";
if (wallet.canFulfillOrder(obe))
{
std::cout << "Wallet looks good. " << std::endl;
orderBook.insertOrder(obe);
}
else {
std::cout << "Wallet has insufficient funds . " << std::endl;
}
}catch (const std::exception& e)
{
std::cout << " MerkelMain::enterAsk Bad input " << std::endl;
}
}
}
void MerkelMain::enterBid()
{
std::cout << "Make an bid - enter the amount: product,price, amount, eg ETH/BTC,200,0.5" << std::endl;
std::string input;
std::getline(std::cin, input);
std::vector<std::string> tokens = CSVReader::tokenise(input, ',');
if (tokens.size() != 3)
{
std::cout << "MerkelMain::enterBid Bad input! " << input << std::endl;
}
else {
try {
OrderBookEntry obe = CSVReader::stringsToOBE(
tokens[1],
tokens[2],
currentTime,
tokens[0],
OrderBookType::bid
);
obe.username = "simuser";
if (wallet.canFulfillOrder(obe))
{
std::cout << "Wallet looks good. " << std::endl;
orderBook.insertOrder(obe);
}
else {
std::cout << "Wallet has insufficient funds . " << std::endl;
}
}catch (const std::exception& e)
{
std::cout << " MerkelMain::enterBid Bad input " << std::endl;
}
}
}
void MerkelMain::printWallet()
{
std::cout << wallet.toString() << std::endl;
}
void MerkelMain::gotoNextTimeframe()
{
std::cout << "Going to next time frame. " << std::endl;
for (std::string p : orderBook.getKnownProducts())
{
std::cout << "matching " << p << std::endl;
std::vector<OrderBookEntry> sales = orderBook.matchAsksToBids(p, currentTime);
std::cout << "Sales: " << sales.size() << std::endl;
for (OrderBookEntry& sale : sales)
{
std::cout << "Sale price: " << sale.price << " amount " << sale.amount << std::endl;
if (sale.username == "simuser")
{
// update the wallet
wallet.processSale(sale);
}
}
}
currentTime = orderBook.getNextTime(currentTime);
}
std::string MerkelMain::getUserOption()
{
std::string userOption = "";
std::string line;
//std::cout << "Type in 1-6" << std::endl;
std::getline(std::cin, line);
try{
userOption = std::stoi(line);
}catch(const std::exception& e)
{
//
}
std::cout << "You chose: " << userOption << std::endl;
return userOption;
}
void printCurrentTime()
{
std::cout << "Current time is: " << currentTime << std::endl;
}
void MerkelMain::processUserOption(string userOption)
{
if (userOption == "help")
{
printHelp();
}
if (userOption == "help cmd")
{
printMarketStats();
}
if (userOption == "prod")
{
enterAsk();
}
if (userOption == "min")
{
enterBid();
}
if (userOption == "max")
{
printWallet();
}
if (userOption == "avg")
{
gotoNextTimeframe();
}
if (userOption == "predict")
{
enterAsk();
}
if (userOption == "time")
{
enterBid();
}
if (userOption == "step")
{
gotoNextTimeframe();
}
}
Your getUserOption() function returns a std::string. This means when you wrote:
input = getUserOption();
In the above statement the right hand side is of type std::string. On the other hand, the left hand side is of type int. So there is mismatch in the type of left hand side and right hand side expressions. Hence the error.
You can solve this by changing the type of variable input to std::string. So replace int input; by:
std::string input; //type changed to std::string

How to exit from a stream reading loop, avoiding an additional empty loop?

When the program enters in the if and then break, empty cout-s are printed again.
void Person::ShowRecords()
{
std::ifstream data("Input.txt");
while (true)
{
if (!data.good())
{
break;
}
Person person;
data >> person;
std::cout << "First Name: " << person.getFirstName() << "\n";
std::cout << "Last Name: " << person.getLastName() << "\n";
std::cout << "Phone number: " << person.getNumber() << "\n";
std::cout << "EGN: " << person.getEGN() << "\n\n";
}
}
I really think that the most didactic way of tackling stream input is:
while (true) {
// Read
// Check (if fail then break)
// Use
}
Notice the pattern: infinite loop with Read/Check/Use. Check is where we can exit the loop. First you read, than you check if the reading operation was successful or failed, than you can use the data or exit based on that.
Adapting this to your case:
void Person::ShowRecords()
{
std::ifstream data("Input.txt");
while (true) {
// Read
Person person;
data >> person;
// Check
if (!data) {
break;
}
// Use
std::cout << "First Name: " << person.getFirstName() << "\n";
std::cout << "Last Name: " << person.getLastName() << "\n";
std::cout << "Phone number: " << person.getNumber() << "\n";
std::cout << "EGN: " << person.getEGN() << "\n\n";
}
}
The non didactic and probably more idiomatic way is:
void Person::ShowRecords()
{
std::ifstream data("Input.txt");
Person person;
while (data >> person) { // Read and, immediately after, Check
std::cout << "First Name: " << person.getFirstName() << "\n"; // Use
std::cout << "Last Name: " << person.getLastName() << "\n";
std::cout << "Phone number: " << person.getNumber() << "\n";
std::cout << "EGN: " << person.getEGN() << "\n\n";
}
}

undefined reference to `Mosaic::Mosaic()'

Error in terminal of VS Code:
/tmp/ccU4qzPn.o: In function main':
azul.cpp:(.text+0xa7e): undefined reference toMosaic::Mosaic()'
azul.cpp:(.text+0xa86): undefined reference to `Mosaic::printMosaic()'
collect2: error: ld returned 1 exit status*
azul.cpp
#include "Mosaic.h"
#include <iostream>
// int menuOption;
std::string playerOne;
std::string playerTwo;
void printMenu() {
std::cout << " " << std::endl;
std::cout << "*-*-*-*-*-*-*-*-*-*-*-*-*-*-*" << std::endl;
std::cout << "| |" << std::endl;
std::cout << "| Welcome to Azul |" << std::endl;
std::cout << "| |" << std::endl;
std::cout << "*-*-*-*-*-*-*-*-*-*-*-*-*-*-*" << std::endl;
std::cout << "| ----------- |" << std::endl;
std::cout << "| Main Menu |" << std::endl;
std::cout << "| ----------- |" << std::endl;
std::cout << "| 1. New Game |" << std::endl;
std::cout << "| 2. Load Game |" << std::endl;
std::cout << "| 3. Credits |" << std::endl;
std::cout << "| 4. Help |" << std::endl;
std::cout << "| 5. Quit |" << std::endl;
std::cout << "| |" << std::endl;
std::cout << "*-*-*-*-*-*-*-*-*-*-*-*-*-*-*" << std::endl;
std::cout << " " << std::endl;
}
int main(void) {
printMenu();
std::cout << "Enter Your Choice: " << std::endl;
char menuOption;
std::cin >> menuOption;
if (menuOption == '1') {
std::cout << "\n\nStarting a new game..." << std::endl;
std::cout << "\nEnter Name for Player One:" << std::endl;
std::cin >> playerOne;
std::cout << "\nEnter Name for Player Two:" << std::endl;
std::cin >> playerTwo;
std::cout << "\n\nLet's play!\n" << std::endl;
std::cout << "-----------" << std::endl;
std::cout << "Start Round" << std::endl;
std::cout << "-----------" << std::endl;
std::cout << "\nMosaic for " << playerOne << ":" << std::endl;
Mosaic* mosaic = new Mosaic();
mosaic->printMosaic();
}
return EXIT_SUCCESS;
};
Mosaic.cpp
#include "Mosaic.h"
#include <iostream>
Mosaic::Mosaic(){
}
Mosaic::~Mosaic(){
}
void Mosaic::printMosaic() {
for (int i = 1; i < 6; i++)
{
std::cout << i << ". ";
for (int j = 6; j > i; j--)
{
std::cout << " ";
}
for (int j = 0; j < i; j++)
{
std::cout << ".";
}
std::cout << "|| . . . . ." << std::endl;
}
}
Mosaic.h
class Mosaic
{
public:
Mosaic();
~Mosaic();
void printMosaic();
};
I think the problem is at the pointer
Mosaic* mosaic = new Mosaic();

How to print correctly const char* struct member of a list?

I am trying to display struct members of a list in OMNeT++, all members are displayed correctly unless the member which is of type const char*. I am confused because after three push_back in the list, when I display. All the members of the last pushed element is displayed correctly even the one of type const char*. But for the two first pushed elements, the member of type cont char* display nothing, garbage or "DETAIL (Ipv4)Drones.host[3].ipv4.ip".
Ipv4Address srcAddress = recMtlsd->getSrcAddress();
Ipv4Address dstAddress = recMtlsd->getDstAddress();
const char* position = recMtlsd->getPosition();
simtime_t time = recMtlsd->getTime();
int srcID = recMtlsd->getId();
EV_DEBUG << "Source : " << srcAddress << endl;
EV_DEBUG << "Destination : " << dstAddress << endl;
EV_DEBUG << "Position : " << position << endl;
EV_DEBUG << "Time : " << time << endl;
EV_DEBUG << "Source ID: " << srcID << endl;
// All precedent displays are working correctly
/*typedef struct Mtlsd{
Ipv4Address originatorAddr, destinationAddr;
const char *position;
int originatorId;
simtime_t time;
}MTLSD;*/
MTLSD recitem;
recitem.originatorAddr = srcAddress;
recitem.originatorId = srcID;
recitem.destinationAddr = dstAddress;
recitem.position = position;
recitem.time = time;
EV_DEBUG << "Source : " << recitem.originatorAddr << endl;
EV_DEBUG << "Destination : " << recitem.dstinationAddr << endl;
EV_DEBUG << "Position : " << recitem.position << endl;
EV_DEBUG << "Time : " << recitem.time << endl;
EV_DEBUG << "Source ID: " << recitem.srcID << endl;
// All precedent displays are working correctly
/*typedef struct Mtlsd_data{
list<MTLSD> q;
int ID;
}MTLSD_DATA;*/
list<MTLSD_DATA> mtlsd_file;
auto node = find_if(mtlsd_file.begin(), mtlsd_file.end(), [=] (MTLSD_DATA const& i){return (i.ID == srcID);});
bool found = (node != mtlsd_file.end());
if (!found)
{
MTLSD_DATA recdata;
recdata.ID = srcID;
recdata.q.push_back(recitem);
mtlsd_file.push_back(recdata);
EV_DEBUG << "For node " << srcID ;
for(auto claim=mtlsd_file.back().q.begin(); claim!=mtlsd_file.back().q.end();++claim)
{
EV_DEBUG << "(" << string(claim->position) << ", " << claim->time << ");" << endl;
}
// The precedent display works correctly
}
else
{
EV_DEBUG << "I already have data about the node " << node->ID << endl;
if (node->q.size() == 3)
{
EV_DEBUG << "I already have three time-location claim in the queue" << endl;
EV_DEBUG << "Here they are: ";
EV_DEBUG << "For node " << (*node).ID << endl;
for(auto fileclaim=(*node).q.begin(); fileclaim!=(*node).q.end();++fileclaim)
EV_DEBUG << "(" << string((*fileclaim).position) << ", " << (*fileclaim).time << ");" << endl;
EV_DEBUG << "I will delete the old one (" << node->q.front().position << ", " << node->q.front().time << ")" << endl;
node->q.pop_front();
}
node->q.push_back(recitem);
EV_DEBUG << "I have pushed this new one : (" << string(node->q.back().position) << ", " << node->q.back().time << ")" << endl;
}
EV_DEBUG << "Here they are all time-location claims in the queue : ";
for(auto fileclaims=node->q.begin(); fileclaims!=node->q.end();++fileclaims)
{
EV_DEBUG << "(" << string(fileclaims->position) << ", " << fileclaims->time << ");" << endl;
}
// The last element is displayed correctly, but those before not.
.
.
.

GetConsoleSelectionInfo C++

cI want to select some text with my cursor using the Mark Function from Console, but my code doesn't work ...
CONSOLE_SELECTION_INFO c;
if(GetConsoleSelectionInfo(&c))
{
while((c.dwFlags & CONSOLE_MOUSE_DOWN) == 0) { if(c.dwFlags) cout << c.dwFlags; }
cout << "SelectionAnchor: " << c.dwSelectionAnchor.X << " " << c.dwSelectionAnchor.Y;
cout << "RectangleSelection: " << c.srSelection.Top << " " << c.srSelection.Left << c.srSelection.Bottom << c.srSelection.Right;
}
else cout << "\n\nError: " << GetLastError();
Whatever I'm selecting or I'm doing, always c.dwFlags will be 0 ...