I'm having problems using std::vector<int> in C++ on Mac OSX Catalina. I have a function static int insertMoneyData(std::vector<int> money) that writes data to an SQLite database. The function is declared in SQLFunctions.h and defined in SQLFunctions.cc.
When also running the function from SQLFunctions.cc, everything works fine in the compilation (using c++ in make). But when I try to run the same function from another file (city.cc), I get the following error:
Undefined symbols for architecture x86_64:
"insertMoneyData(std::__1::vector<int, std::__1::allocator<int> >)", referenced from:
City::save_money_data() in city.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1
(use -v to see invocation)
make: *** [main] Error 1
Calling insertMoneyData(money_data) from SQLFunctions.cc, where it is defined, works fine.
//SQLFunctions.cc
#include <iostream>
#include <sqlite3.h>
#include <stdio.h>
#include <vector>
#include <cstring>
#include "SQLfunctions.h"
using namespace std;
using Record = std::vector<std::string>;
using Records = std::vector<Record>;
int initiateDB() {
std::vector<int> money_data;
money_data.push_back(1);
money_data.push_back(2);
money_data.push_back(3);
money_data.push_back(4);
money_data.push_back(5);
money_data.push_back(6);
money_data.push_back(7);
money_data.push_back(8);
money_data.push_back(9);
money_data.push_back(10);
money_data.push_back(11);
money_data.push_back(12);
money_data.push_back(13);
insertMoneyData(money_data);
}
static int insertMoneyData(std::vector<int> money) {
const char* dir = "/Users/bennyjohansson/Projects/ekosim/myDB/ekosimDB.db";
sqlite3* DB;
char* messageerror;
int exit = sqlite3_open(dir, &DB);
string sql = "INSERT INTO MONEY_DATA (TIME, BANK_CAPITAL, BANK_LOANS, BANK_DEPOSITS, BANK_LIQUIDITY, CONSUMER_CAPITAL, CONSUMER_DEPOSITS, CONSUMER_DEBTS, COMPANY_DEBTS, COMPANY_CAPITAL, MARKET_CAPITAL, CITY_CAPITAL, TOTAL_CAPITAL) VALUES(";
sql.append(std::to_string(money[0]) + ", ");
sql.append(std::to_string(money[1]) + ", ");
sql.append(std::to_string(money[2]) + ", ");
sql.append(std::to_string(money[3]) + ", ");
sql.append(std::to_string(money[4]) + ", ");
sql.append(std::to_string(money[5]) + ", ");
sql.append(std::to_string(money[6]) + ", ");
sql.append(std::to_string(money[7]) + ", ");
sql.append(std::to_string(money[8]) + ", ");
sql.append(std::to_string(money[9]) + ", ");
sql.append(std::to_string(money[10]) + ", ");
sql.append(std::to_string(money[11]) + ", ");
sql.append(std::to_string(money[12]) + ");");
exit = sqlite3_exec(DB, sql.c_str(), NULL, 0, &messageerror);
}
However, when I call the function from another file, it doesn't work:
//City.cc
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <list>
#include <fstream>
#include <cmath>
#include <random>
#include "SQLfunctions.h"
using namespace std;
void City::save_money_data() {
std::vector<int> money_data;
money_data.push_back(1);
money_data.push_back(2);
money_data.push_back(3);
money_data.push_back(4);
money_data.push_back(5);
money_data.push_back(6);
money_data.push_back(7);
money_data.push_back(8);
money_data.push_back(9);
money_data.push_back(10);
money_data.push_back(11);
money_data.push_back(12);
money_data.push_back(13);
insertMoneyData(money_data);
}
Declaring:
//SQLFunctions.h
#ifndef SQL_FUNCTIONS_H
#define SQL_FUNCTIONS_H
#include <iostream>
#include <sqlite3.h>
#include <stdio.h>
using namespace std;
using Record = std::vector<std::string>;
using Records = std::vector<Record>;
int initiateDB();
static int createDB(const char* s);
static int createParameterTable(const char* s);
static int createDataTable(const char* s);
static int createMoneyTable(const char* s);
static int insertParameterData(const char* s);
static int insertMoneyData(std::vector<int> money); //
static int updateData(const char* s);
static int updateParameter(const char* s, string, double);
static int deleteTheData(const char* s);
static int selectData(const char* s);
static int callback(void* NotUsed, int argc, char** argv, char** azColName);
int select_callback(void *p_data, int num_fields, char **p_fields, char **p_col_names);
Records select_stmt(const char* stmt, const char* s);
#endif
Problem is obsolete keyword static before each function.
static keyword has multiple meanings. In this context it means: this function definition should be visible only in this translation unit (translation unit means sources compiled during single compilation - so source file with all its includes).
So you defined a function which should be accessed by other translation units (other sources), but you have limited its visibility to single file where it is defined. That is why linker complains that can't find this functions.
Related
My application name changes after runtime, but it has no file extension. I want it to be an .exe.
I'm new to c++ and I really need to figure this out.
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
using namespace std;
std::string path()
{
char shitter[_MAX_PATH]; // defining the path
GetModuleFileNameA(NULL, shitter, _MAX_PATH); // getting the path
return std::string(shitter); //returning the path
}
int main()
{
srand(time(NULL));
char letter = 'A' + (rand() % 26);
const char *val = new char(letter);
std::rename(path().c_str(), val); //renaming the file
}
I tried doing this
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
using namespace std;
std::string path()
{
char shitter[_MAX_PATH]; // defining the path
GetModuleFileNameA(NULL, shitter, _MAX_PATH); // getting the path
return std::string(shitter); //returning the path
}
int main() {
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); // Higher Priority
SetConsole();
srand(time(NULL));
char letters = 'A'+ (rand() % 26);
const char* val = new char(letters);
std::string rename(path().c_str(), val += ".exe"); //renaming the file
But now im getting an error
https://prnt.sc/uejlxz
rename(path().c_str(), val + ".exe")
or use append
String Concatenation
after installing mpir-3.0 on fedora 31. Now I try to build project:
#include <stdio.h>
#include <gmp.h>
#include <mpir.h>
#include <mpfr.h>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
mpf_t a; //mpir float variable
mpf_init(a); //initialise a
mpir_ui two = 2; //mpir unsigned integer variable
FILE* stream; //file type pointer to output on standard output (console)
mpf_init_set_ui (a, 2); //set value of a to 2
mpf_out_str (stream, 10, 2, a); //output value of a
cout << "\nMPIR working" << "\n" ;
}
But when I compile it I get this error:
‘mpir_ui’ was not declared in this scope; did you mean ‘mpfr_ai’?|
I've used the flags:
-lmpir -lmpfr -lgmp
I'm learning C++, and I have the following problem. I can't understand how this sentence interacts
extern vector<string> startParsing(FILE*);
I tried to find information about (FILE*) but I can't find anything.
main.cpp
#include <iostream>
#include <fstream>
#include "Parser/parser.h"
using namespace std;
int main(int argc, char** argv)
{
cout<<"Welcome to Group 01 final project."<<endl;
std::string rule_file = "urbanmodel.zoo";
// parsing
Parser parser(rule_file);
std::vector<std::string> tokens = parser.parse();
parser.printTokens();
return 1;
}
parser.cpp
#include "parser.h"
extern vector<string> startParsing(FILE*); //<---------------------???
Parser::Parser(string filePath){
// open a file handle to a particular file:
this->myfile = fopen(filePath.c_str(), "r");
// make sure it's valid:
if (!this->myfile) {
cout << "I can't open the urbanmodel.zoo file!" << endl;
}
};
vector<string> Parser::parse(){
if(this->myfile)
this->tokens = startParsing(myfile);
return this->tokens;
};
void Parser::printTokens(){
int size = this->tokens.size();
for(int i=0;i<size;i++)
cout<<this->tokens[i];
cout<<std::endl;
};
parser.h
#include <iostream>
#include <vector>
#include <cstdio>
#include "scanner.h"
using namespace std;
class Parser{
private:
FILE* myfile; //<----------------------------------------???
vector<string> tokens;
public:
Parser(string filePath);
vector<string> parse();
void printTokens();
};
Currently I have an unique source file (*.cpp) where all my functions are working right. Now i'm trying to take some of them out into separate source files and including them into main source with no success.
My current project is as follows:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <windows.h>
#define _SQLNCLI_ODBC_
#include <sqlext.h>
#include <sqlncli.h>
using namespace std;
using std::cout;
using std::ifstream;
/*This is one of the functions to be put in separate file:*/
string *ReadPageAsignations ( const char* RutayNombre, const char* Page )
{
bool MisionCumplida = false;
bool EncabezadoListo = false;
int i = 0;
int j = 0;
char * pch;
char istr[256];
const int NUM_DATA = 15;
static string data[NUM_DATA];
std::stringstream InputString;
ifstream inputFile(RutayNombre);
if (inputFile.is_open())
{
while (inputFile.good() && MisionCumplida == false)
{
i = 0;
inputFile.getline(istr,256);
pch = strtok (istr,":");
if (string(pch) == "[Pagina]")
{
EncabezadoListo = true;
}
else
{
EncabezadoListo = false;
}
if (string(pch) == Page)
{
MisionCumplida = true;
}
while (pch != NULL)
{
if ((EncabezadoListo == true) || (MisionCumplida == true))
{
data[i] = data[i] + " " + string(pch);
}
pch = strtok (NULL, ",");
i++;
}
}
inputFile.close();
return data;
}
} //End of function 'ReadPageAsignations'
/*This is another function where my function "ReadPageAsignations' get called -- btw, I want also this function to be in a separate source file.*/
void DeliverHtml (const char* page){//const char* RutayNombre ) {
string *p;
char * pch;
size_t pos;
string RutayNombre;
RutayNombre = "../Substructure/Templates/" + SearchConfigValue( "../Substructure/Conf/Config-Templates.txt", "htmlTemplate:");
const char *RutayNombreConfigCompos = "../Substructure/Conf/Config-Composition.txt";
string RutayNombreParaInsertar;
string token, token1, token2;
string line, lineRead, lineToInsert;
char * StrToTokenize2;
string StrToTokenize1;
p=ReadPageAsignations( RutayNombreConfigCompos, page); //Here, I call the function I want in a separate file
...
}
/*And here is the main() function*/
int main()
{
char *value = "page=Home";
if (NULL!=strstr(getenv("QUERY_STRING"), "page="))
{
value = getenv("QUERY_STRING");
}
char *posCh = strstr(value, "=");
DeliverHtml(&posCh[0]+1);
return 0;
}
For the first function, I have tried creating the header file 'ReadPageAsignations.h' and a source file 'ReadPageAsignations.cpp'.
Header file 'ReadPageAsignations.h' containing:
#ifndef READPAGEASIGNATIONS_H_INCLUDED
#define READPAGEASIGNATIONS_H_INCLUDED
string *ReadPageAsignations ( const char* RutayNombre, const char* Page );
#endif // READPAGEASSIGNATIONS_H_INCLUDED
Source file 'ReadPageAsignations.cpp' for separate function containing:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
using std::cout;
using std::ifstream;
string *ReadPageAsignations ( const char* RutayNombre, const char* Page )
{
bool MisionCumplida = false;
bool EncabezadoListo = false;
int i = 0;
int j = 0;
char * pch;
char istr[256];
const int NUM_DATA = 15; /*El numero de elementos debe coincidir con el iterador en la función Deliverhtml.*/
static string data[NUM_DATA];
std::stringstream InputString;
ifstream inputFile(RutayNombre); //Abre el archivo y lo asigna al stream inputFile.
if (inputFile.is_open()) //Chequea que el archivo esté abierto.
{
while (inputFile.good() && MisionCumplida == false)
{
i = 0;
inputFile.getline(istr,256);
pch = strtok (istr,":");
if (string(pch) == "[Pagina]")
{
EncabezadoListo = true;
}
else
{
EncabezadoListo = false;
}
if (string(pch) == Page)
{
MisionCumplida = true;
}
while (pch != NULL)
{
if ((EncabezadoListo == true) || (MisionCumplida == true))
{
data[i] = data[i] + " " + string(pch);
}
pch = strtok (NULL, ",");
i++;
}
}
inputFile.close();
return data;
}
} //End function
and, main project containing:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <windows.h>
#define _SQLNCLI_ODBC_
#include <sqlext.h>
#include <sqlncli.h>
#include "ReadPageAsignations.h" //Here I #include the function definition file (header)
using namespace std;
using std::cout;
using std::ifstream;
...
}
I've got a lot of compiling errors:
\ReadPageAsignations.h|4|error C2143: syntax error : missing ';' before '*'|
\ReadPageAsignations.h|4|error C4430: missing type specifier - int assumed. Note: C++ does not support default-int|
\ReadPageAsignations.h|4|error C4430: missing type specifier - int assumed. Note: C++ does not support default-int|
main.cpp|20|error C2872: 'string' : ambiguous symbol|
...
I'm working Code::blocks 13.12 with MS Visual C++ 2005/2008 compiler.
any help will be highly appreciated, thanks in advance.
The error is telling you that when it tried to parse the header file it encountered the symbol string and doesn't recognize it. Adding #include <string> to your header file and fully qualifying the string type as std::string should correct the problem.
You should put #include <string> in your header file and remove it from your .cpp file
as following:
main.cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <windows.h>
#define _SQLNCLI_ODBC_
#include <sqlext.h>
#include <sqlncli.h>
#include "ReadPageAsignations.h"
...
note: including header file with the same name of .cpp file , include both.
ReadPageAsignations.h
#ifndef READPAGEASIGNATIONS_H_INCLUDED
#define READPAGEASIGNATIONS_H_INCLUDED
#include <string> //<-----This line, include string header
std::string *ReadPageAsignations ( const char* RutayNombre, const char* Page );
#endif // READPAGEASSIGNATIONS_H_INCLUDED
ReadPageAsignations.cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include "ReadPageAsignations.h" // <--- add the header file here
//#include <string> <---remove it already included in the header file
using namespace std;
//using std::cout; <--remove this you already used namespace std
//using std::ifstream; <--remove this you already used namespace std
string *ReadPageAsignations ( const char* RutayNombre, const char* Page )
{
... } //End function
I'm trying to compute a SHA256 hash of the string iEk21fuwZApXlz93750dmW22pw389dPwOkm198sOkJEn37DjqZ32lpRu76xmw288xSQ9
When I run my C++ code, I get a string that's not even a valid SHA256 hash. However, when I run echo -n iEk21fuwZApXlz93750dmW22pw389dPwOkm198sOkJEn37DjqZ32lpRu76xmw288xSQ9 | openssl sha256, I get the correct hash. Here's my C++ code:
#include <iostream>
#include <time.h>
#include <sstream>
#include <string>
#include <iomanip>
#include <typeinfo>
#include <openssl/sha.h>
#include <cstdio>
#include <cstring>
std::string hash256(std::string string) {
unsigned char digest[SHA256_DIGEST_LENGTH];
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, string.c_str(), std::strlen(string.c_str()));
SHA256_Final(digest, &ctx);
char mdString[SHA256_DIGEST_LENGTH*2+1];
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
std::sprintf(&mdString[i*2], "%02x", (unsigned int)digest[i]);
return std::string(mdString);
}
int main(int argc, char *argv[])
{
const char *hash = hash256("iEk21fuwZApXlz93750dmW22pw389dPwOkm198sOkJEn37DjqZ32lpRu76xmw288xSQ9").c_str();
std::cout << hash << std::endl;
return 0;
}
Another thing to note: When I run my code in an online compiler, such as Coliru, I get the correct hash. I am compiling with G++ on Cygwin with OpenSSL version OpenSSL 1.0.1g 7 Apr 2014
As pointed out by #Alan Stokes, you have Undefined Behavior due to a dangling reference to the internal structure of the string. Change your declaration of hash in main:
std::string hash = hash256("...");