Reading Binary Files

I have this code but it's failing one test with using option 3 to read both files because it's only reading one and I'm not sure how to fix it.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

void processFile(string fileName, int opt);

int main(){
int option;
cin >> option;
string file;
if (option == 1){
file = "friendlyships.shp";
processFile(file, option);
}
else if (option == 2){
file = "enemyships.shp";
processFile(file, option);
}
else if (option == 3){
file = "friendlyships.shp";
processFile(file, option);
file = "enemyships.shp";
processFile(file, option);
}
return 0;
}


void processFile(string fileName, int opt)
{
char *tmp, *shipName, *shipClass, *weaponName;
unsigned int *tmpIntPtr, *shipShield, *weaponRating;
short *shipLength, *tmpShrtPtr, shrtTmp;
ifstream file;
unsigned int count, nameLength, classLength, intTmp, lengthIndex = 0, shieldIndex = 0,
warpIndex = 0, nameSize = 0, classSize = 0, numWeapons = 0, weaponLength, weaponSize = 0,
weaponIndex = 0, conIndex = 0;
float fltTemp, *weaponCon, *tmpFltPtr, *shipWarp;
char ch;
vector<int> numWeapVec;
vector<int> shipTracker, weaponTracker;
shipName = nullptr, shipClass = nullptr, shipLength = nullptr,
tmpIntPtr = nullptr, shipShield = nullptr, shipWarp = nullptr,
weaponName = nullptr, weaponRating = nullptr, weaponCon = nullptr;

file.open(fileName, ios::in | ios::binary);
if (file.is_open()){
file.read(reinterpret_cast<char *>(&count), 4);
for (unsigned int i = 0; i < count; i++){
file.read(reinterpret_cast<char *>(&nameLength), 4);
if (shipName != nullptr){
tmp = new char[nameSize];
for (unsigned int j = 0; j < nameSize; j++){
tmp[j] = shipName[j];
}
delete[] shipName;
shipName = new char[nameLength + nameSize];
for (unsigned int j = 0; j < nameSize; j++){
shipName[j] = tmp[j];
}
delete[] tmp;
}
else{
shipName = new char[nameLength];
}
for (unsigned int j = 0; j < nameLength; j++){
file.seekg(0L, ios::cur);
file.get(ch);
shipName[nameSize] = ch;
nameSize++;
}
shipTracker.push_back(nameSize);

file.read(reinterpret_cast<char *>(&classLength), 4);
if (shipClass != nullptr){
tmp = new char[classSize];
for (unsigned int j = 0; j < classSize; j++){
tmp[j] = shipClass[j];
}
delete[] shipClass;
shipClass = new char[classLength + classSize];
for (unsigned int j = 0; j < classSize; j++){
shipClass[j] = tmp[j];
}
delete[] tmp;
}
else{
shipClass = new char[classLength];
}
for (unsigned int j = 0; j < classLength; j++){
file.seekg(0L, ios::cur);
file.get(ch);
shipClass[classSize] = ch;
classSize++;
}
shipTracker.push_back(classSize);

file.read(reinterpret_cast<char *>(&shrtTmp), 2);
if (shipLength != nullptr){
tmpShrtPtr = new short [lengthIndex];
for (unsigned int j = 0; j < lengthIndex; j++){
tmpShrtPtr[j] = shipLength[j];
}
delete[] shipLength;
shipLength = new short [1 + lengthIndex];
for (unsigned int j = 0; j < lengthIndex; j++){
shipLength[j] = tmpShrtPtr[j];
}
delete[] tmpShrtPtr;
shipLength[lengthIndex] = shrtTmp;
lengthIndex++;
}
else{
shipLength = new short [1];
shipLength[lengthIndex] = shrtTmp;
lengthIndex++;
}
shipTracker.push_back(lengthIndex);

file.read(reinterpret_cast<char *>(&intTmp), 4);
if (shipShield != nullptr){
tmpIntPtr = new unsigned int[shieldIndex];
for (unsigned int j = 0; j < shieldIndex; j++){
tmpIntPtr[j] = shipShield[j];
}
delete[] shipShield;
shipShield = new unsigned int[1 + shieldIndex];
for (unsigned int j = 0; j < shieldIndex; j++){
shipShield[j] = tmpIntPtr[j];
}
delete[] tmpIntPtr;
shipShield[shieldIndex] = intTmp;
shieldIndex++;
}
else{
shipShield = new unsigned int[1];
shipShield[shieldIndex] = intTmp;
shieldIndex++;
}
shipTracker.push_back(shieldIndex);

file.read(reinterpret_cast<char *>(&fltTemp), 4);
if (shipWarp != nullptr){
tmpFltPtr = new float [warpIndex];
for (unsigned int j = 0; j < warpIndex; j++){
tmpFltPtr[j] = shipWarp[j];
}
delete[] shipWarp;
shipWarp = new float[1 + warpIndex];
for (unsigned int j = 0; j < warpIndex; j++){
shipWarp[j] = tmpFltPtr[j];
}
delete[] tmpFltPtr;
shipWarp[warpIndex] = fltTemp;
warpIndex++;
}
else
{
shipWarp = new float[1];
shipWarp[warpIndex] = fltTemp;
warpIndex++;
}
shipTracker.push_back(warpIndex);

file.read(reinterpret_cast<char *>(&numWeapons), 4);
numWeapVec.push_back(numWeapons);
weaponTracker.push_back(numWeapons);
for (unsigned int j = 0; j < numWeapons; j++){
file.read(reinterpret_cast<char *>(&weaponLength), 4);
if (weaponName != nullptr){
tmp = new char[weaponSize];
for (unsigned int j = 0; j < weaponSize; j++){
tmp[j] = weaponName[j];
}
delete[] weaponName;
weaponName = new char[weaponLength + weaponSize];
for (unsigned int j = 0; j < weaponSize; j++){
weaponName[j] = tmp[j];
}
delete[] tmp;
}
else{
weaponName = new char[weaponLength];
}
for (unsigned int j = 0; j < weaponLength; j++)
{
file.seekg(0L, ios::cur);
file.get(ch);
weaponName[weaponSize] = ch;
weaponSize++;
}
weaponTracker.push_back(weaponSize);

file.read(reinterpret_cast<char *>(&intTmp), 4);
if (weaponRating != nullptr){
tmpIntPtr = new unsigned int[weaponIndex];
for (unsigned int j = 0; j < weaponIndex; j++){
tmpIntPtr[j] = weaponRating[j];
}
delete[] weaponRating;
weaponRating = new unsigned int[1 + weaponIndex];
for (unsigned int j = 0; j < weaponIndex; j++){
weaponRating[j] = tmpIntPtr[j];
}
delete[] tmpIntPtr;
weaponRating[weaponIndex] = intTmp;
weaponIndex++;
}
else{
weaponRating = new unsigned int[1];
weaponRating[weaponIndex] = intTmp;
weaponIndex++;
}
weaponTracker.push_back(weaponIndex);

file.read(reinterpret_cast<char *>(&fltTemp), 4);
if (weaponCon != nullptr){
tmpFltPtr = new float[conIndex];
for (unsigned int j = 0; j < conIndex; j++){
tmpFltPtr[j] = weaponCon[j];
}
delete[] weaponCon;
weaponCon = new float[1 + conIndex];
for (unsigned int j = 0; j < conIndex; j++){
weaponCon[j] = tmpFltPtr[j];
}
delete[] tmpFltPtr;
weaponCon[conIndex] = fltTemp;
conIndex++;
}
else{
weaponCon = new float[1];
weaponCon[conIndex] = fltTemp;
conIndex++;
}
weaponTracker.push_back(conIndex);
}
}
}
else{
throw "File could not be opened";
}

int option;
cin >> option;
if (option == 1){
int i = 0, j = 0, k = 0, l = 0, m = 0, n = 0,
x = 0, y = 0, z = 0;
int firePower;
for (unsigned int a = 0; a < count; a++){
firePower = 0;
cout << "Name: ";
while (shipName[i] != '\0'){
cout << shipName[i];
i++;
}
i++;
cout << endl << "Class: ";
while (shipClass[j] != '\0'){
cout << shipClass[j];
j++;
}
j++;
cout << endl << "Length: " << shipLength[k];
k++;
cout << endl << "Shield capacity: " << shipShield[l];
l++;
cout << endl << "Maximum Warp: " << shipWarp[m];
m++;
cout << endl << "Armaments:" << endl;
if (numWeapVec[n] != 0){
for (int h = 0; h < numWeapVec[n]; h++){
while (weaponName[x] != '\0'){
cout << weaponName[x];
x++;
}
x++;

cout << ", " << weaponRating[y] << ", ";
firePower = firePower + weaponRating[y];
y++;
cout << weaponCon[z] << endl;
z++;
}
cout << "Total firepower: " << firePower << endl;
}
else{
cout << "Unarmed" << endl;
}
n++;
cout << endl;
}
}
When posting code, put it in "code tags" like this:

[code]
put your code between the tags to preserve indentation
[/code]


The problem in your code is not just with option 3. Your code has too many errors to go into them all. Multiple errors are of this type:

1
2
            // The first time this code is executed, nameSize is 0.
            tmp = new char[nameSize];

You also pass in opt but never use it. You create an option variable at one point and then use cin >> option to give it a value.
I have no idea what that's about (there's no prompt).

In general, having 40+ local variables in a single function is a hint that that function is doing way too much.

If you describe what you want the program to do there's probably a better way to write it that wouldn't be so ugly and complicated.
Can you provide the input file?

Use C++ strings and vectors instead of C strings and dynamic arrays. it will make your life a lot easier.

file.seekg(0L, ios::cur); does nothing. It basically says "go to where you current are."

There appears to be a lot of duplicated code. See if you can factor it out into functions.

instead of
1
2
3
4
if (file.is_open()) {
   // hundreds of lines of code
} else {
    throw "File could not be opened";
}

I find it much easier to read:
1
2
3
4
if (!file.is_open()) {
    throw "File could not be opened";
}
// hundreds of lines of code. 

It also cuts down on the indentation levels.
Topic archived. No new replies allowed.