Laden von Dateien in Streams



  • Schon alleine der Titel sagt es aus:
    Ein Meister der Programmierkunst bin ich nicht.

    Ich versuche mich gerade daran, eine .txt - Datei in einen String zu laden und scheitere dabei. Bis jetzt habe ich die Datei öffnen können, aber das wars auch. Soweit ich weiss, muss man eine Datei zuerst in einen Stream laden, um sie dann Stück für Stück in den entsprechenden String zu übertragen (der ja auch ein Stream ist, afaik)
    Ich poste mal den Code (bestimmte Variablen wurden bereits global vorgegeben, das ist aber nicht das Problem.)
    Es ist für den Borland C++ geschrieben, es wäre aber nett wenn es auch eine Verallgemeinerung gäbe, die mich von diesem Compiler etwas unabhängig macht.

    int pos,check[8];
    long length;
    char *buffer;
    Form1->OpenDialog1->Execute();
    Folder=OpenDialog1->FileName;
    pos=Folder.LastDelimiter("\");
    Folder=Folder.SubString(0,pos);

    for (int a1=0;a1<9;a1++)
    {
    check[a1]=FileOpen(Folder + Filenames[a1],0);
    }
    Memo1->Text= Folder;

    //begin for1
    for (int a2=0;a2<9;a2++)
    {
    if (check[a2]==-1)
    {
    Memo1->Lines->Add("Error on " + Filenames[a2]);
    Textfiles[a2]="na";
    }
    else
    {
    Textfiles[a2]=IntToStr(check[a2]);
    }
    }
    //end of for1

    for (int a=0;a<9;a++)
    {
    Memo1->Lines->Add(Textfiles[a]);
    }
    length=filelength(check[0]);
    Textfiles[0]=Textfiles[0].LoadStr(check[0]);
    Textfiles[0]=(Textfiles[0] + buffer);
    Memo1->Lines->Add(IntToStr(length) + Textfiles[0]);
    }



  • int pos,check[8];
    long length;
    char *buffer;
    Form1->OpenDialog1->Execute();
    Folder=OpenDialog1->FileName;
    pos=Folder.LastDelimiter("\");
    Folder=Folder.SubString(0,pos);
    
    for (int a1=0;a1<9;a1++)
    {
    check[a1]=FileOpen(Folder + Filenames[a1],0);
    }
    Memo1->Text= Folder;
    
    //begin for1
    for (int a2=0;a2<9;a2++)
    {
    if (check[a2]==-1)
    {
    Memo1->Lines->Add("Error on " + Filenames[a2]);
    Textfiles[a2]="na";
    }
    else
    {
    Textfiles[a2]=IntToStr(check[a2]);
    }
    }
    //end of for1
    
    for (int a=0;a<9;a++)
    {
    Memo1->Lines->Add(Textfiles[a]);
    }
    length=filelength(check[0]);
    Textfiles[0]=Textfiles[0].LoadStr(check[0]);
    Textfiles[0]=(Textfiles[0] + buffer);
    Memo1->Lines->Add(IntToStr(length) + Textfiles[0]);
    }
    

    als zitat unschön zu lesen



  • Phat Looser schrieb:

    Es ist für den Borland C++ geschrieben, es wäre aber nett wenn es auch eine Verallgemeinerung gäbe, die mich von diesem Compiler etwas unabhängig macht.

    da wirst du dann mit deinem code garnicht weit kommen!

    wenn du unabhängig von der ide arbeiten willst, dann mit standard c++!
    hier werden buttons, memos, dialoge benutzt die nicht standard c++ sind, sondern direkt von deiner ide kommen!



  • Memo1->Lines->LoadFromFile("xxxx.txt");



  • Hallo,

    pos=Folder.LastDelimiter("\");
    Folder=Folder.SubString(0,pos);
    

    ist falsch. Ein \ muß maskiert werden und die Indizes bei AnsiString beginnen bei 1

    pos=Folder.LastDelimiter("\\");
    Folder=Folder.SubString(1,pos);
    

    Dann liegen im ersten Quelltext einige Missverständnisse.
    Wo wird buffer initialisiert?
    FileOpen liefert ein Handle auf die geöffnete Datei zurück und nicht die Länge.
    AnsiString::LoadStr liest eine String aus einer StringRessource und nicht aus einer TextDatei. Hierfür wäre hier FileRead zuständig.
    usw.

    Wie Christian aber schon bemerkte ist hier LoadFromFile sicher die einfachste variant.
    Wenn du BCB-unabhängiger programmieren möchtest, beschäftige dich mal mit iostreams. Dazu gibt es unter anderem ind der FAQ des C++-Forums eine Anleitung.



  • Braunstein schrieb:

    Hallo,

    pos=Folder.LastDelimiter("\");
    Folder=Folder.SubString(0,pos);
    

    ist falsch. Ein \ muß maskiert werden und die Indizes bei AnsiString beginnen bei 1

    pos=Folder.LastDelimiter("\\");
    Folder=Folder.SubString(1,pos);
    

    Dann liegen im ersten Quelltext einige Missverständnisse.
    Wo wird buffer initialisiert?
    FileOpen liefert ein Handle auf die geöffnete Datei zurück und nicht die Länge.
    AnsiString::LoadStr liest eine String aus einer StringRessource und nicht aus einer TextDatei. Hierfür wäre hier FileRead zuständig.
    usw.

    Wie Christian aber schon bemerkte ist hier LoadFromFile sicher die einfachste variant.
    Wenn du BCB-unabhängiger programmieren möchtest, beschäftige dich mal mit iostreams. Dazu gibt es unter anderem ind der FAQ des C++-Forums eine Anleitung.

    Das \\ steht richtig im Quelltext. Ich hab keinen Schimmer warum es hier nicht drinnensteht.
    Auch wenn bei mir eine 0 und keine 1 steht, funktioniert es. Irritierend, aber wahr. Ich probier die "1". (Versuch: Es macht keinen Unterschied. Augenscheinlich korrigiert das der Compiler bei der ersten Stelle.)
    Buffer wird bis jetzt nirgendwo initalisiert. Das mit dem "Char* buffer" war nur der 9. Fehlgegangene Versuch. Ich guck mir das Tut an, versprochen. Trotzdem möchte ich selber auf die Nase fallen, das hilft mehr als jedes Tut. Besonders wenn man sich dann einen funktionierenden Quelltext anschaut und seine eigenen Fehler erkennt.
    Fileopen schreibt in "check[x]", die lenth-Variable wird hier nur ausprobiert (filelength(check[0])); ich bin von 8 bis 0 durchgelaufen.
    Danke für die Hilfe.

    P.S.:

    Memo1->Lines->LoadFromFile("xxxx.txt")

    Hehe, DAS wollte ich vermeiden.



  • Zitat:
    Memo1->Lines->LoadFromFile("xxxx.txt")

    Hehe, DAS wollte ich vermeiden.

    Warum einfach, wenn es auch kompliziert geht 👍



  • In meiner Hilfe zu FileRead (BCB5) steht ein recht ausfühliches Beispiel. Schau doch da einfach mal rein.



  • Braunstein schrieb:

    In meiner Hilfe zu FileRead (BCB5) steht ein recht ausfühliches Beispiel. Schau doch da einfach mal rein.

    Werde ich brauchen.
    Aus welchen-Gründen-auch-immer komme ich mit den FileHandles nicht zurecht. Ich bekomme eins, aber wenn ich es verwende kommt immer "-1" heraus.



  • Hast du das Beispiel denn nicht?
    Ich poste es jetzt mal hier.

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      int iFileHandle;
      int iFileLength;
      int iBytesRead;
      char *pszBuffer;
      if (OpenDialog1->Execute())
      {
        try
        {
          iFileHandle = FileOpen(OpenDialog1->FileName, fmOpenRead);
          iFileLength = FileSeek(iFileHandle,0,2);
          FileSeek(iFileHandle,0,0);
          pszBuffer = new char[iFileLength+1];
          iBytesRead = FileRead(iFileHandle, pszBuffer, iFileLength);
          FileClose(iFileHandle);
    
          for (int i=0;i<iBytesRead;i++)
          {
            StringGrid1->RowCount += 1;
            StringGrid1->Cells[1][i+1] = pszBuffer[i];
            StringGrid1->Cells[2][i+1] = IntToStr((int)pszBuffer[i]);
          }
          delete [] pszBuffer;
        }
        catch(...)
        {
          Application->MessageBox("Can't perform one of the following file operations: Open, Seek, Read, Close.", "File Error", IDOK);
        }
      }
    }
    

    Ich selbst verwende diese Funktionen normalerweise nicht, sondern statt dessen Standard-streams oder TFileStream.


Anmelden zum Antworten