|
Hi
I'm getting problem running the sw I attach here below. I am trying to make an array of a certain class.
In the header I have the class then a .cpp with public methods. In the main I'm doing this:
<pre>#include "Anagrafica.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void cod (anagrafica arr,string n, string c,int chiave)
{ arr.codifica(n,c,chiave); }
void decod (anagrafica arr)
{ arr.decodifica(); }
int main()
{
ifstream file;
file.open("input.txt");
int N;
string n,c;
int chiave;
int chiave_input;
file>>N;
cout<<N<<endl;
anagrafica* Arr_ = new anagrafica[N];
for (int i = 0; i < N; i++)
{
Arr_[i] = anagrafica("ciao", "miao", i*25);
}
for (int i=0; i<N; i++)
{
file>>chiave;
file>>n;
file>>c;
}
for (int i=0; i<N; i++)
cout<<"inserire un valore intero"<<endl;
cin>>chiave_input;
}
here is header
<pre>#include<iostream>
#include<string>
using namespace std;
class anagrafica
{
private:
string nome_cifrato;
string cognome_cifrato;
int chiave_cifratura;
public :
anagrafica(string ="", string ="", int=0);
void setNome(string );
void setCognome(string );
string getNome();
string getCognome();
void codifica(string , string , int );
void decodifica();
void setChiave(int);
int getChiave();
void stampa();
};
I do not attach the public method here because problem is before using methods.
Problem occurs when I create instance of array of class anagrafica. At the end that is not an array. Program does not raise any exception in the for with i from 1 to N. As if array was of dimension N. But it isn't.
I tried also with the double pointer like this
<pre>anagrafica** Arr_ = new anagrafica*[N];
for (int i = 0; i < N; i++)
{
Arr_[i] = new anagrafica("ciao", "miao", i*25);
}
but Arr_ is of only 1 element,
the first no other
|
|
|
|
|
Roberto64_Ge wrote: but Arr_ is of only 1 element,
the first no other
How did you verify that? If you just looked in VisualStudio debugger, it will indeed show only one element because it doesn't know the size of the array. You can enter a length specifier in the inspector window (like Arr_,10) to make it show 10 elements.
Alternatively you can just say:
anagrafica *Arr_[10];
for (int i = 0; i < N; i++)
{
Arr_[i] = new anagrafica("ciao", "miao", i*25);
}
In this case the debugger will know the size of the array and show all elements.
Otherwise your code looks good as far as array creation goes.
Mircea
|
|
|
|
|
Problem is that I tried also with a costant as in your example but I could only see the first element.
In the snippet I posted some parts of the code is commented.
But when I remove comments app is working but the behaviour is that as if array was of 1 only element.
I will read further replies tomorrow, thank you.
|
|
|
|
|
The array variable needs to point to an array of pointers, so the syntax needs to be:
anagrafica** Arr_ = new anagrafica*[N];
for (int i = 0; i < N; i++)
{
Arr_[i] = new anagrafica("ciao", "miao", i*25);
}
Remember that Arr_ is a pointer to the actual array so it will appear to contain only one element. But you can check the contents with another simple loop.
You could make life much simpler for yourself by using one of the STL containers, such as vector<T> .
|
|
|
|
|
ok, i better checked, so thank you. Now, how is the syntax to access the method of any instance (of the class) pointed by the i element af Arr_. I don't find the way to do that. I mean that I need to do something like
Example : Arr_[i].setChiave(3)
By the way, may I call a method , example setNome(stringaNome) from within another method?
modified 8-Sep-22 10:22am.
|
|
|
|
|
Arr_[i]-> setChiave(3)
EDIT: And sure, one method can call another, subject to access controls (public, protected, private).
|
|
|
|
|
OK thanks.
By the way, may I call a method , example setNome(stringaNome) from within another method? I attach here three methods of the class, the greater calling the two small.
void anagrafica::setNome(string n_)
{
nome_cifrato=n_;
}
void anagrafica::setCognome(string c_)
{
cognome_cifrato=c_;
}
void anagrafica::codifica(string nome_chiaro, string cognome_chiaro, int chiave)
{
char car;
nome_cifrato = "";
cognome_cifrato = "";
for (int i=0;i <nome_chiaro.length();i++)
{
car = nome_chiaro[i] + chiave;
nome_cifrato = nome_cifrato + car;
cout<<"carattere "<<i<<" n in chiaro "<<nome_chiaro[i]<<" chiave "<<chiave<<" cifrato "<<car<<" nome incostruzione "<<nome_cifrato<<endl;
}
setNome(nome_cifrato);
for (int i=0; i<cognome_chiaro.length();i++)
{
car = cognome_chiaro[i] + chiave;
cognome_cifrato = cognome_cifrato + car;
cout<<"carattere "<<i<<" c in chiaro "<<cognome_chiaro[i]<<" chiave "<<chiave<<" cifrato "<<car<<" cognome incostruzione "<<cognome_cifrato<<endl;
}
setCognome(cognome_cifrato);
}
The two lines of code hghlighted have no effects.
|
|
|
|
|
Those lines have no effect because the default in C++ is to pass an argument by value. That is, to make a copy of it. If you want to modify the data that is passed to the function, it must be passed by reference; another option is to pass a pointer to the argument. To pass by reference, you append a & to the argument's type. So, you need to change your two small functions like this:
void anagrafica::setNome(string& n_)
{
nome_cifrato=n_;
}
void anagrafica::setCognome(string& c_)
{
cognome_cifrato=c_;
}
modified 8-Sep-22 13:10pm.
|
|
|
|
|
That will not make any difference. I have just tested the code and those methods both do what they are supposed to. The issue is more complex due to the confused (and confusing) nature of this code.
|
|
|
|
|
Roberto64_Ge wrote: Example : Arr_[i].setChiave(3) Yes, as a simple test would show you.
Roberto64_Ge wrote: may I call a method , example setNome(stringaNome) from within another method? Yes again. All methods* within a class may be called from other methods, whether they are private or public. *But you cannot call non-static from static methods, as the non-statics need an object reference.
|
|
|
|
|
if I use double pointer compiler don't let me use that syntax.
|
|
|
|
|
What do you mean by, "double pointer"? If something does not work then please show the actual code and the error message(s).
|
|
|
|
|
i do not know how to quote a previous answer. Anyway you suggested me to use a pointer to an array of pointers so we did
anagrafica **Arr_ = new anagrafica*[N];
But in this case compiler didn't let me access the method in this way :
Arr_[i].setChiave(3);
For that reason I asked for the correct syntax. Meanwhile I was waiting your reply I decided to try and so I went back to the first version temporarily and this is working, with respect to my first question " why I cannot see all the array elements?".
With this I mean that, also with my first version, if I access Arr_[i] during the debug (within the relevant window "Control expression". I guess this is the correct translation from Italian) I see all the different instances of the class in each element of the array Arr_. I attach here the code of the first version.
With this version running then I get a new malfunction that is that when I call the method for cifrating the true name and surname, from within this method I call the two methods to set the name and the surname, setNome and setCognome but this has no effects. If preferred I will attach the complete solution.
<pre>anagrafica* Arr_ = new anagrafica[N];
for (int i = 0; i < N; i++)
{
Arr_[i] = anagrafica("ciao", "miao", i*25);
}
for (int i=0; i<N; i++)
{
file>>chiave;
file>>n;
file>>c;
Arr_[i].setChiave(chiave);
cod(Arr_[i],n,c,chiave);
}
for (int i=0; i<N; i++)
Arr_[i].stampa();
|
|
|
|
|
Arr_[i].setChiave(3);
Sorry, I misread that. Arr_[i] is a pointer so you need to use the correct pointer dereferencing syntax:
Arr_[i]->setChiave(3);
|
|
|
|
|
Ok i realized that. thank you very much. What about the other problem? Methods ....
|
|
|
|
|
I have commented out all the parts of your code that are not needed to create a simple test. The result is as follows:
#include<iostream>
#include<string>
using namespace std;
class anagrafica
{
private:
string nome_cifrato;
string cognome_cifrato;
int chiave_cifratura;
public :
anagrafica(string a, string b, int c);
void setChiave(int);
void print();
};
#include "Anagrafica.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
anagrafica::anagrafica(string a, string b, int c) {
nome_cifrato = a;
cognome_cifrato = b;
chiave_cifratura = c;
}
void anagrafica::setChiave(int a)
{
chiave_cifratura = a;
}
void anagrafica::print()
{
cout << nome_cifrato << " " << cognome_cifrato << " " << chiave_cifratura << endl;
}
int main()
{
int N = 4;
anagrafica** Arr_ = new anagrafica*[N];
for (int i = 0; i < N; i++)
{
Arr_[i] = new anagrafica("ciao", "miao", i*25);
}
for (int i = 0; i < N; i++)
{
Arr_[i]->print();
}
}
|
|
|
|
|
Ok , so the syntax is not
Arr_[i].setChiave(3)
but
Arr_[i]->setChiave(3)
as per Greg Utas and your new indication.
As I wrote I would say that also the version
<pre>anagrafica* Arr_ = new anagrafica[N];
for (int i = 0; i < N; i++)
{
Arr_[i] = anagrafica("ciao", "miao", i*25);
}
is working the same. Then I have the further problem of the two methods for setting cifrated name and surname tha have no effects.
I see that there is some problem of synchronizations with the replies. But ok syntax has been clarified.
|
|
|
|
|
You have declared a number of methods in your header file but you have not added their implementation to the .cpp source. In my sample code above you can see the implementation for the setChiave method. You need to do the same for all the other methods declared in the class.
|
|
|
|
|
I attach the method file .cpp
#include "Anagrafica.h"
#include <iostream>
#include <string>
using namespace std;
anagrafica::anagrafica(string name,string surname, int key)
{
nome_cifrato=name;
cognome_cifrato=surname;
chiave_cifratura=key;
}
void anagrafica::setNome(string n_)
{
nome_cifrato=n_;
}
void anagrafica::setCognome(string c_)
{
cognome_cifrato=c_;
}
string anagrafica::getNome()
{
return nome_cifrato;
}
string anagrafica::getCognome()
{
return cognome_cifrato;
}
int anagrafica::getChiave()
{
return chiave_cifratura;
}
void anagrafica::setChiave(int c)
{
chiave_cifratura=c;
}
void anagrafica::stampa()
{
string nom = nome_cifrato;
string cog = cognome_cifrato;
cout<<" nome cifrato "<<nom;
cout<<" cognome cifrato "<<cog<<endl;
}
void anagrafica::codifica(string nome_chiaro, string cognome_chiaro, int chiave)
{
char car;
nome_cifrato = "";
cognome_cifrato = "";
for (int i=0;i <nome_chiaro.length();i++)
{
car = nome_chiaro[i] + chiave;
nome_cifrato = nome_cifrato + car;
cout<<"carattere "<<i<<" n in chiaro "<<nome_chiaro[i]<<" chiave "<<chiave<<" cifrato "<<car<<" nome incostruzione "<<nome_cifrato<<endl;
}
setNome(nome_cifrato);
for (int i=0; i<cognome_chiaro.length();i++)
{
car = cognome_chiaro[i] + chiave;
cognome_cifrato = cognome_cifrato + car;
cout<<"carattere "<<i<<" c in chiaro "<<cognome_chiaro[i]<<" chiave "<<chiave<<" cifrato "<<car<<" cognome incostruzione "<<cognome_cifrato<<endl;
}
setCognome(cognome_cifrato);
}
void anagrafica::decodifica()
{
char car;
string nome_chiaro = "";
string cognome_chiaro = "";
for (int i=0;i <nome_cifrato.length();i++)
{
car = nome_cifrato[i] - chiave_cifratura;
nome_chiaro = nome_chiaro + car;
cout<<"carattere "<<i<<" n in cifrato "<<nome_cifrato[i]<<" chiave "<<chiave_cifratura<<" chiaro "<<car<<" nome incostruzione "<<nome_chiaro<<endl;
}
cout<<" nome in chiaro "<<nome_chiaro;
for (int i=0; i<cognome_cifrato.length();i++)
{
car = cognome_cifrato[i] - chiave_cifratura;
cognome_chiaro = cognome_chiaro + car;
cout<<"carattere "<<i<<" c in cifrato "<<cognome_cifrato[i]<<" chiave "<<chiave_cifratura<<" chiaro "<<car<<" cognome incostruzione "<<cognome_chiaro<<endl;
}
cout<<" cognome in chiaro "<<cognome_chiaro<<endl;
}
I can't understand where is the error.
|
|
|
|
|
Clarified the syntax problem I resume here.
The code works also in this way ::
anagrafica* Arr_ = new anagrafica[N];
for (int i = 0; i < N; i++)
{
Arr_[i] = anagrafica("ciao", "miao", i*25);
}
for (int i=0; i<N; i++)
{
file>>chiave;
file>>n;
file>>c;
Arr_[i].setChiave(chiave);
cod(Arr_[i],n,c,chiave);
}
for (int i=0; i<N; i++)
Arr_[i].stampa();
Because I can see all the Arr_ elements containing instances of the class. But two methods recalled from one other method do not heve effects.
|
|
|
|
|
I think this thread is getting confused (I certainly am). I suggest you start a new thread and post the actual code that you are now using, and explain what methods do not work.
|
|
|
|
|
header
#include<iostream>
#include<string>
using namespace std;
class anagrafica
{
private:
string nome_cifrato;
string cognome_cifrato;
int chiave_cifratura;
public :
anagrafica(string ="", string ="", int=0);
void setNome(string );
void setCognome(string );
string getNome();
string getCognome();
void codifica(string , string , int );
void decodifica();
void setChiave(int);
int getChiave();
void stampa();
};
methods
#include "Anagrafica.h"
#include <iostream>
#include <string>
using namespace std;
anagrafica::anagrafica(string name,string surname, int key)
{
nome_cifrato=name;
cognome_cifrato=surname;
chiave_cifratura=key;
}
void anagrafica::setNome(string n_)
{
nome_cifrato=n_;
}
void anagrafica::setCognome(string c_)
{
cognome_cifrato=c_;
}
string anagrafica::getNome()
{
return nome_cifrato;
}
string anagrafica::getCognome()
{
return cognome_cifrato;
}
int anagrafica::getChiave()
{
return chiave_cifratura;
}
void anagrafica::setChiave(int c)
{
chiave_cifratura=c;
}
void anagrafica::stampa()
{
string nom = nome_cifrato;
string cog = cognome_cifrato;
cout<<" nome cifrato "<<nom;
cout<<" cognome cifrato "<<cog<<endl;
}
void anagrafica::codifica(string nome_chiaro, string cognome_chiaro, int chiave)
{
char car;
nome_cifrato = "";
cognome_cifrato = "";
for (int i=0;i <nome_chiaro.length();i++)
{
car = nome_chiaro[i] + chiave;
nome_cifrato = nome_cifrato + car;
cout<<"carattere "<<i<<" n in chiaro "<<nome_chiaro[i]<<" chiave "<<chiave<<" cifrato "<<car<<" nome incostruzione "<<nome_cifrato<<endl;
}
setNome(nome_cifrato);
for (int i=0; i<cognome_chiaro.length();i++)
{
car = cognome_chiaro[i] + chiave;
cognome_cifrato = cognome_cifrato + car;
cout<<"carattere "<<i<<" c in chiaro "<<cognome_chiaro[i]<<" chiave "<<chiave<<" cifrato "<<car<<" cognome incostruzione "<<cognome_cifrato<<endl;
}
setCognome(cognome_cifrato);
}
void anagrafica::decodifica()
{
char car;
string nome_chiaro = "";
string cognome_chiaro = "";
for (int i=0;i <nome_cifrato.length();i++)
{
car = nome_cifrato[i] - chiave_cifratura;
nome_chiaro = nome_chiaro + car;
cout<<"carattere "<<i<<" n in cifrato "<<nome_cifrato[i]<<" chiave "<<chiave_cifratura<<" chiaro "<<car<<" nome incostruzione "<<nome_chiaro<<endl;
}
cout<<" nome in chiaro "<<nome_chiaro;
for (int i=0; i<cognome_cifrato.length();i++)
{
car = cognome_cifrato[i] - chiave_cifratura;
cognome_chiaro = cognome_chiaro + car;
cout<<"carattere "<<i<<" c in cifrato "<<cognome_cifrato[i]<<" chiave "<<chiave_cifratura<<" chiaro "<<car<<" cognome incostruzione "<<cognome_chiaro<<endl;
}
cout<<" cognome in chiaro "<<cognome_chiaro<<endl;
}
main
#include "Anagrafica.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void cod (anagrafica arr,string n, string c,int chiave)
{
arr.codifica(n,c,chiave);
}
void decod (anagrafica arr)
{
arr.decodifica();
}
int main()
{
ifstream file; file.open("input.txt");
int N;
string n,c;
int chiave;
int chiave_input;
file>>N; cout<<N<<endl;
anagrafica* Arr_ = new anagrafica[N];
for (int i = 0; i < N; i++)
{
Arr_[i] = anagrafica("ciao", "miao", i*25);
}
for (int i=0; i<N; i++)
{
file>>chiave;
file>>n;
file>>c;
Arr_[i].setChiave(chiave);
cod(Arr_[i],n,c,chiave);
}
for (int i=0; i<N; i++)
Arr_[i].stampa();
cout<<"inserire un valore intero"<<endl;
cin>>chiave_input;
for (int i=0; i<N; i++)
{
cout<<" chiave "<< Arr_[i].getChiave()<<endl;
if(chiave_input== Arr_[i].getChiave())
decod(Arr_[i]);
}
}
That's it.
Highlighted, within method "codifica", the call to the two methods setNome and setCognome that do not work (they do not set any name and surname). The two cout inside "codifica" are only to understand what happens.
The txt file from where to take the data to process is made like this
2 (means how many rows follows)
key1 name1 surname1
key2 name2 surname2
|
|
|
|
|
You need to execute that code through the debugger to see exactly what is happening. I tried to reproduce it and it was passing blank parameters in to the method. I suspect that the problem is where you are reading values from the input file.
[edit]
That method is modifying both variables nome_cifrato and cognome_cifrato inline, and you then call setNome and setCognome . But you have already modified the names so you do not need to call the setter methods. I think you need to look more closely at the design of this application and remove some of the redundancies.
modified 9-Sep-22 6:00am.
|
|
|
|
|
Ok you are right saying that
Richard MacCutchan wrote: That method is modifying both variables nome_cifrato and cognome_cifrato inline, and you then call setNome and setCognome. But you have already modified the names so you do not need to call the setter methods.
I didn't see it, I get confused writing the code, probably I inteded to use local variables to build cifrated name and surname.
But problem was in this function within the main
void cod (anagrafica arr,string n, string c,int chiave)
{
arr.codifica(n,c,chiave);
}
that i re-arranged this way
void cod (anagrafica &arr,string n, string c,int chiave)
{
arr.codifica(n,c,chiave);
}
passing the address to "cod". And about this, I understood the reason (Greg Utas was right about the rules but didn't apply to the real problem because i did not need to change the strings passed to the methods but the instance of the class itself). But now there is another behaviour that confuses me :
In a previous version the following method :
void anagrafica::stampa()
{
cout<<" nome cifrato "<<nome_cifrato;
cout<<" cognome cifrato "<<cognome_cifrato<<endl;
}
I had to modify in this new version :
void anagrafica::stampa()
{
string nom = nome_cifrato;
string cog = cognome_cifrato;
cout<<" nome cifrato "<<nom;
cout<<" cognome cifrato "<<cog<<endl;
}
because in the first version it was just printing nothing. Now it prints correctly. I just tried without a real knowledge behind, only some kind of sensation but I don't understand why it didn't work before and why it works now.
Anyway thanks for all the efforts/suggestions. I am just starting with c++ in order to help my children in their school exercise.
modified 10-Sep-22 3:10am.
|
|
|
|
|
Roberto64_Ge wrote: I am just starting with c++ in order to help my children in their school exercise. Well, I am sorry to have to say this, but what you have created is not a good example of C++ code for them to follow. The two static methods cod and decod serve no purpose other than to call the actual methods of the anagrafica class. So they are totally redundant; you could call the codifica method direct from main . There are a number of other issues that look incorrect to me but I do not have time to teach you C++.
|
|
|
|
|