Name followed by :: must be a class or namespace name - c++

I have reviewed numerous articles on this subject both here and elsewhere on the internet and have developed my code to conform with what I've learned. Unfortunately, that doesn't seem to solve this problem. Here are the pieces of the puzzle:
The defined class:
class FileData {
private:
char* filename;
public:
FileData();
void CloseFile(std::fstream file);
int DeleteFile(char* fname);
int FileExist(char* fname);
int OpenDestFile(std::fstream file, char* fname);
int OpenListFile(std::fstream file, char* fname);
int OpenSourceFile(std::fstream file, char* fname);
int ReadBuffer(std::fstream file, char* Buffer);
int ReadListFile(std::fstream file);
int WipeFile(char* fname);
int WriteBuffer(std::fstream file, char* Buffer);
};
The constructor code:
FileData::FileData() : filename(nullptr) {}
The defined function that I'm having an issue with (does not matter which function of the class...they all have the same error):
int FileData::OpenListFile(std::fstream file, char* fname) {
int ccode;
ccode = 0;
file.open(fname, std::fstream::in);
if (file.bad()) {
ccode = -1;
}
return ccode;
}
As a global variable I declare FileRec as an class of FileData:
FileData FileRec;
Here is the actual function call that generates the error:
if ((ccode = FileRec::OpenListFile(&ListFile, fspec3)) != 0) {
// ....
}
Any help would be greatly appreciated. Thanks.

You have declared OpenListFile() as an instance method, not as a static method. FileRec is an instance of the FileData class. You need to use the . operator to access members of an object instance, eg:
FileData FileRec;
std::fstream ListFile;
...
if ((ccode = FileRec.OpenListFile(ListFile, fspec3)) != 0) {
// ...
}
Otherwise, use static for any methods that don't need to access any data members of the FileData class, and then use the class name instead of the instance name when using ::, eg:
class FileData {
public:
static void CloseFile(std::fstream file);
static int DeleteFile(char* fname);
static int FileExist(char* fname);
static int OpenDestFile(std::fstream file, char* fname);
static int OpenListFile(std::fstream file, char* fname);
static int OpenSourceFile(std::fstream file, char* fname);
static int ReadBuffer(std::fstream file, char* Buffer);
static int ReadListFile(std::fstream file);
static int WipeFile(char* fname);
static int WriteBuffer(std::fstream file, char* Buffer);
};
...
int FileData::OpenListFile(std::fstream file, char* fname) {
file.open(fname, std::fstream::in);
return file.bad() ? -1 : 0;
}
...
std::fstream ListFile;
if ((ccode = FileData::OpenListFile(ListFile, fspec3)) != 0) {
// ....
}
That said, note that you can't pass around a std::fstream by value, as std::fstream is not copyable. You need to pass it by reference or by pointer instead:
...
int OpenListFile(std::fstream& file, char* fname);
...
...
int OpenListFile(std::fstream* file, char* fname);
...

Related

I am trying to solve the problem in C++ Files and Streams

#include <iostream>
class Model
{
public:
Model(const char *a)
{
message=a;
}
const char *car() { return message; }
const char *message;
};
class ModelCar
{
public:
ModelCar(const char *sn, const char *b="c")
{
filename=strdup(sn);
f=fopen(sn,b);
if (f==NULL)
{
throw Model("File can't be opened");
}
}
~ModelCar()
{
delete [] filename;
if (fclose(f)<0)
{
throw Model("File can't be closed");
}
}
void read(char *buf, int size)
{
if (fread(buf, 1, size, f)!=size)
{
throw Model("File can't be read");
}
}
const char *filename;
FILE *f;
};
Why I am getting error: ‘strdup’ was not declared in this scope , I tried and add #include <string.h> but still getting error
Can anyone please help me what is wrong in this code
First of all I suggest you to fix some problems with the code:
1.
delete [] filename;
filename=strdup(sn);
Okay your delete function suggests that your filename is a dynamic array which you never intialized. Also have you looked at what strdup returns, it returns a dynamic char, not an dynamic array. I would suggest you change:
delete [] filename;
to
free(filename);

Error using "enum" within a class

I get the following error message about my enum, and I can't figure out why.
I have only 1 header file and only 1 source file where I implemented all the functions (and main). I declared the enum within class "Survivor", in "public". I didn't forget to include the header file in the source file. Please help me see what I've done wrong.
"error: 'e_status' does not name a type"
This is my header file:
class Survivor
{
public:
enum e_status {SINGLE, MARRIED, RELATIONSHIP};
char* get_name();
int get_age();
e_status get_status();
void set_name(char n[]);
void set_age (int a);
void set_status (e_status s);
const void print();
private:
char name [20];
int age;
e_status status;
};
This is the relevant part in my Source file:
e_status Survivor::get_status()
{
return status;
}
You have to use a qualified name
Survivor::e_status Survivor::get_status()
{
//...
}
The type e_status is a member of the class Survivor.
A return type of a member function is not searched in the class scope while for example a parameter type is used in the class scope.
Consider the following two function definitions.
#include <iostream>
class Survivor
{
public:
enum e_status {SINGLE, MARRIED, RELATIONSHIP};
e_status get_status();
void set_status (e_status s);
//...
private:
e_status status;
};
Survivor::e_status Survivor::get_status()
{
return status;
}
void Survivor::set_status (e_status s)
{
status = s;
}
int main()
{
return 0;
}
You're trying to reference outside the class; do this:
Survivor::e_status Survivor::get_status()

I want to pass in constructor mode of file

I created child class of ofstream. I want to pass in constructor mode of file. For example ios::app. How can i do it ? What should i write in my_file constructor to put it in ofstream class constructor? I know that it's int type but how to understand what is value of ios::app?
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
class my_file : public ofstream {
string name;
public:
my_file(string name, const char* filename) : ofstream(filename) { this->name = name; }
inline const string get() { return this->name; }
};
int main(void) {
my_file file("Name","new.txt" /* , ios::app */ );
return 0;
}
I know that it's int type but how to understand what is value of ios::app?
Wrong, that's not a int!
Go to ofstream doc http://www.cplusplus.com/reference/fstream/ofstream/, then click (constructor) to see what the parameters are and then you can see that mode is of type std::ios_base::openmode (as described here)
So simply do:
class my_file : public ofstream {
string name;
public:
my_file(string name, const char* filename, std::ios_base::openmode mode ) : ofstream(filename,mode) { this->name = name; }
inline const string get() { return this->name; }
};
Then:
my_file file("Name","new.txt", ios::app);

C++ - '(const char*)' not declared in scope? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I want to make a custom String class for C++. But when I do this:
g++ test.cpp sys/Base.h sys/Base.cpp
I get this error:
sys/Base.cpp: In function 'const char* Base::toChar()':
sys/Base.cpp:57:13: error: 'strval' was not declared in this scope
return strval;
^
sys/Base.cpp: In function 'std::string Base::toStr()':
sys/Base.cpp:60:20: error: 'strval' was not declared in this scope
return string(strval);
^
test.cpp
#include "sys/Base.h"
int main() {
Base::write("Hello there.\n");
return 0;
}
sys/Base.h
// Header file handling
#ifndef ARAVK_BASE_H
#define ARAVK_BASE_H
// Includes
#include <string>
// Global variables
#define EXIT_YAY 0
#define EXIT_ERR 1
using namespace std;
namespace Base {
// Classes:
class String {
static const char* strval;
public:
// Constructors:
String();
String(char[]);
String(const char*);
String(string);
// Destructors:
~String();
// Operators:
// =
void operator=(const String&);
void operator=(const char*&);
void operator=(const string&);
// Conversion:
const char* toChar() const;
string toStr() const;
};
// Functions:
// Input-Output:
// Write:
void write(String);
void write(string);
void write(const char*);
// Read:
String read();
// Executing:
String run(String);
}
#endif
sys/Base.cpp
// Including
#include "Base.h"
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
// Global variables
#define EXIT_ERR 1
#define EXIT_YAY 0
/* ------------------------ */
using namespace std;
namespace Base {
// Classes
// String functions
// Constructors
String::String() {
const char* strval = "";
}
String::String(const char* str) {
const char* strval = str;
}
String::String(string str) {
const char* strval = str.c_str();
}
String::String(char str[]) {
const char* strval = str;
}
// Destructors
String::~String() {
delete strval;
}
// Operators
// =
void String::operator=(const String &strp) {
strval = strp.toChar();
}
void String::operator=(const char* &strp) {
strval = strp;
}
void String::operator=(const string &strp) {
strval = strp.c_str();
}
// Conversion:
const char* toChar() {
return strval;
}
string toStr() {
return string(strval);
}
// Functions:
// Input-Output:
// Write
void write(String str) { printf(str.toChar()); }
void write(const char* str) { printf(str); }
void write(string str) { printf(str.c_str()); }
// Read
String read() { char str[100]; scanf("%s", str); return String(str); }
//TODO: More to come
// Executing
/*String run(String command) {
const char* cmd = command.toChar();
char buffer[128];
string result = "";
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) throw runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer, 128, pipe.get()) != NULL)
result += buffer;
}
return String(result);
}*/
String run(String command) {
char buffer[128];
std::string result = "";
const char* cmd = command.toChar();
FILE* pipe = popen(cmd, "r");
if (!pipe) throw std::runtime_error("popen() failed!");
try {
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
} catch (...) {
pclose(pipe);
throw;
}
pclose(pipe);
return String(result);
}
}
I'm not sure why this is happening. I think it's related to how I've declared/defined the const char* 'strval'. Can anybody help?
P.S: If the answer is too big, this project is on Github: AravK/C-Applications
Let's take a look at your constructor:
String::String() {
const char* strval = "";
}
This declares a local variable called strval. The variable is local to the constructor; it doesn't exist once execution of the constructor completes.
What you need instead is a member variable - declare it inside the class, but not inside a member method or constructor. In fact, you have already defined it as such in the header file:
class String {
static const char* strval;
So, remove the const char * from your constructor and add a class qualifier, so that the line becomes an assignment to the existing variable, rather than creation of a local:
String::String() {
String::strval = "";
}
And also change the return statement that is giving you the error:
return String::strval;
Or perhaps - and this is likely what you really wanted - remove the static qualifier from the variable definition, and change the constructor instead to just:
String::String() {
strval = "";
}
Furthermore, your destructor incorrectly deletes data that was not necessarily dynamically allocated, or which may belong to another object:
String::~String() {
delete strval;
}
This requires re-working. At the moment the simplest solution is to remove the delete strval altogether.
Your read() function potentially instigates a buffer overflow, by using scanf("%s") with a fixed size buffer and unknown input size:
char str[100]; scanf("%s", str); return String(str);
Finally, your command line:
g++ test.cpp sys/Base.h sys/Base.cpp
... should not include the header file (Base.h). You are specifying the units you want compiled, and Base.h is already included in Base.cpp; it is not a standalone unit that should be compiled invidually.
yes you did not define the variable in your class as a field.
there is 3 locals déclaration in your constructors.
just add it the way you have done in the header.
static const char* strval
and remove the définition in your constructors. Just keep the assignement part.
regards

C++, Access violation

I have started to learn C++ some weeks ago and now I have a problem with my current project.
I wanted to write templates, that allow me to save objects into binary datas and load them again later. Here ist the code of these templates:
#ifndef TOOLS_H
#define TOOLS_H
#include <fstream>
#include <string>
namespace Tools
{
template <class T>
void writeBinaryFile(std::string filename, T object)
{
std::ofstream of(filename, std::ios::out | std::ios::binary);
of.write((char*) &object, sizeof(T));
of.close();
}
template <class P>
P readBinaryFile(std::string filename)
{
P temp;
std::ifstream ifs(filename, std::ios::in | std::ios::binary);
ifs.read((char*) &temp, sizeof(P));
ifs.close();
return temp;
}
}
#endif
I created a class called GameSettings. The header data is:
#ifndef GAMESETTINGS_H
#define GAMESETTINGS_H
#include <iostream>
#include <string>
#include "SFML\Graphics.hpp"
class GameSettings
{
public:
GameSettings();
GameSettings(std::string playerName, bool sound, int volume, int level);
~GameSettings();
void setPlayerName(std::string playername){ playerName = playername; };
void setSound(bool sound){ this->sound = sound; };
void setVolume(int volume){ this->volume = volume; };
void setLevel(int level){ this->level = level; };
const std::string getPlayerName() { return playerName; }
const bool getSound() { return sound; }
const int getVolume() { return volume; }
const int getLevel() { return level; }
private:
std::string playerName;
bool sound;
int volume;
int level;
};
#endif
With the cpp-data:
#include "GameSettings.h"
GameSettings::GameSettings(std::string playerName, bool sound, int volume, int level)
{
this->playerName = playerName;
this->sound = sound;
this->volume = volume;
this->level = level;
}
GameSettings::GameSettings():
playerName(""),
sound(true),
volume(0),
level(0)
{
}
GameSettings::~GameSettings()
{
}
When I start the main-function:
#include <iostream>
#include "GameSettings.h"
#include "Tools.h"
int main()
{
GameSettings* gs = new GameSettings("Andrew", true, 100, 3);
Tools::writeBinaryFile<GameSettings>("gamesettings.bin", *gs);
gs->setPlayerName("TEST");
*gs = Tools::readBinaryFile<GameSettings>("gamesettings.bin");
std::cout << gs->getPlayerName();
std::getchar();
return 0;
}
an error occurs:
Unhandled exception at 0x5a1cad54 (msvcp100d.dll) in Mohrhuhn.exe: 0xC0000005: Access violation writing location 0xfeeefeee.
Can somebody help me?
Sincerly, Andrew
I think the root of the trouble is
*gs = Tools::readBinaryFile<GameSettings>("gamesettings.bin");
You read raw bytes to a variable that contains std::string. It may ruin char pointer inside it. So, any call to playerName should fail or result in UB.
Only POD types can be read/write this way. A bit more I found on another web-page: http://www.cplusplus.com/forum/general/39764/
The template you implement to serialize the object will not work because casting the std::string to char* and saving sizeof(std::string) will not save the content of the string.
Check the saved file, but I guess you need to implement properly serialization and deserialization.
First of all writing down binary files by just dumping them from memory is a bad idea since you might incur in lots of additional problems (e.g. shallow copies, polimorphism, etc..)
return temp;
You are returning a temporary object that is being destroyed after the function exits.
Change your code into
gs = Tools::readBinaryFile<GameSettings>("gamesettings.bin");
...
template <class P>
P* readBinaryFile(std::string filename)
{
P* temp = new P();
std::ifstream ifs(filename, std::ios::in | std::ios::binary);
ifs.read((char*) temp, sizeof(P));
ifs.close();
return temp;
}
and everything will work out properly (psst. remember to free the memory!)