سؤال

I need to create a program with Windows forms. I made a bit of code in c++...and Windows forms in c++/cli at the same time. Now I'm trying to adapt the c++ code from the forms, but I'm having some problems with the file, it's completely different from c++.

I have 2 forms. The first is for registration (it should register every student in a file). The second is for modifying students data with a given surname for example.

In registration.cpp I have created a list of objects but when I write I use streamwriter, but I guess there isnt any relationship with my list.

So my problems are:

How can I WRITE my data list into a file?

How can I MODIFY that data?

Now I post some code, but it's in italian :D as I am from italy (sorry for my mistakes.)

//.cpp of the registration

class studente
{
private:
      string cognome;
string nome;
public:
 studente(){
    cognome="";
    nome="";
    };
~studente(){};
void set(string str1,string str2){
                               cognome=str1;
                               nome=str2;
               }

class primo_anno:public studente
{
private:
 int voto_diploma;
public:
 primo_anno(){
       cognome="";
       nome="";
             voto_diploma='0';
    };
 ~primo_anno(){};
 void set(string str1,string str2, int mark){                                                voto_diploma=mark;                                };
 void stampa(){//I KNOW ITS NOT USEFUL HERE..BUT IN C++ I USED THAT
        f<<"\ncognome: "<<cognome<<"\n";
        f<<"nome:    "<<nome<<"\n";
        f<<"voto:    "<<voto_diploma<<"\n";
        };
};

list<primo_anno> l1;//DECLARE MY STL LIST

{//WHEN I CLICK ON MY REGISTER BUTTON THE PROGRAM RUN THIS
int mark;
primo_anno *s;
s=new primo_anno;

char* str1=(char*)(Marshal::StringToHGlobalAnsi(textBox1->Text)).ToPointer();
char* str2=(char*)(Marshal::StringToHGlobalAnsi(textBox2->Text)).ToPointer();
mark = Convert::ToInt16(textBox35->Text);

s->set(str1,str2,mark);
l1.push_back(*s);
list<primo_anno>::iterator it;

//I HAVE FOUND THIS METHOD BUT ITS NOT LINKED TO MY STL LIST.
//BY THE WAY I AM ABLE TO WRITE ON FILE WITH THIS.BUT LATER I DONT KNOW HOW TO MODIFY
//FOR EXAMPLE "DELETE THE LINE WHERE THERE IS Rossi SURNAME".HOW!!!
TextWriter ^tw = gcnew StreamWriter("primoAnno.txt", true);//true append
tw->WriteLine(textBox1->Text + "\t\t" + textBox2->Text + "\t\t" + textBox35->Text);
tw->Close();

Thank you in advance! And sorry again for my English... I'm just a student:)

هل كانت مفيدة؟

المحلول

Normally, you can convert a std::string into a System::String^ quite easily (it's even possible that simply using gcnew String(myPrimoAnnoObj.cognome) will give you a string with the right contents, easily written into the managed stream.

However you appear to have failed to grasp how new works for unmanaged objects: Your code allocates a primo_anno structure dynamically for no reason, before copying its value into the list and leaking the pointer. You also leak the pointers to the unmanaged strings you obtained from the Marshal class.

Are you sure you should be using unmanaged objects? It would be much easier to have everything in a managed System::Collections::Generic::List<> of managed objects...

Added: For writing everything in a file, you can try something like this:

ref class MyClass
{
public:
    String^ cognome;
    String^ nome;
    int voto_diploma;
};

//...

List<MyClass^>^ primo = gcnew List<MyClass^>();

//...

MyClass^ myObj = gcnew MyClass();
myObj->cognome = textBox1->Text;
myObj->nome = textBox2->Text;
myObj->voto_diploma = Convert::ToInt32(textBox35->Text);
primo->Add(myObj);

//...

TextWriter ^tw = gcnew StreamWriter(L"primoAnno.txt", true);
for each(MyClass^ obj in primo)
{
    //You can use any character or string as separator,
    //as long as it's not supposed to appear in the strings.
    //Here, I used pipes.
    tw->Write(obj->cognome);
    tw->Write(L"|");
    tw->Write(obj->nome);
    tw->Write(L"|");
    tw->WriteLine(obj->voto_diploma);
}
tw->Close();

For reading, you can use a function like this:

MyClass^ ParseMyClass(String^ line)
{
    array<String^>^ splitString = line->Split(L'|');
    MyClass^ myObj = gcnew MyClass();
    myObj->cognome = splitString[0];
    myObj->nome = splitString[1];
    myObj->voto_diploma = Convert::ToInt32(splitString[2]);
    return myObj;
}

And for deleting:

TextWriter^ tw = gcnew StreamWriter(L"primoAnno2.txt", true);
TextReader^ tr = gcnew StreamReader(L"primoAnno.txt");
String^ line;
while((line=tr->ReadLine()) != nullptr)
{
    MyClass^ obj = ParseMyClass(line);
    if(obj->cognome != L"cat")
        tw->WriteLine(line);
}
tr->Close();
tw->Close();
File::Delete(L"primoAnno.txt");
File::Move(L"primoAnno2.txt", L"primoAnno.txt");

It may not be the exact code, but it's overall what should work.

Note: If you want your separator to be spaces, and there can be spaces in the strings, things will get a lot more complicated.

نصائح أخرى

I have tried to use a generic list..(thanks MSDN).in the comments below there are my dubts..

List<String^>^ primo=gcnew List<String^>();
int mark;

char* str1=(char*)(Marshal::StringToHGlobalAnsi(textBox1->Text)).ToPointer();
char* str2=(char*)(Marshal::StringToHGlobalAnsi(textBox2->Text)).ToPointer();
mark = Convert::ToInt16(textBox35->Text);

//here i add TEXTBOXES to my generic list...not objects of my stl list
primo->Add(textBox1->Text);
primo->Add(textBox2->Text);
primo->Add(textBox35->Text);

TextWriter ^tw = gcnew StreamWriter("primoAnno.txt", true);
for each(String^ prim in primo){
//here i write my string one by one in column..i want them all in a line!how?
                               tw->WriteLine(prim);
                              }

//i also have tried to delete an object..but i dont like the remove..i mean i want all the strings in a line, if i find "cat" for example i want to delete the ENTIRE line..not just "cat"
if(primo->Contains("cat"))tw->WriteLine("ok");primo->Remove("cat");
for each(String^ prim in primo){
                               tw->WriteLine(prim);
                              }
tw->Close();

i make an example of my primoAnno.txt file first time i write(and push the register button) i want this:

cat gae 5

second time i write(and push the register button again) i want this:

cat gae 5

bla bla 1

then, when i remove(if there is "cat" in a line delete that line) i want this:

bla bla 1

hope it s useful. thanks to ones who will reply

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top