C++ : data file has error: Expected unqualified-id - c++

SIMPLY PUT Why does my text data file myData.cpp get the error Expected unqualified-id before '{' token? The file alone gives rise to this error and has been reproduced here http://coliru.stacked-crooked.com/a/7f32b5e643fb4d52
// ***** myData.cpp ******
{ // <---- error occurs here
{ "*****", "Error" },
{ "00-01", "Instructional exposition (textbooks, tutorial papers, etc.)" },
{ "00-02", "Research exposition (monographs, survey articles)" },
{ "00A05", "General mathematics" }
}
MORE DETAIL. Potentially helpful, but not necessary to reproduce error.
Right now, with 2 files main.cpp and myFunctions.cpp, everything works. But when I split it into 3 files main.cpp, myFunctions.cpp, and myData.cpp, I get the error Expected unqualified-id before '{' token.
I want to make it 3 files, because the text data for myData.cpp is pretty long and I don't want it to clutter myFunctions.cpp.
This is what I have as 2 files that compiles.
// ***** main.cpp *****
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include <string>
#include <iostream>
using namespace std;
extern size_t msc_get_no(const char*);
int main(int argc, char** argv)
{
assert(argc >= 0);
return (int)msc_get_no(argv[1]);
}
// ****** myFunctions.cpp *****
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
extern size_t msc_get_no(const char*);
struct msc_data
{
const char* code;
const char* desc;
};
typedef struct msc_data MSCDat;
static const MSCDat mscdat[] =
{
{ "*****", "Error" },
{ "00-01", "Instructional exposition (textbooks, tutorial papers, etc.)" },
{ "00-02", "Research exposition (monographs, survey articles)" },
{ "00A05", "General mathematics" }
}
;
static const size_t msccnt = sizeof(mscdat) / sizeof(mscdat[0]);
static int msc_cmp(const void* a, const void* b)
{
const char* msc_code = static_cast<const char*>(a);
const MSCDat* p = static_cast<const MSCDat*>(b);
return strcmp(msc_code, p->code);
}
size_t msc_get_no(const char* msc_code)
{
MSCDat* p;
p = (MSCDat*) bsearch(msc_code, &mscdat[0], msccnt, sizeof(mscdat[0]), msc_cmp);
return p - &mscdat[0];
}
This is what I have as 3 files that does not compile, because of the Expected unqualified-id error in myData.cpp. The only difference is with myFunctions.cpp, so I have excluded main.cpp and myData.cpp.
// ***** myFunctions.cpp *****
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
extern size_t msc_get_no(const char*);
struct msc_data
{
const char* code;
const char* desc;
};
typedef struct msc_data MSCDat;
static const MSCDat mscdat[] =
#include "myData.cpp" //<------ only here is different
;
static const size_t msccnt = sizeof(mscdat) / sizeof(mscdat[0]);
static int msc_cmp(const void* a, const void* b)
{
const char* msc_code = static_cast<const char*>(a);
const MSCDat* p = static_cast<const MSCDat*>(b);
return strcmp(msc_code, p->code);
}
size_t msc_get_no(const char* msc_code)
{
MSCDat* p;
p = (MSCDat*) bsearch(msc_code, &mscdat[0], msccnt, sizeof(mscdat[0]), msc_cmp);
return p - &mscdat[0];
}
THANK YOU

Your IDE tries to compile myData.cpp by itself. But this file is only an include file. If you rename it to myData.h (or even
myData.dat) everthing should be fine.

Related

How do I fix this c++ expected expression error?

I am making something in c++, it doesn't have any errors visible in Visual Studio code, but when I use g++ to be able to execute it, I get this error:
In file included from Main.cpp:6: In file included from ./Filechange/Filechange.hpp:1: ./Filechange/Filechange.cpp:14:24: error: expected expression
std::thread first ([&wtime,&f,&fn]() mutable {
^ Main.cpp:16:33: error: expected expression
OnFilechange("FileEvent", 0.5, [](char* txt){
^ 2 errors generated.
These are the files:
Main.cpp:
#include <lua.hpp>
#include <iostream>
#include <chrono>
#include <thread>
#include <stdio.h>
#include "Filechange/Filechange.hpp"
void wait(int seconds)
{
std::this_thread::sleep_for(std::chrono::seconds(seconds));
}
int main(int argc, char const *argv[])
{
lua_State *State = luaL_newstate();
OnFilechange("FileEvent", 0.5, [](char* txt){
std::cout << txt << std::endl;
});
lua_close(State);
return 0;
}
Filechange.cpp:
#include <thread>
#include <stdio.h>
#include <stdlib.h>
#include <chrono>
#include <string>
#include <fstream>
char* StringToChar(std::string str){
char* Array = new char[str.length() + 1];
strcpy(Array,str.c_str());
return Array;
}
void OnFilechange(const char *f, float wtime, void (*fn)(char* txt)){
std::thread first ([&wtime,&f,&fn]() mutable {
std::ifstream file(f);
std::string str;
std::string filecontents;
while (std::getline(file,str)){
filecontents += str;
filecontents.push_back('\n');
}
char* LastContents = StringToChar(filecontents);
char* CurrentContents = StringToChar(filecontents);
while (true){
if (wtime != 0){
std::this_thread::sleep_for(std::chrono::milliseconds(int(wtime*1000)));
}
filecontents = "";
while (std::getline(file,str)){
filecontents += str;
filecontents.push_back('\n');
}
CurrentContents = StringToChar(filecontents);
if (strcmp(LastContents, CurrentContents) != 0){
LastContents = StringToChar(filecontents);
fn(StringToChar(filecontents));
}
}
});
}
Filechange.hpp:
#include "Filechange.cpp"
#ifndef FILECHANGE_HPP
#define FILECHANGE_HPP
#include <thread>
#include <stdio.h>
#include <stdlib.h>
#include <chrono>
#include <string>
#include <fstream>
void OnFilechange(const char *f,float wtime,void (*fn)(char txt));
#endif
There's also a extension less file named FileEvent which will change in the runtime using other code files.
The Filechange.cpp and Filechange.hpp are in a folder named "Filechange"
This function:
void OnFilechange(const char *f, float wtime, void (*fn)(char* txt))
expects a function pointer, and a lambda in g++ is not implemented as a function pointer. Instead, you should declare the function to take a std::function, as in:
void OnFilechange(const char *f, float wtime, std::function<void(char *)> fn)
You may also need #include <functional> to get the declaration of std::function.
use -std=c++17 in g++ if possible as g++ defaulted to c++98

Unsure how to decorate my C++ library code for use in C

We have defined some methods to allow for ad-hoc console input when required. The methods are contained within a namespace and define and use a class to perform the actual work.
The definions, stripped down for brevity:
ConsoleInput.h
#include <cstddef>
#include <map>
#include <memory>
#include <vector>
namespace MyNameSpc
{
typedef std::vector<char> buffer_t;
class ConsoleInput
{
// Methods for windows and linux console input
}
int GetString(buffer_t &buffer, ...);
}
RequestInput.h
#include "ConsoleInput.h"
#include <cstddef>
#include <string>
namespace MyNameSpc
{
const std::string empty = std::string();
class RequestInputParam
{
// Methods
}
int RequestInput(buffer_t &buffer);
int RequestInput(buffer_t &buffer, const RequestInputParam &param);
// and other overloads
}
ConsoleInput.cpp
#include "ConsoleInput.h"
#include "RequestInput.h"
#include <cstddef>
#include <iostream>
#include <memory>
#include <string>
#include <fcntl.h>
#include <stdio.h>
// and other headers.
namespace MyNameSpc
{
// implements class ConsoleInput methods.
// Implements GetString()
}
RequestInput.cpp
#include "ConsoleInput.h"
#include "RequestInput.h"
#include <cstddef>
#include <iostream>
#include <memory>
#include <string>
namespace MyNameSpc
{
// implements the overloaded methods.
}
And we call them by #include RequestInput.h and then calling int retVal = MyNameSpc::RequestInput(...). This all works fine when all of the code is C++. I now have to reference this code from C code which was recently dropped into our repository. I don't think I can (well, I -can-, but I think it's going to break other things) simply compile the C code as C++, so I really do need to somehow pull this into C.
When I tried to build, I was getting initial errors about not finding the iostream header.. makes sense, but, after reading about extern "C", I am unclear how to proceed, when I have these C++ headers in the code, classes (the only one I might need to reference is the parameter class) and namespaces.
UPDATE
I have reviewed the links which were provided and attempted to make use of the information from here and here. I am having no success with this.
RequestInputWrapper.h
#ifndef REQUEST_WRAPPER_H
#define REQUEST_WRAPPER_H
#include <stddef.h>
#include "RequestInput.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct RequestInputParam RequestInputParam; // line 29
RequestInputParam* CreateRequestInputParam();
void DisposeRequestInputParam( RequestInputParam* pObject );
void C_AddMainPrompt(RequestInputParam *param, char *msg);
int C_RequestInputAllocPtr(char * * const ppInput,
unsigned int * const pInputLen);
int C_RequestInput(char * const pInput,
unsigned int * const pInputLen);
#ifdef __cplusplus
}
#endif
#endif /* REQUEST_WRAPPER_H */
RequestInputWrapper.cpp
#include "RequestInput.h"
#include "RequestInputWrapper.h" // line 13
#ifdef __cplusplus
extern "C" {
#endif
RequestInputParam* CreateRequestInputParam()
{
return new RequestInputParam(); // line 25
}
void DisposeRequestInputParam( RequestInputParam* pObject ) // line 28
{
if ( pObject != NULL )
{
delete pObject; // line 32
pObject = NULL;
}
}
void C_AddMainPrompt(RequestInputParam *param, char *msg) { param->AddMainPrompt( msg ); }
int C_RequestInputAllocPtr(char * * const ppInput,
unsigned int * const pInputLen)
{
return RequestInput(ppInput, pInputLen);
}
int C_RequestInput(char * const pInput,
unsigned int * const pInputLen)
{
return RequestInput(pInput, pInputLen);
}
#ifdef __cplusplus
}
#endif
It is currently throwing the following errors (I C&P only the first portion, it started getting repetitive; the line numbers won't match the code above, which has been stripped of all comments and such so I added comments with the noted line #'s):
cli/RequestInputWrapper.cpp: In function ‘RequestInputParam* CreateRequestInputParam()’:
cli/RequestInputWrapper.cpp:25:35: error: invalid use of incomplete type ‘RequestInputParam {aka struct RequestInputParam}’
return new RequestInputParam();
^
In file included from cli/RequestInputWrapper.cpp:13:0:
./Include/RequestInputWrapper.h:29:16: error: forward declaration of ‘RequestInputParam {aka struct RequestInputParam}’
typedef struct RequestInputParam RequestInputParam;
^
cli/RequestInputWrapper.cpp: In function ‘void DisposeRequestInputParam(RequestInputParam*)’:
cli/RequestInputWrapper.cpp:32:16: error: possible problem detected in invocation of delete operator: [-Werror]
delete pObject;
^
cli/RequestInputWrapper.cpp:28:6: error: ‘pObject’ has incomplete type [-Werror]
void DisposeRequestInputParam( RequestInputParam* pObject )
^
In file included from cli/RequestInputWrapper.cpp:13:0:
./Include/RequestInputWrapper.h:29:16: error: forward declaration of ‘struct RequestInputParam’ [-Werror]
typedef struct RequestInputParam RequestInputParam;
^
cli/RequestInputWrapper.cpp:32:16: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined
delete pObject;
^
I suspect the answers in the articles suggested as "duplicates" have simply been written and not tested. After more searching, I eventually stumbled across this answer which offered the guidance needed to get this to build.
In short, I was missing the namespace in my C++ wrapper code (facepalm) and I had to add the reinterpret_cast calls. I also changed the name of the type in the typedef... I thought it was referencing the C++ type (as that was what at least one example seemed to show) but, nope... it needs to be it's own struct type.
RequestInputWrapper.h
#ifndef REQUEST_WRAPPER_H
#define REQUEST_WRAPPER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
typedef struct C_RequestInputParam C_RequestInputParam;
C_RequestInputParam * CreateRequestInputParam();
void DisposeRequestInputParam( C_RequestInputParam *pObject );
void C_AddMainPrompt( C_RequestInputParam *param, char *msg);
int C_RequestInputAllocPtr( char * * const ppInput,
unsigned int * const pInputLen );
int C_RequestInput( char * const pInput,
unsigned int * const pInputLen );
#ifdef __cplusplus
}
#endif
#endif /* REQUEST_WRAPPER_H */
RequestInputWrapper.cpp
#include "RequestInput.h"
#include "RequestInputWrapper.h"
extern "C" {
C_RequestInputParam * CreateRequestInputParam()
{
return reinterpret_cast< C_RequestInputParam * >( new RequestInputParam() );
}
void DisposeRequestInputParam( C_RequestInputParam *pObject )
{
if ( pObject != NULL )
{
delete reinterpret_cast< MyNameSpc::RequestInputParam * >( pObject );
pObject = NULL;
}
}
void C_AddMainPrompt( C_RequestInputParam *param, char *msg )
{
reinterpret_cast< MyNameSpc::RequestInputParam * >( param )->AddMainPrompt( msg );
}
int C_RequestInputAllocPtr( char * * const ppInput,
unsigned int * const pInputLen )
{
return MyNameSpc::RequestInput( ppInput, pInputLen );
}
int C_RequestInput( char * const pInput,
unsigned int * const pInputLen )
{
return MyNameSpc::RequestInput( pInput, pInputLen );
}
}

C and C++ : data file with error "Expected unqualified-id" [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I would like to run C code in C++, using Xcode 8.33 on MacOS Sierra 10.12. I am new to C/C++, compilers, etc so please bear with me. The C code, when compiled and ran with make via Terminal, works. But when I throw all the same files into a XCode C++ project, there is an error with the data file. Note: I did change main.c to main.cpp.
//**** main.cpp *****
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
extern "C" {
#include "msclib.h"
}
int main(int argc, char** argv)
{
assert(argc >= 1);
return msc_get_no(argv[1]);
}
The file msclib.c calls on the data file mscmix_dat.c. Here is also msclib.h
// ***** msclib.h *****
extern size_t msc_get_no(const char*);
// ***** msclib.c *****
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include "msclib.h"
struct msc_data
{
const char* code;
const char* desc;
};
typedef struct msc_data MSCDat;
static const MSCDat mscdat[] =
#include "mscmix_dat.c"
;
static const size_t msccnt = sizeof(mscdat) / sizeof(mscdat[0]);
static int msc_cmp(const void* a, const void* b)
{
const char* msc_code = a;
const MSCDat* p = b;
return strcmp(msc_code, p->code);
}
size_t msc_get_no(const char* msc_code)
{
assert(NULL != msc_code);
assert(strlen(msc_code) == 5);
MSCDat* p = bsearch(msc_code, &mscdat[0], msccnt, sizeof(mscdat[0]), msc_cmp);
if (NULL == p)
{
fprintf(stderr, "MSC \"%s\" not valid\n", msc_code);
return 0;
}
assert(NULL != p);
return p - &mscdat[0];
}
When running/compiling, the mscmix_dat.c file gets the error Expected identifier or ( - which is what I need help with. Even when I replace mscmix_dat.c with .cpp, I get the error Expected unqualified-id
// ***** mscmix_dat.c *****
{ //<-- Xcode highlights this line and gives the error
{ "*****", "Error" },
{ "00-01", "Instructional exposition (textbooks, tutorial papers, etc.)" },
{ "00-02", "Research exposition (monographs, survey articles)" },
{ "00A05", "General mathematics" },
.
.
.
}
I would appreciate explanations as to why this error is occurring, suggestions on how to fix it, and if necessary alternatives to processing this data file. Thank you!
OP here. These are the steps I took to resolve my issue, based on the last edit of my question:
With the separate files, as given in my question, the error was Expected identifier in mscmix_dat.c.
Per #LightnessRacesinOrbit's suggestion, I consolidated the multiple main.cpp, msclib.h, msclib.c, and mscmix_dat.c files into two files: main.cpp and msclib.c, by replacing the #include thisfile.c with the actual file code content. I also changed msclib.c to .cpp via simple rename. This eliminated the original error of Expected identifier, but a new one arose.
Compiling the two files gave multiple errors in msclib.cpp, all wrt variable type conversions.
Because of C++ differences from C, I handled the type conversion issue via casting, but also respecting const.
Below is my final, successfully compiling code.
// **** main.cpp ****
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include<string>
#include<iostream>
using namespace std;
extern size_t msc_get_no(const char*);
int main(int argc, char** argv)
{
assert(argc >= 0);
return (int)msc_get_no(argv[1]); // casting
}
// **** msclib.cpp ****
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
extern size_t msc_get_no(const char*);
struct msc_data
{
const char* code;
const char* desc;
};
typedef struct msc_data MSCDat;
static const MSCDat mscdat[] =
{
{ "*****", "Error" },
{ "00-01", "Instructional exposition (textbooks, tutorial papers, etc.)" },
{ "00-02", "Research exposition (monographs, survey articles)" },
{ "00A05", "General mathematics" }
}
;
static const size_t msccnt = sizeof(mscdat) / sizeof(mscdat[0]);
static int msc_cmp(const void* a, const void* b)
{
const char* msc_code = static_cast<const char*>(a); //<----
const MSCDat* p = static_cast<const MSCDat*>(b); // (const MSCDat*)b also works
return strcmp(msc_code, p->code);
}
size_t msc_get_no(const char* msc_code)
{
assert(NULL != msc_code);
assert(strlen(msc_code) == 5);
MSCDat* p; // changed initialization of p
p = (MSCDat*) bsearch(msc_code, &mscdat[0], msccnt, sizeof(mscdat[0]), msc_cmp);
if (NULL == p)
{
fprintf(stderr, "MSC \"%s\" not valid\n", msc_code);
return 0;
}
assert(NULL != p);
return p - &mscdat[0];
}

c++ overloaded member function not found in 'ShaderProgram

What's wrong I'm doing? Strange, because signature of constructor is the same. The compiler says:
'ShaderProgram::ShaderProgram(std::vector< int*, std::allocator< _Ty >>)': overloaded member function not found in 'ShaderProgram'.
This error occures, when I use 3 files with code(below), but when I put this code in 1 file(main cpp) - it works
//main.cpp
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include "ShaderHelpers.h"
int main(int argc, const char* argv[]) {
int* a = new int(5);
int* b = new int(7);
ShaderProgram *sp = new ShaderProgram(std::vector<int*>{ a, b});
return 0;
}
================================================================
//shader.cpp
#include "ShaderHelpers.h"
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <string>
ShaderProgram::ShaderProgram() { }
ShaderProgram::ShaderProgram(std::vector<int*> shaders)
{
Shaders = shaders;
for each (int* i in shaders)
{
std::cout << i;
}
}
ShaderProgram::~ShaderProgram()
{
std::cout << "delete";
}
===============================================================
//ShaderHelper.h
#pragma once
#include <string>
class ShaderProgram
{
public:
std::vector<int*> Shaders;
ShaderProgram(std::vector<int*> shaders);
~ShaderProgram();
private:
ShaderProgram();
};
I just needed to add
# include <vector>
into the ShaderHelper.h

error: request for member which is of non class type

I am using forward declaration and now I am getting an error referring to the class that uses the forward declaration...so fInstance forward declares fConfig and then the Helper class (a namespace - used for global access to functions) - getting t
fConfig.h
#ifndef FCONFIG_H
#define FCONFIG_H
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <fcntl.h>
#include "JWDSFork.h"
//#include "fInstance.h"
using namespace std;
class fConfig
{
private:
pid_t pid, w;
public:
pid_t cPid;
string name;
int group;
int instanceId;
int numInstance;
int tries;
bool reply;
bool debug;
bool service;
bool currentlyRunning;
time_t startTime;
time_t endTime;
string path;
fConfig();
virtual ~fConfig();
void start();
string intToString(int);
char* stringToChar(string);
};
#endif // FCONFIG_H
fInstance.h
#ifndef FINSTANCE_H
#define FINSTANCE_H
//#include "fConfig.h"
#include <vector>
#include <sys/types.h>
#include <string>
using namespace std;
class fConfig;
class fInstance
{
public:
fConfig* config;
pid_t pid;
vector<string> notes;
vector<time_t> times;
fInstance();
virtual ~fInstance();
};
#endif // FINSTANCE_H
Helper.h
#ifndef HELPER_H
#define HELPER_H
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <sstream>
#include <limits.h>
#include "fInstance.h"
using namespace std;
namespace Helper
{
extern string APPDIR;
bool errorCheck(int, char*);
string charToString(char*, int);
string longToString(unsigned long);
bool Contains(vector<fInstance>, fInstance);
string convertInt(int);
string convertDouble(double);
bool Read(int, char*, size_t);
bool Write(int, char*, size_t);
};
#endif // HELPER_H
Helper.cpp
//Helper.cpp - function that causes a problem
#include "Helper.h"
namespace Helper
{
bool Contains(vector<fInstance> a, fInstance b)
{
for(unsigned int i= 0; i < a.size(); i++ )
{
if(a[i].config.name == b.config.name)
{
return true;
}
}
return false;
}
}
I am getting these errors
error: request for member ‘name’ in ‘a.std::vector<_Tp, _Alloc>::operator[] [with _Tp = fInstance, _Alloc = std::allocator<fInstance>](((long unsigned int)i))->fInstance::config’, which is of non-class type ‘fConfig*’
That's a pretty unfriendly error message, but what it means is that the config member is a pointer, so you need to use the -> operator instead, ie.
if(a[i].config->name == b.config->name)
Assuming that you have an operator== overloaded for your type fInstance, you can write your function as (note also that you should pass your parameters a and b by reference-to-const)
#include<algorithm>
bool fInstance::operator==(const fInstance& other)
{
return config->name == other.config->name;
}
bool Contains(const vector<fInstance>& a, const fInstance& b)
{
return std::find_if(a.begin(), a.end(), b);
}
If you don't have an operator== in your fInstance class, you can use a C++11 lambda expression
bool Contains(const vector<fInstance>& a, const fInstance& b)
{
return std::find_if(a.begin(), a.end(),
[](const fInstance& i) { return i.config->name == b.config->name; });
}
And even better yet, you should encapsulate the name member into a member function of fInstance:
std::string fInstance::name() { return config->name; };
bool Contains(const vector<fInstance>& a, const fInstance& b)
{
return std::find_if(a.begin(), a.end(),
[](const fInstance& i) { return i.name() == b.name(); });
}
This increases encapsulation, decreases compilation times and makes the implementation of the fInstance class opaque to its clients. Your current implementation leaves the fConfig implementation transparant to clients. This decrease in encapsulation is called a violation of the Law of Demeter.