1

我需要用 Windows 窗体创建一个程序。我在 c++ 中编写了一些代码……同时在 c++/cli 中编写了 Windows 表单。现在我正在尝试从表单中调整 c++ 代码,但是我在文件中遇到了一些问题,它与 c++ 完全不同。

我有 2 个表格。第一个是注册(它应该在一个文件中注册每个学生)。第二个是用于修改具有给定姓氏的学生数据。

在registration.cpp中,我创建了一个对象列表,但是当我写的时候我使用了streamwriter,但我想这与我的列表没有任何关系。

所以我的问题是:

如何将我的数据列表写入文件?

我怎样才能修改这些数据?

现在我发布了一些代码,但它是意大利语:D,因为我来自意大利(对不起我的错误。)

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

先感谢您!再次为我的英语感到抱歉……我只是个学生:)

4

2 回答 2

1

通常,您可以很容易地将 std::string 转换为 System::String^ (甚至有可能简单地使用gcnew String(myPrimoAnnoObj.cognome)将为您提供具有正确内容的字符串,轻松写入托管流。

但是,您似乎未能掌握new非托管对象的工作原理:您的代码primo_anno无缘无故地动态分配结构,然后将其值复制到列表中并泄漏指针。您还泄漏了指向从 Marshal 类获得的非托管字符串的指针。

你确定你应该使用非托管对象吗?将所有内容都放在托管对象的托管中会容易得多System::Collections::Generic::List<>......

补充:要将所有内容写入文件,您可以尝试以下操作:

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

对于阅读,您可以使用如下函数:

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;
}

对于删除:

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

它可能不是确切的代码,但它是应该工作的整体。

注意:如果你希望你的分隔符是空格,并且字符串中可以有空格,事情会变得更加复杂。

于 2013-07-01T12:04:14.493 回答
0

我尝试使用通用列表..(感谢 MSDN)。在下面的评论中有我的配音..

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

我第一次写(并按下注册按钮)时,我以我的 primoAnno.txt 文件为例,我想要这个:

猫 gae 5

我第二次写(并再次按下注册按钮)我想要这个:

猫 gae 5

呜呜呜 1

然后,当我删除时(如果一行中有“猫”,则删除该行)我想要这个:

呜呜呜 1

希望它有用。感谢那些会回复的人

于 2013-07-01T15:40:57.953 回答