"extern vector<string> startParsing(FILE*);" - c++

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();
};

Related

command spawnl() not executed

I have a code that is executable without error messages but it seems like it denies to run the code
I call by the "spawnl" command. This is my code and I receive "error=-1". I tried may different ways to solve the situation but I always receive the "-1" for an answer. I use Dev C++ compiler with 32bit release. My problem is to call the other program, sending the name of the file.
#include <stdlib.h>
#include <graphics.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <conio.h>
#include <process.h>
#include <ctype.h>
#include <dir.h>
#include <windows.h>
#include <dos.h>
#include <iostream>
#include <stddef.h>
void translate_to_ascii_files(),
save_mesh_data(),
make_no(),
give_names();
int load_patches(char *);
FILE *memco ;
int outnod[400] ;
float r_vector[21][21][3],cx[500],cy[500],cz[500] ;
int NOP1,NOP2; /* Number Of Points */
int patches;
char nams[26][26];
int num_of_files;
int kk,nv,nh,exnod,totnod ;
int no[4][400];
char filename[26];
void *buf;
COORD coord= {0,0};
HANDLE hConsole;
using namespace std; // std::cout, std::cin
void gotoxy(int x,int y) {
coord.X=x;
coord.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}
int main(int argc,char *argv[]) {
char com_nam[26];
int counter1,counter2,i;
int error;
system("cls");
give_names();
printf("give the final filename:");scanf("%s",filename);
for(patches=1;patches<=num_of_files;patches++) {
strcpy(com_nam,nams[patches]);
load_patches(com_nam); /* load patches for meshing*/
i=1;
for(counter1=0;counter1<=NOP1;counter1++) {
for(counter2=0;counter2<=NOP2;counter2++) {
cx[i]=r_vector[counter1][counter2][0];
cy[i]=r_vector[counter1][counter2][1];
cz[i]=r_vector[counter1][counter2][2];
i=i+1;
}
}
nh=NOP1+1;nv=NOP2+1;
make_no();
save_mesh_data();
if(argc ==1){
error=spawnl(P_WAIT,"c:\\cpprog\\unitsrf.exe","",filename,NULL);
if (error ==0) {
else {printf ("error=%d\n",error); system("PAUSE");
} }
else{gotoxy(2,11);printf("error=%s\n\n",argv[1]);
system("PAUSE");
}
} translate_to_ascii_files();
}

Passing a global string variable between .cpp files?

I have created a globals.h header file which has the extern string which is declared as "new_name". In image_output.cpp (main), I have declared string(new_name) as a global variable at the top of my function. Then I passed that variable into the erode_image.cpp(function file) and update it. I have included the globals.h with the main and the function files. The problem is that the "new_name" variable does not get updated in the function file(erode_image.cpp). Does anyone know where I am doing mistake?
globals.h:
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
extern string new_name;
erode_image.cpp (function):
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "functions.h"
#include "globals.h"
using namespace cv;
using namespace std;
Mat erode_image(Mat image, int erosion_size, string new_name) {
new_name += "_eroded";
Mat element = getStructuringElement(MORPH_RECT, Size(erosion_size, erosion_size));
erode(image, image, element);
return image;
}
image_output.cpp (main):
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "functions.h"
#include "globals.h"
using namespace cv;
using namespace std;
Mat imgCrop;
string new_name;
int erosion_size = 25;
int dilate_size = 50;
int brightness = 50;
int threshold_to_zero = 3;
int sectionCount = 5;
int main()
{
String folderpath = "*.png";
vector<String> filenames;
cv::glob(folderpath, filenames);
//removes ./ from beginning of filepath
for (int i = 0; i < size(filenames); i++) {
filenames[i] = filenames[i].erase(0, 2);
}
for (int i = 0; i < size(filenames); i++) {
if (filenames[i].find("_cropped") == string::npos) {
string image_path = filenames[i];
string new_name = image_path.substr(0, image_path.find_last_of('.')) + "_cropped";
string extension = image_path.substr(image_path.find_last_of("."));
Mat img = imread(image_path);
cvtColor(img, img, cv::COLOR_BGR2GRAY);
img = crop_image(img);
img = rotate_image(img);
img = erode_image(img, erosion_size, new_name);
//img = average_section_threshold(img, sectionCount, new_name);
//img = dilate_image(img, dilate_size, new_name);
string new_file_name = new_name + extension;
imwrite(new_file_name, img);
cout << "Image Succesfully Saved!";
}
}
}
You already solved your problem in the comments, so I'm just typing it up to make it a proper answer.
Your original code was like this:
globals.h
extern std::string new_name;
other_file.cpp
#include "globals.h"
void func(std::string new_name) // <- shadows the global new_name
{
new_name += "_stuff";
}
main.cpp
#include "globals.h"
std::string new_name;
int main()
{
new_name = "bla";
func(new_name);
std::cout << new_name << std::endl;
return 0;
}
Here new_name in main is not updated, and the output is bla. This happens because the argument in func shadows the global/extern variable.
The correct way to use extern (if you really want to keep the global) is to remove the argument to func:
globals.h
extern std::string new_name;
other_file.cpp
#include "globals.h"
void func()
{
new_name += "_stuff";
}
main.cpp
#include "globals.h"
std::string new_name;
int main()
{
new_name = "bla";
func();
std::cout << new_name << std::endl;
return 0;
}
Now the shadowing is gone, and the output is bla_stuff. However, this uses a global which is something to avoid, since being global makes it hard to reason about where, when, and how the variable is updated (as it can be accessed literally anywhere in the program).
A better solution is to get rid of the global, and instead pass the variable like originally except by reference.
other_file.cpp
void func(std::string& new_name)
{
new_name += "_stuff";
}
main.cpp
int main()
{
std::string new_name = "bla";
func(new_name);
std::cout << new_name << std::endl;
return 0;
}
Now the global is gone (as is the globals.h file), and the output is still bla_stuff as intended.

WritePrivateProfileString works in main but not in function

I am trying to use WritePrivateProfileString and GetPrivateProfileInt for a .ini parser.
When I put the code below into main(), or into a class constructor, it works for writing and reading.
But, when I make functions for writing and reading, and call the functions in main(), nothing happens, although the functions are run as they will cout something if I ask them to.
Here is the test program I wrote to demonstrate this:
#include <iostream>
#include <Windows.h>
#include <fstream>
#include <string>
#define CStringify(x) std::to_string(x).c_str()
int testvar = 12;
int returntestvar = 0;
std::fstream config;
std::string configstring = ".//config.ini";
int main()
{
WriteINI();
ReadINI();
std::cout << returntestvar << std::endl;
getchar();
}
void WriteINI()
{
config.open("config.ini", std::ios::app);
WritePrivateProfileString("Test", "Test1", CStringify(testvar), configstring.c_str());
}
void ReadINI()
{
config.open("config.ini", std::ios::app);
returntestvar = GetPrivateProfileInt("Test", "Test1", 0, configstring.c_str());
}
The above code creates and then edits an .ini file, as it is expected to.
However, if I move the code into a class, it will no longer work.
main.cpp
#include <iostream>
#include <Windows.h>
#include <fstream>
#include <string>
#include "INIClassTest.h"
extern INIParser* Parse;
int main()
{
Parse->WriteINI();
Parse->ReadINI();
std::cout << Parse->returntestvar << std::endl;
getchar();
}
INIClassTest.h
#pragma once
#include <fstream>
#include <string>
#include <Windows.h>
#define CStringify(x) std::to_string(x).c_str()
class INIParser
{
public:
INIParser();
void WriteINI();
void ReadINI();
int testvar;
int returntestvar;
std::fstream config;
std::string configstring;
};
extern INIParser* Parse;
INIClassTest.cpp
#include "INIClassTest.h"
#include <iostream>
INIParser* Parse = new INIParser();
INIParser::INIParser()
{
returntestvar = 0;
testvar = 18;
std::string configstring = ".//config.ini";
}
void INIParser::WriteINI()
{
config.open("config.ini", std::ios::app);
WritePrivateProfileString("Test", "Test1", CStringify(testvar), configstring.c_str());
}
void INIParser::ReadINI()
{
config.open("config.ini", std::ios::app);
returntestvar = GetPrivateProfileInt("Test", "Test1", 0, configstring.c_str());
}
The above code creates an .ini file, but it doesn't edit it or return anything.
You should NOT be using an fstream at all to create/open the INI file manually. WritePrivateProfileString() and GetPrivateProfileInt() handle that for you.
Also, if you read their documentation, you would see that you SHOULD NOT use a relative path for the INI file, or else the file will be relative to the Windows installation folder, not your app folder. So, you probably ARE reading/writing the INI file, just not where you are expecting from/to. If you want your INI file to be relative to your app's folder, you need to retrieve the path of your app's folder 1 and append the INI filename to it.
1: that is really not a good idea in general, though. Depending on where you install your app, the user might not have write access to that folder. You should instead use SHGetFolderPath() or SHGetKnownFolderPath() to get the user's local %AppData% folder, then create your own subfolder inside of it, and then create your INI file inside of that subfolder.
Try this instead:
#include <Windows.h>
#include <iostream>
#include <string>
#define CStringify(x) std::to_string(x).c_str()
std::string GetAppFolder();
std::string GetINIPath();
void WriteINI();
void ReadINI();
int testvar = 12;
int returntestvar = 0;
std::string configstring = GetINIPath();
int main()
{
WriteINI();
ReadINI();
std::cout << returntestvar << std::endl;
std::cin.get();
return 0;
}
std::string GetAppFolder()
{
char szFileName[MAX_PATH];
DWORD len = GetModuleFileName(NULL, szFileName, MAX_PATH);
std::string result(szFileName, len);
std::string::size_type pos = result.find_last_of("\\/");
result.resize(pos+1);
return result;
}
std::string GetINIPath()
{
return GetAppFolder() + "config.ini";
}
void WriteINI()
{
WritePrivateProfileString("Test", "Test1", CStringify(testvar), configstring.c_str());
}
void ReadINI()
{
returntestvar = GetPrivateProfileInt("Test", "Test1", 0, configstring.c_str());
}
The main reason your INIParser class fails is because your constructor is storing the INI file path in a local variable named configstring, instead of in the class's member also named configstring. Thus, the class member is blank when WriteINI() and ReadINI() are called.
Try this instead:
main.cpp
#include <iostream>
#include "INIClassTest.h"
int main()
{
Parse.WriteINI();
Parse.ReadINI();
std::cout << Parse.returntestvar << std::endl;
std::cin.get();
return 0;
}
INIClassTest.h
#pragma once
#include <string>
class INIParser
{
public:
INIParser();
void WriteINI();
void ReadINI();
int testvar;
int returntestvar;
std::string configstring;
};
extern INIParser Parse;
INIClassTest.cpp
#include <Windows.h>
#include "INIClassTest.h"
#include <string>
#define CStringify(x) std::to_string(x).c_str()
INIParser Parse;
static std::string GetAppFolder()
{
char szFileName[MAX_PATH];
DWORD len = GetModuleFileName(NULL, szFileName, MAX_PATH);
std::string result(szFileName, len);
std::string::size_type pos = result.find_last_of("\\/");
result.resize(pos+1);
return result;
}
static std::string GetINIPath()
{
return GetAppFolder() + "config.ini";
}
INIParser::INIParser()
{
returntestvar = 0;
testvar = 18;
configstring = GetINIPath();
}
void INIParser::WriteINI()
{
WritePrivateProfileString("Test", "Test1", CStringify(testvar), configstring.c_str());
}
void INIParser::ReadINI()
{
returntestvar = GetPrivateProfileInt("Test", "Test1", 0, configstring.c_str());
}

C++ regex cstring error

I wrote this code:
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <regex>
using namespace std;
int compile()
{
string linecode;
linecode = "_hello:";
if (std::regex_match (linecode, std::regex("(_)(.*)(:)") ))
{
cout<<"...";
}
else if (std::regex_match (linecode, std::regex("(#)(.*)(:)") ))
{
cout<<"###";
}
return 1;
}
int main(int argc, char** argv)
{
compile();
return 0;
}
And i get this error:
enter image description here
cstring error, probably in regex library.
How i can fix this ?
Thanks in advance.

c++ put functions in separate source files

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