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