Hi,
I have in class private char* region. I need create constructor which takes as argument data of type char* and on the basis of that data constructor determines region of some object. Data which is argument looks like this:(for example:"Lombardia Milano").So region is, in this case, Lombardia and city is Milano. How to do that?
what exactly do you want to do? It isnt clear.
you can copy the argument's data to your private variable. to do that, you need something like
int l = strlen(input);
private_var = new char[l+1];
strcpy(private_var, input);
and your destructor needs to release the memory.
is that ^^^ what you want to know?
do not just copy the pointers:
private_var = input; //this will work, but its very risky. any changes to input in the calling program will break the class variable too, and it takes away the private-ness of the variable. This idea can be useful in high performance code where you accept the risks and manage them, but in general, this idea is poor.
ideally you would use string and just say
private_var = input; //ok, not pointers, copying is correct and safe and simple.
#include <iostream>
#include <sstream>
#include <string>
class Place {
std::string region, city;
public:
Place(std::string s) {
std::istringstream iss(s);
iss >> region >> city;
}
void print() const {
std::cout << region << ", " << city << '\n';
}
};
int main() {
Place place(" Lombardia Milano ");
place.print();
}
Yes, dutch. I need to split that, but I don't think I have to use this method (with std::string).
My assignment is next.
Write class GeoMap with following private attributes:
region(char*)
city(char*)
surface(double)
population (int)
timezone(int)
hours (int)
minutes (int)
mark(char*)
Write constructor that takes as argument one char array (data of type char*) and on the basis of it sets values of attributes. For example:"Lombardia Milano 181.76 1360422 +5".
I tried to use strtok, but it doesn't work. Am I maybe clearer now?
You’d better take good note of what jonnin told you:
jonnin wrote:
to do that, you need something like
int l = strlen(input);
private_var = new char[l+1];
strcpy(private_var, input);
and your destructor needs to release the memory.
Once you have got your ‘private_var’ pointer (which points to a memory area you own), you can use std::strtok on it.
However, we can help you with your code if you post it. Otherwise, it’s a guessing game.
It does not work. Resaons and advices what to fix?
Reasons
---------
The compiler is already explaining the problem. Just read:
main.cpp:34:13: error: ISO C++ forbids converting a string constant to 'char*' [-Werror=write-strings]
34 | GMapa g("Lombardija Milano 181.76 1360422 +5");
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A “string constant”, also known as a string literal is stored in a read-only memory area. You cannot assign it to a char* (in standard C++).
This program raises a warning:
1 2 3 4
int main()
{
char * str = "Lombardija Milano 181.76 1360422 +5";
}
This program compiles fine:
1 2 3 4
int main()
{
constchar * str = "Lombardija Milano 181.76 1360422 +5";
}
Anyway, even assuming you changed your (badly indented and plenty of issues) code from
GMapa(char* c)
to
GMapa(constchar* c)
you would anyway face another error:
main.cpp: In constructor 'GMapa::GMapa(const char*)':
main.cpp:19:15: error: invalid conversion from 'const char*' to 'char*' [-fpermissive]
19 | regija=strtok(c,f);
| ^
| |
| const char*
In file included from main.cpp:2:
/usr/include/string.h:343:39: note: initializing argument 1 of 'char* strtok(char*, const char*)'
343 | extern char *strtok (char *__restrict __s, const char *__restrict __delim)
| ~~~~~~~~~~~~~~~~~^~~
Advice
-------
You can easily solve this last problem simply by reading what you have already being told.
(Later we can deal with the following one.)
#include <cstdlib>
#include <cstring>
#include <iostream>
class GMapa {
public:
explicit GMapa(constchar * const s);
~GMapa();
void ispis();
private:
char * regija { nullptr };
char * grad { nullptr };
double povrsina {};
int brojStanovnika {};
char *zona { nullptr };
int sati {};
int minuti {};
char * oznaka { nullptr };
};
GMapa::GMapa(constchar * const s)
{
constauto len { std::strlen(s) + 1 };
auto * s_new { newchar[len] };
std::strcpy(s_new, s);
regija = std::strtok(s_new, " ");
grad = std::strtok(nullptr, " ");
povrsina = std::atof( std::strtok(nullptr, " ") );
// This is wrong and causes the compilation to fail:
// brojStanovnika = int( std::strtok(nullptr, " ") );
zona = std::strtok(nullptr, " ");
// sati?
// minuti?
// oznaka?
}
GMapa::~GMapa()
{
// clean up the memory here
}
void GMapa::ispis()
{
std::cout << regija << '\n'
<< grad << '\n'
<< povrsina << '\n'
<< brojStanovnika << '\n'
<< zona << '\n';
}
int main()
{
GMapa g("Lombardija Milano 181.76 1360422 +5");
g.ispis();
return 0;
}
Output:
Lombardija
Milano
181.76
0
1360422
Can you explain why?
I can try, but what parts of the previous three explanations are not clear?
Or better: how many words may I use before you stop reading?
std::strtok modifies the passed (C-style) string.
Therefore it’s first argument can be neither const nor stored in a read only memory area.
You need to pass a pointer to a memory area you own, for example one you obtain from “new”.