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

#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);

Related

Name followed by :: must be a class or namespace name

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);
...

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

Compile in Linux/Unix issue C++

This is only part of an overall program and compiles and runs fine in Windows, however it does not like my strcpy in Linux/Unix. What am I doing wrong and how can I fix it? Also a note, I am not allowed to use string, only cstring.
Song.cpp
#include "Song.h"
Song::Song()
{
}
Song::~Song()
{
}
Song::Song(char* title, char* artist, char* duration, char* album)
{
strcpy(this->title,50,title);
strcpy(this->artist, 50, artist);
strcpy(this->duration, 50, duration);
strcpy(this->album, 50, album);
}
void Song::setTitle(char* title)
{
this->title= title;
}
void Song::setArtist(char* artist)
{
this->artist = artist;
}
void Song::setDuration(char* duration)
{
this->duration= duration;
}
void Song::setAlbum(char* album)
{
this->album= album;
}
char* Song::getTitle()
{
return this->title;
}
char* Song::getArtist()
{
return this->artist;
}
char* Song::getDuration()
{
return this->duration;
}
char* Song::getAlbum()
{
return this->album;
}
Song.h
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <cctype>
using namespace std;
class Song
{
private:
char* title;
char* artist;
char* duration;
char* album;
public:
Song();
~Song();
Song(char* title, char* artist, char* duration, char* album);
void setTitle(char* title);
void setArtist(char* artist);
void setDuration(char* duration);
void setAlbum(char* album);
char* getTitle();
char* getArtist();
char* getDuration();
char* getAlbum();
};
You haven't allocated any memory for strcpy to copy into. Thus your constructor invokes undefined behavior.
You need to allocate a character array first. But then you also need to deallocate it in each of your setters. Otherwise the memory will be leaked, since you're reassigning the pointer that manages it.

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!)

Pushing to custom stack class freezing .exe

I'm using a stack class, however every time I push something to the stack, the executable freezes and stops working once the line of code pushing is reached.
Could I please get some help on as to why?
My stack.h:
#ifndef STACK_H
#define STACK_H
#include <cassert>
namespace standard
{
class Stack
{
public:
static const int CAPACITY = 30;
void stack() {used=0;};
void push (const char entry);
void pop();
bool empty() const;
int size() const;
char top() const;
private:
char data[CAPACITY];
int used;
};
}
#endif
My stack.cpp:
#include "stack.h"
namespace standard
{
void Stack::push(const char entry)
{
assert(size() < CAPACITY);
data[used] = entry;
++used;
}
void Stack::pop()
{
assert(!empty());
--used;
}
char Stack::top() const
{
assert(!empty());
return data[used-1];
}
int Stack::size() const
{
return used;
}
bool Stack::empty() const
{
if (size() == 0)
return true;
else
return false;
}
}
My calc.cpp:
#include "stack.h"
#include <iostream>
#include <fstream>
using namespace std;
using namespace standard;
void main()
{
Stack myStack;
ifstream input;
input.open("tests.txt");
if (input.fail())
{
cerr << "Could not open input file." << endl;
exit(0);
}
char i;
input >> i;
cout << i;
myStack.push(i); // This is where things go wrong.
cin.get();
}
Thanks for any help!
It looks like you are not initializing used, you have something that may look like a constructor here but it is not:
void stack() {used=0;};
this is what it should look like:
Stack() { used=0;};
So without a constructor used is going to be some indeterminate value and will probably end up with you attempting to access data way out of bounds. Also main should always return int.
void stack() {used=0;};
should this be capitalised? & remove the void!
Stack myStack;
should this be
Stack myStack = new Stack();
if you don't initialise it, the variable myStack will be a "null pointer".
I think you wrote this function wrong:
void stack() {used=0;};
//^^extra ; here
should be
Stack() {used = 0;}
//^^Note that constructor has no return type
You have never really used the stack member function which return void. This results in the fact that used was never initialized. You probably mean the constructor of Stack. Meanwhile, you should use constructor initialization list:
Stack(): used(0) {}