Błąd podczas ładowania nagłówka

0

Witam,
ostatnio miałem troszeczkę czasu na dokończenie swojego VFS'a i natrafiłem na błąd podczas ładowania nagłówka. Błąd pojawia się przy oddzielenie nagłówka głównego od nagłówka pliku zawartego.
Najlepiej przedstawi to kod.

bool CFileSystem::LoadFile(std::string strFileName)
{
    std::ifstream inFile;
    std::string strTemp;
    char ch;
    inFile.open(strFileName, std::ios_base::out | std::ios_base::app);
    if (inFile.good())
    {
        inFile.seekg(0, std::ios_base::beg);
        ///////////////////////////////////////////początek głównego pliku -- główny nagłówek
        inFile.get(ch);//b
        strTemp += ch;
        inFile.get(ch);//e
        strTemp += ch;
        inFile.get(ch);//g
        strTemp += ch;
        //////////////////////////////////////////////
        if (strTemp != "beg")
        {
            std::cout << "Blad beg\n";
            inFile.close();
            return false;
        }
        strTemp.clear();
        while (1)//nazwa
        {
            inFile.get(ch);
            if (ch != '+')
                strTemp += ch;
            else
                break;
        }

        m_MyFileInfo.m_sHead.m_strFileName = strTemp;
        std::cout << "Nazwa: " << m_MyFileInfo.m_sHead.m_strFileName << std::endl;

        strTemp.clear();
        while (1)//rozszerzenie
        {
            inFile.get(ch);
            if (ch != '+')
                strTemp += ch;
            else
                break;
        }
        m_MyFileInfo.m_sHead.m_pchFileExtension = (char*)strTemp.c_str();
        std::cout << "Rozszerzenie: " << m_MyFileInfo.m_sHead.m_pchFileExtension << std::endl;

        strTemp.clear();
        while (1)//rozmiar
        {
            inFile.get(ch);
            if (ch != '+')
                strTemp += ch;
            else
                break;
        }
        m_MyFileInfo.m_ulSize = strToInt(strTemp);
        std::cout<< "Rozmiar: " << m_MyFileInfo.m_ulSize << std::endl;

        strTemp.clear();
        while (1)//ilosc plikow
        {
            inFile.get(ch);
            if (ch != '+')
                strTemp += ch;
            else
                break;
        }
        m_MyFileInfo.m_sHead.m_usFileCount = strToInt(strTemp);
        std::cout<< "Ilosc plikow: " << m_MyFileInfo.m_sHead.m_usFileCount << std::endl;

        strTemp.clear();
        while (1)//wersja
        {
            inFile.get(ch);
            if (ch != 'e')
                strTemp += ch;
            else
                break;
        }

        m_MyFileInfo.m_sHead.m_usFileVersion = strToInt(strTemp);
        std::cout << "Wersja: " << m_MyFileInfo.m_sHead.m_usFileVersion << std::endl;

        inFile.seekg(-1, inFile.cur);//od tego momentu pojawia się błąd
        strTemp.clear();

        inFile.get(ch);//e
        strTemp += ch;
        inFile.get(ch);//n
        strTemp += ch;
        inFile.get(ch);//d
        strTemp += ch;

        if (strTemp != "end")
        {
            std::cout << "Blad end\n";
            inFile.close();
            return false;
        }

        //////////////////////// -- koniec głównego nagłówka

        for (size_t i = 0; i < m_MyFileInfo.m_sHead.m_usFileCount; i++)//ładowanie poszczególnych plików
        {
            inFile.get(ch);//s
            strTemp += ch;
            inFile.get(ch);//B
            strTemp += ch;
            inFile.get(ch);//e
            strTemp += ch;
            inFile.get(ch);//g
            strTemp += ch;
            if (strTemp != "sBeg")
            {
                std::cout << "Blad sBeg\n";
                inFile.close();
                return false;
            }
            strTemp.clear();
            while (1)//nazwa
            {
                inFile.get(ch);
                if (ch != '+')
                    strTemp += ch;
                else
                    break;
            }
            m_FileInfo.m_sHead[i].m_strFileName = strTemp;

            strTemp.clear();
            while (1)//rozmiar
            {
                inFile.get(ch);
                if (ch != '+')
                    strTemp += ch;
                else
                    break;
            }
            m_FileInfo.m_sHead[i].m_ulSizeFile = strToInt(strTemp);
            m_FileInfo.m_ulSize[i] = m_FileInfo.m_sHead[i].m_ulSizeFile;

            strTemp.clear();
            while (1)//nr
            {
                inFile.get(ch);
                if (ch != 's')
                    strTemp += ch;
                else
                    break;
            }
            m_FileInfo.m_sHead[i].m_nNumberFile = strToInt(strTemp);
            inFile.seekg(-1, inFile.cur);

            strTemp.clear();
            inFile.get(ch);//s
            strTemp += ch;
            inFile.get(ch);//E
            strTemp += ch;
            inFile.get(ch);//n
            strTemp += ch;
            inFile.get(ch);//d
            strTemp += ch;

            if (strTemp != "sEnd")
            {
                std::cout << "Blad sEnd\n";
                inFile.close();
                return false;
            }

            m_pBuffer = new char[m_FileInfo.m_ulSize[i]];
            inFile.read(m_pBuffer, m_FileInfo.m_ulSize[i]);
            m_FileInfo.m_pvFile[i] = m_pBuffer;
        }//for
    }
    else
    {
        return false;
    }

    inFile.close();
    return true;
} 
0

Dziwnie zapisujesz liczby - dlaczego tak marnujesz miejsce konwertując je na ASCII i z powrotem?

0

Masz wielokrotnie zgwałconą zasadę DRY, tak na szybko wklej te funkcje i użyj od razu całość stanie się kilkowierszowa:

string readCount(ifstream &fin,unsigned Count)
  {
   string ret;
   while(Count--) ret+=(char)fin.get();
   return ret;
  }

string readUntil(ifstream &fin,char Stop)
  {
   string ret;
   for(char ch;(fin.get(ch))&&(ch!=Stop);) ret+=ch;
   return ret;
  }

Na przykład kilka wierszy z początku:

        inFile.seekg(0, std::ios_base::beg);
        ///////////////////////////////////////////początek głównego pliku -- główny nagłówek
        inFile.get(ch);//b
        strTemp += ch;
        inFile.get(ch);//e
        strTemp += ch;
        inFile.get(ch);//g
        strTemp += ch;
        //////////////////////////////////////////////
        if (strTemp != "beg")
        {
            std::cout << "Blad beg\n";
            inFile.close();
            return false;
        }
        strTemp.clear();
        while (1)//nazwa
        {
            inFile.get(ch);
            if (ch != '+')
                strTemp += ch;
            else
                break;
        }

        m_MyFileInfo.m_sHead.m_strFileName = strTemp;
        std::cout << "Nazwa: " << m_MyFileInfo.m_sHead.m_strFileName << std::endl;

zamieniasz na:

        inFile.seekg(0, std::ios_base::beg);
        ///////////////////////////////////////////początek głównego pliku -- główny nagłówek
        if(readCount(inFile,3)!="beg") return false; // plik sam się zamknie bo wychodzisz, wyjście będziesz psuć w miejscu wywołania, a jeszcze lepiej walnij tu wyjątek.
        m_MyFileInfo.m_sHead.m_strFileName=readUntil(inFile,'+');
        std::cout << "Nazwa: " << m_MyFileInfo.m_sHead.m_strFileName << std::endl;
1

Dodaj do flag otwarcia pliku ios::binary, dzięki czemu inFile.seekg() działa "normalnie".
Po tym wystąpi jeszcze jeden błąd, "Błąd sBeg", wystarczy dodać strTemp.clear() przed wczytywaniem tego łańcucha.
Przy okazji, string::c_str() zwraca wskaźnik do tablicy znaków.

m_MyFileInfo.m_sHead.m_pchFileExtension = (char*)strTemp.c_str();

Gdy później nadpisujesz łańcuch strTemp, informacja o rozszerzeniu jest stracona.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0