Infinite loop in C++ why? - c++

Im sorry about posting a super long code, but when I run this code all I see is this-
Heap size: 1638652
Getting int:
Getting int:
Getting int:
Getting int:
Getting int:
Heap size: 1638653
and it keeps going in a loop with the heapsize being incremented by one.
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <exception>
#ifndef WX_REPORT_H
#define WX_REPORT_H
#include <string>
#include <sstream>
using std::string;
using std::stringstream;
typedef struct WX_REPORT
{
string unitType;
string stationName;
string time;
string gpsLoc;
int pressure;
int windSpeed;
int temperature;
int humidity;
int windDirection;
string toString()
{
stringstream str;
str << stationName << ": " << time << "\t" << gpsLoc << "\n";
str << pressure << "\n" << windSpeed << "\n" << temperature << "\n";
str << humidity << "\n" << windDirection;
return str.str();
}
}
WXReport;
#endif
/*
* Reports must be in the following format:
* M or I // Metric or imperial units
*/
using namespace std;
vector<WXReport*> heap;
bool compTime(const WXReport* a, const WXReport* b) {
if(a->time < b->time) { // timing
return false;
} else {
return true; // commands to return true
}
}
void heapAdd(WXReport* wx) {
heap.push_back(wx);
push_heap(heap.begin(), heap.end());
}
WXReport* heapPop() { // header popup
pop_heap(heap.begin(), heap.end());
WXReport* rep = heap.back();
heap.pop_back();
return rep;
}
void getInt(istream &input, int &i) {
string temp;
input>>temp;
cout<<"Getting int: "<<temp<<endl;
i = atoi(temp.c_str());
}
void readInFile(string filename) {
ifstream input(filename);
WXReport *report;
while(!input.eof()) {
report = new WXReport();
getline(input, report->unitType);
getline(input, report->stationName);
getline(input, report->time);
getline(input, report->gpsLoc);
getInt(input, report->pressure);
getInt(input, report->windSpeed);
getInt(input, report->temperature);
getInt(input, report->humidity);
getInt(input, report->windDirection);
heapAdd(report);
cout<<"Heap size: "<<heap.size()<<endl;
}
}
int menu() {
cout<<"\n\nPlease select one: "<<endl;
cout<<"1) Read in another file"<<endl;
cout<<"2) Display the fastest wind speed"<<endl;
cout<<"3) Display weather stations by name"<<endl;
cout<<"4) Display all weather reports"<<endl;
cout<<"5) Remove a weather report"<<endl;
cout<<"6) Write weather reports to file"<<endl;
cout<<"0) Exit"<<endl;
int choice;
cin>>choice;
return choice;
}
void printAllReports() {
cout<<"Printing all reports"<<endl;
for(WXReport* rep: heap) {
cout<<rep->toString()<<endl;
}
cout<<"Done printing reports"<<endl;
}
int main(int argc, char* argv[]) {
string filename = "report.txt";
readInFile(filename);
int choice = menu();
while(choice != 0) {
switch(choice) {
case 1:
cout<<"What file would you like to read in?"<<endl;
cin>>filename;
readInFile(filename);
break;
case 2:
cout<<"Has not been implemented"<<endl;
break;
case 3:
cout<<"Has not been implemented"<<endl;
break;
case 4:
printAllReports();
break;
case 5:
cout<<"Has not been implemented"<<endl;
break;
case 6:
cout<<"Has not been implemented"<<endl;
break;
default:
cout<<"Invalid choice, please try again."<<endl;
}
choice = menu();
}
cout<<"Thank you!"<<endl;
return 0;
}

Important part. If you read nothing else, read this: Always check the error codes and return values.
After ifstream input(filename); you have no idea if the file opened. Testing with input.is_open() gets past that.
If the file isn't open, all those calls to getline fail as does eof(). File not open, can't read end of file and can't exit loop. Even if the the file is open, if you don't check the output of getline, how do you know you read a line?
One of the fun parts of streams is if you test the stream, it tells you if it is in a bad state, so you can write code that looks like
if (getline(...) && getline(...) && ...)
So you don't have to make a massive block of if-else-if or a sea of nested ifs. First bad read and you are out.
The problem with if eof() is covered in the comments to the question. The basic is you don't know if you got the end of the file until you start reading. Also, what happen if you hit the end of the file in the middle of a bunch of reads?
So read a line. If it's good, read the next line, etc... until done.
getInt isn't necessary.
int val;
input >> val;
loads an integer into val, if the stream can be parsed into an int. If it can't, input is marked bad and you can check why. Could be unparsable. Could be end of file.
int val;
if (input >> val)
{
//do stuff
}
else
{
//no int here. Do other stuff
}
Just like above, you can chain the instructions and get
if (input >> val >> anotherval >> ...)

Related

C++ issues with adding variables to a vector list

I've created a program that reads different text files and stores each file in its own Vector list. However, the vector list proportion of the program is not working. Provided below is the text file im currently working on as well the program itself
Text file
A:Head:1:2:15.
B:Torso:0:6:5.
C:Leg:0:4:6.
D:Arm:0:4:8.
E:Tail:0:6:2.
Main file
#include <iostream>
#include <string>
#include <conio.h>
#include <stdio.h>
#include "driver.h"
#include "implementation.cpp"
#include <fstream>
#include <vector>
using namespace std;
int main() {
readFile();
writeFile();
robotComplexity();
getch();
return 0;
}
Implementation file containing functions
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <fstream>
#include <vector>
using namespace std;
//declaration of parts variables
char partCode;
std::string partName;
int maximum;
int minimum;
int complexity;
std::vector<string> partsVector;
std::ifstream partsList("Parts.txt");
std::string outputFile = "output.txt";
std::string input;
std::string newChar;
std::stringstream convertChar;
void readFile() //function to read Builders, Customers and Parts text file
{
std::string line;
while (std::getline(partsList, line)) {
line.pop_back();//removing '.' at end of line
std::string token;
std::istringstream ss(line);
convertChar << partCode;
convertChar >> newChar;
// then read each element by delimiter
int counter = 0;//number of elements you read
while (std::getline(ss, token, ':')) {//spilt into different records
switch (counter) {//put into appropriate value-field according to element-count
case 0:
newChar = token; //convert partCode from a char to a string
break;
case 1:
partName = token;
break;
case 2: maximum = stoi(token);
break;
case 3: minimum = stoi(token);
break;
case 4: complexity = stoi(token);
break;
default:
break;
}
counter++;//increasing counter
}
partsVector.push_back(newChar);
for(string x: partsVector)
cout << x << endl;
}
}
double robotComplexity() {
double complexity;
for(int i = 1; i < partsVector.size(); i++)
/*
if(newChar == "A") {
cout << "Character: " << newChar;
} else {
cout << "Program isnt working! :(";
} */
if(complexity > 100) {
complexity = 100;
}
cout << "\nThe Robot Complexity is: " << complexity << endl;
return complexity;
}
double robotVariability() {
double variability;
cout << "\nThe Robot Variability is: " << variability << endl;
return variability;
}
void writeFile() //writes to a file output.txt the end calculations.
{
}
The code that im currently experiencing issues with is the following
while (std::getline(partsList, line)) {
line.pop_back();//removing '.' at end of line
std::string token;
std::istringstream ss(line);
convertChar << partCode;
convertChar >> newChar;
// then read each element by delimiter
int counter = 0;//number of elements you read
while (std::getline(ss, token, ':')) {//spilt into different records
switch (counter) {//put into appropriate value-field according to element-count
case 0:
newChar = token; //convert partCode from a char to a string
break;
case 1:
partName = token;
break;
case 2: maximum = stoi(token);
break;
case 3: minimum = stoi(token);
break;
case 4: complexity = stoi(token);
break;
default:
break;
}
counter++;//increasing counter
}
partsVector.push_back(newChar);
for(string x: partsVector)
cout << x << endl;
}
When this program is compiled and executed, the following is printed out to the console
A
A
B
A
B
C
A
B
C
D
A
B
C
D
E
This is clearly wrong, as it should be printing one of each letter, as required by my program specs.
A
B
C
D
E
The purpose of this is so i know the function can successfully identify Each Record. To note, this occurs with other varialbes such as partName. Ive deducted that it is an issue with how I'm adding the variables to the vector but I am unsure why. Any help would be great Thankyou.
So the problem is simply where you are printing out the partsVector, it's inside your reading loop when it should be after the reading loop. So it should be this
while (std::getline(partsList, line)) {
...
partsVector.push_back(newChar);
}
for(string x: partsVector)
cout << x << endl;
instead of this
while (std::getline(partsList, line)) {
...
partsVector.push_back(newChar);
for(string x: partsVector)
cout << x << endl;
}
Because you are printing the parts vector as you read it in, you get those repeated values displayed.

C++ encrypt and decrypt secret messages using files

I have my prototypes in a header file, but I need some help. I am having some trouble getting the program to compile all the way through. It appears to be getting caught in a loop with the input. Possibly some issues with the functions. Thanks in advance for any input.
#include <iostream>
#include <conio.h>
#include "header.h"
#include <fstream>
class Caesar
{
public: void readText(char *input);
void encrypt(char *input,char *output,char *key);
void decrypt(char *input,char *output,char *key);
};
void main()
{
Caesar a;
char key[1000];
ifstream fin;
int choice;
char input[100],output[100];
cout<<"\n Enter input file: ";
cin>>input;
cout << input;
cout<<"\n Enter output file: ";
cin>>output;
cout <<output;
cout<<"\n Enter key: ";
cin>>key;
cout <<key;
cout<<"\n\n 1. Encrypt\n 2. Decrypt\n\n Select choice(1 or 2): "<< endl;
cin >> choice;
cout << choice;
a.readText(input);
if(choice==1)
{
a.encrypt(input,output,key);
}
if(choice==2)
{
a.decrypt(input,output,key);
}
else
{
cout<<"\n\n Unknown choice";
}
}
void Caesar::readText(char *input)
{
ifstream reader;
char buf;
reader.open(input);
cout<<"\n\n <--- "<<input<<" --->\n";
buf=reader.get();
while(!reader.eof())
{
cout<<buf;
buf=reader.get();
}
reader.close();
}
void Caesar::encrypt(char *input,char *output,char *key)
{
ifstream reader;
ofstream writer;
char buf;
reader.open(input);
writer.open(output);
buf=reader.get();
while(!reader.eof())
{
if(buf>='a'&&buf<='z')
{
buf-='a';
buf+=key[buf];
buf%=26;
buf+='A';
}
writer.put(buf);
buf=reader.get();
}
reader.close();
writer.close();
readText(input);
readText(output);
}
void Caesar::decrypt(char *input,char *output,char *key)
{
ifstream reader;
ofstream writer;
char buf;
reader.open(input);
writer.open(output);
buf=reader.get();
while(!reader.eof())
{
if(buf>='A'&&buf<='Z')
{
buf-='A';
buf+=26-key[buf];
buf%=26;
buf+='a';
}
writer.put(buf);
buf=reader.get();
}
reader.close();
writer.close();
readText(input);
readText(output);
}
if(choice=1)
should be
if(choice==1)
and also in the other if
In your case, you are assigning the value 1 to choice, then test if choice is true, and it is, since any non-zero numeral type is implicitly casted to bool true.
I have just executed your code and tried debugging it and took a screen shot
you program gets into a loop after entering the choice.there is no problem with cin>>.
From your comments, it seems like you're just trying to debug main. Everything seems to work fine. What are you inputting for key? If it's a very large integer, that may be your problem as it might exceed the maximum integer range and cause overflow.
Your key is an integer variable. You are inputting a string for the file name that holds your key, so that should be changed to a C string array. Change all of the passed key parameters to char* instead of int.
You have an infinite loop when the readText() function is called.
Maybe try this:
void Caesar::readText(char *input)
{
ifstream reader(input);
if(reader.is_open())
{
char buf;
cout<<"\n\n <--- "<<input<<" --->\n";
while(reader.get(buf))
{
cout << buf;
}
}
reader.close();
}
Make sure that your text file is in the same folder as your code. See this for more details: ifstream not opening file

I need help doing a word search and count

Ok so im doing a homework assignment where im suppose to read a a text file with a 100 selected words and then read another "text" file and compare how many of those 100 selected words show up on the "text" file and what is the longest and shortest words and how many time those selected words are in the text file. I need complete help this is what i got so far. by the way i still havent inputed the selected files yet so thats why those ifs statements are incomplete
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
int fileNumber;
string Words [100];
string wordCounts [100];
string Frequencies [100];
string shortest = "abcdefghijklmnopqrstuvwxyz";
string longest = "";
int totalWordCount = 0;
ifstream inData;
int I=0;
inData.open("SelectWords.txt");
while ( !inData.eof () ) {
inData >> Words [I];
}
int irow;
while ( irow=0, irow<=100, irow++) {
cout<<Words[I]<<endl;
}
cout<<"Choose a file you want to open"<<endl;
cout<<"1= A Modest Proposal"<<endl;
cout<<"2=Apology" <<endl;
cout<<"3=The Call of the Wild"<<endl;
cout<<"4=The Adventures of Tom Sawyer"<<endl;
cin>> fileNumber;
while ((fileNumber<1) || (fileNumber>4))
{
cout<<"Error please try again"<<endl;
cout<<"Choose a file you want to open"<<endl;
cout<<"1 - A Modest Proposal"<<endl;
cout<<"2 - Apology" <<endl;
cout<<"3 - The Call of the Wild"<<endl;
cout<<"4 - The Adventures of Tom Sawyer"<<endl;
cin>> fileNumber;
}
if (fileNumber==1)
{
}
if (fileNumber==2)
{
}
if (fileNumber==3)
{
}
if (fileNumber==4)
{
}
system ("pause");
return 0;
}
I would do something like this:
std::string filename;
switch (filenumber)
{
case 1:
filename = "modest_proposal.txt";
break;
case 2:
filename = "apology.txt";
break;
//...
}
std::ifstream target_file(filename.c_str());
if (!target_file)
{
std::cerr << "Error opening file " << filename << endl;
return EXIT_FAILURE;
}
std::string word;
while (target_file >> word)
{
// Search word list
}
Notice how I only use the switch for determining the file name. The remaining part of the algorithm is the same regardless of the file name.
Edit 1: Suggestions
Use std::map<word, count> instead of two separate arrays.
Create one text variable for the menu and print the variable twice
instead of duplicating the code.

Binary structure delete error

This is the whole program. Right now,the delete function does not write to the temp file. I'll try to change str array to string and see if it helps.
The program is supposed to read write edit search and sort binary file with structures.
#include <cstdlib>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include<string>
#include<limits>
#include<iomanip>
#include<stdio.h>
#include <errno.h>
using namespace std;
const int SIZE=40;
char typedef str[SIZE];
char fname[]="c:/solident.dat";
char tname[]="c:/temp.dat";
struct Rec{int id;str lname,fname;};
//prototypes
void menu(string&);
void engine(string&,Rec&,fstream&,fstream&,int,char[],char[]);
void openFile(char[]);
void addRec(Rec&,char[]);
void delAll(char[]);
void listAll(Rec&,fstream &,char[]);
void appRec(Rec&,fstream &,char[]);
void delRec(Rec&,fstream &, fstream &,char[],char []);
void srcRec(Rec&,fstream& ,char[]);
void modRec(Rec &J,fstream &outfile, char fname[]);
void sort();
int main(int argc, char *argv[])
{
string choice;
Rec Student;
fstream infile;
fstream outfile;
do
{
menu(choice);
engine(choice,Student,infile,outfile,SIZE,fname,tname);
} while(choice[0]!='0');
system("PAUSE");
return EXIT_SUCCESS;
}
//function menu
void menu(string &choice)
{
cout<<"\n\n\n\t\t========================";
cout<<"\n\n\t\tMENU \n";
cout<<"\n\t\t========================\n\n";
cout<<"\t\t[1] Open/check file\n";
cout<<"\t\t[2] Add records\n";
cout<<"\t\t[3] Append records\n";
cout<<"\t\t[4] Search for a record\n";
cout<<"\t\t[5] Delete a record\n";
cout<<"\t\t[6] Delete all records\n";
cout<<"\t\t[7] Modify a record\n";
cout<<"\t\t[8] List all records\n";
cout<<"\t\t[9] Sort all records\n";
cout<<"\t\t[0] Exit\n";
cout<<"\n\t\t========================= \n";
cout<<"\t\tYour choice :";
getline(cin,choice);
while (choice[0] !='1' && choice[0] !='2' &&choice[0] !='3' &&choice[0] !='4' &&choice[0] !='5' &&choice[0] !='6' &&choice[0] !='7' &&choice[0] !='8' &&choice[0] !='9' &&choice[0] !='0' )
{
cout<<"\n\t\t"<<choice<<" is invalid!";
cout<<"\n\t\tEnter correct choice: ";
getline(cin,choice);
}
cout<<"\n\t\t========================= \n\n";
}
//function
void engine(string &choice,Rec &J,fstream &infile,fstream &outfile,int SIZE,char fname[],char tname[])
{
switch (choice[0]){
case '1':
{
cout<<"Executing number "<<choice<<":"<<"Open/check file\n"<<endl;
openFile(fname);
break;
}
case '2':
{
cout<<"Executing number "<<choice<<":"<<"Add records\n"<<endl;
addRec(J,fname);
break;
}
case '3':
{
cout<<"Executing number "<<choice<<":"<<"Append records\n"<<endl;
appRec(J,outfile,fname);
break;
}
case '4':
{
cout<<"Executing number "<<choice<<":"<<"Search for a record\n"<<endl;
srcRec(J,infile,fname);
break;
}
case '5':
{
cout<<"Executing number "<<choice<<":"<<"Delete a record\n"<<endl;
delRec(J,infile, outfile,fname,tname);
break;
}
case '6':
{
cout<<"Executing number "<<choice<<":"<<"Delete all records\n"<<endl;
delAll(fname);
break;
}
case '7':
{
cout<<"Executing number "<<choice<<":"<<"Modify a record\n"<<endl;
modRec(J,outfile,fname);
break;
}
case '8':
{
cout<<"Executing number "<<choice<<":"<<"List all records\n"<<endl;
listAll(J,infile,fname);
break;
}
case '9':
{
cout<<"Executing number "<<choice<<":"<<"Sort all records\n"<<endl;
sort();
break;
}
default:exit(0);
}
}
//function
void openFile(char fname[])
{
cout<<"\nOpening file"<<fname<<"..."<<endl;
//confirm if file exists and opens
fstream infile;
fstream outfile;
infile.open(fname,ios::in|ios::binary);
if (infile.is_open())
{
cout<<"File "<<fname<<" exists, and was opened succesfully.";
}
infile.close();
//if fail ask to create
if (infile.fail())
{
cout<<"File does not exist. Create? [Y]/[N]";
char ch;
cin>>ch;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//if yes then create file
if(ch=='y'|| ch=='Y')
outfile.open(fname,ios::out| ios::binary);
//if not created display error
if (outfile.fail())
{
cout<<"Error: File not created";
}
//else confirm creation of file
cout<<"File "<<fname<<" has been created.\n\n";
outfile.close();
}
}
//function
void addRec(Rec&J,char fname[])
{
fstream outfile;
outfile.open(fname,ios::out|ios::binary|ios::app);
char another[10];
do
{
cout<<"Please enter ID number :";
cin>>J.id;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout<<"\nPlease enter first name: ";
cin.getline(J.fname,SIZE);
cout<<"\nPlease enter lastname: ";
cin.getline(J.lname,SIZE);
outfile.write((char*) &J, sizeof(J));
cout<<"Add another record:[Y]/[N] ";
cin.get(another[0]);
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} while(another[0]=='y'||another[0]=='Y');
cout<<"exiting to main menu.."<<endl;
}
//function
void delAll(char fname[])
{
fstream outfile;
cout<<"\n------------------\n"<<endl;
cout<<"\nDelete all records"<<fname<<"..."<<endl;
cout<<"\nAre you sure you want to delete all records in "<<fname<<" [Y]/[Any key for exit]?"<<endl;
char ch;
cin>>ch;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if(ch=='y'||ch=='Y')
{
outfile.open(fname,ios::out|ios::binary|ios::trunc);
outfile.close();
}
else {cout<<"\nExiting to main menu..."<<endl;}
}
//function
void listAll(Rec&J,fstream &infile,char fname[])
{
infile.clear();
infile.open(fname,ios::in|ios::binary);
infile.read((char*)&J,sizeof(J));
cout<<"|=======================================================|"<<endl;
cout<<"| # | ID | FIRST | LAST |"<<endl;
cout<<"|=======================================================|"<<endl;
int count=1;
while(!infile.eof())
{
cout<<"| "<<setw(6)<<left<<count<<left<<"| "<<setw(9)<<J.id<<"| ";
cout<<left<<setw(14)<<J.fname<<"| ";
cout<<left<<setw(19)<<J.lname<<"|"<<endl;
infile.read((char*)&J,sizeof(J));
count=count+1;
cout<<"|-------------------------------------------------------|"<<endl;
}
infile.close();
}
//function
void appRec(Rec &J,fstream &outfile, char fname[])
{
outfile.open(fname,ios::out|ios::binary|ios::app);
outfile.clear();
cout<<"Please enter ID number :";
cin>>J.id;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout<<"\nPlease enter first name: ";
cin.getline(J.fname,SIZE);
cout<<"\nPlease enter lastname: ";
cin.getline(J.lname,SIZE);
outfile.write((char*) &J, sizeof(J));
outfile.close();
}
//----------------------------------------------------
void delRec(Rec&s,fstream &infile, fstream &outfile,char fname[],char tname[])
{
int current, request=1;
infile.open("c:/solident.dat",ios::in|ios::out|ios::binary);
if (!infile.is_open())
cout << "infile not open\n";
outfile.open("c:/temp.dat",ios::out|ios::binary|ios::trunc);
if (!outfile.is_open())
cout << "outfile not open\n";
for (;;)
{
infile.read((char*)&s, sizeof s);
if (infile.eof())
break;
current = s.id;
if (current != request)
outfile.write((char*)&s, sizeof s);
}
infile.close();
outfile.close();
infile.open("c:/temp.dat)",ios::in|ios::binary);
outfile.open("c:/solident.dat)", ios::out|ios::binary|ios::trunc);
for (;;)
{
infile.read((char*)&s, sizeof (s));
if (infile.eof())
break;
outfile.write((char*)&s, sizeof (s));
}
infile.close();
outfile.close();
}
void srcRec(Rec&Job,fstream &infile,char fname[])
{
cout << "Allowing the user to open a specific record.\n";
infile.open(fname, ios::in | ios::binary) ;
if(infile.fail())
{
cout << "Could not access file.\n";
}
else
{
int position; //user's position
//gets user's position
cout << "Please the record you would like to read: ";
cin >> position;
//ignore luki
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//find the specific record, read it, and display it
infile.seekp((position - 1)*sizeof(Job));
infile.read((char*) &Job, sizeof(Job));
cout<<"|===============================================|"<<endl;
cout<<"| ID | FIRST | LAST |"<<endl;
cout<<"|===============================================|"<<endl;
cout<<left<<"| "<<setw(9)<<Job.id<<"| ";
cout<<left<<setw(14)<<Job.fname<<"| ";
cout<<left<<setw(19)<<Job.lname<<"|"<<endl;
}
//clears and closes the file
infile.clear();
infile.close();
}
void modRec(Rec &J,fstream &outfile, char fname[])
{
int position, //user's position
cntr = 0; //marks the current record within the file
cout << "Modifying a record.\n";
//open the two files
outfile.open(fname, ios::out | ios::in | ios::binary);
//get the user's desired position
cout << "please enter the record you would like to modify: ";
cin >> position;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << endl;
if(outfile.fail())
{
cout << "File could not be read.\n";
}
else
{
//find the desired record
outfile.seekp((position - 1)*(sizeof(J)));
//get the user's modification
cout<<"Please enter ID number :";
cin>>J.id;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout<<"\nPlease enter first name: ";
cin.getline(J.fname,SIZE);
cout<<"\nPlease enter lastname: ";
cin.getline(J.lname,SIZE);
//write over the desired record
outfile.write((char*) &J, sizeof(J));
}
//closes the files
outfile.close();
}
void sort()
{
int StructureSize, Idx1, Idx2;
FILE * binaryFile;
binaryFile = fopen("c:/solident.dat","rb+");
Rec Index, IndexTemp;
StructureSize = sizeof(Index);
fseek(binaryFile, 0, SEEK_END);
int fileSize = ftell(binaryFile);
rewind(binaryFile);
for (Idx1 = 0; Idx1 < fileSize; Idx1 += StructureSize)
{
for (Idx2 = 0; Idx2 < fileSize - StructureSize; Idx2 += StructureSize)
{
fread(&Index, StructureSize, 1, binaryFile);
fread(&IndexTemp, StructureSize, 1, binaryFile);
if (Index.id > IndexTemp.id)
{
fseek(binaryFile, -(StructureSize * 2), SEEK_CUR);
fwrite(&IndexTemp, StructureSize, 1, binaryFile);
fwrite(&Index, StructureSize, 1, binaryFile);
fseek(binaryFile, -StructureSize, SEEK_CUR);
}
else
{
fseek(binaryFile, -StructureSize, SEEK_CUR);
}
}
rewind(binaryFile);
}
fclose(binaryFile);
}
I don't know, there seem to be a few issues with this code. Here's just one of them though
int request=1,current;
...
while (!infile.eof())
{
s.id=current;
if (current!=request)
At no point in this code do you give current a value, but you are still using the variable. This is an uninitialised variable which is one reason your code isn't working.
I wonder if you meant to write
current=s.id;
instead? That would make a little more sense.
Try reading the file with a loop like this
infile.open("c:/solident.dat",ios::in|ios::out|ios::binary);
if (!infile.is_open())
cout << "infile not open\n";
outfile.open("c:/temp.dat",ios::out|ios::binary|ios::trunc);
if (!outfile.is_open())
cout << "outfile not open\n";
for (;;)
{
infile.read((char*)&s, sizeof s);
if (infile.eof())
break;
current = s.id;
if (current != request)
outfile.write((char*)&s, sizeof s);
}
infile.close();
outfile.close();
I wouldn't use fail() if I were you. I think it's extremely unlikely you'll detect a genuine read or write failure with it. It's much more likely to be an end of file error, or a failure to open a file.
#john .Thanks!
The first part works, but trying
rename(tempname,destination) does not work:
(the dest file exists)
Although the file temp.dat now contains the records minus the one deleted , the output is not written to the solident.dat file(it remains unchanged)
//So I tried to read every rec from file and write every record to dest file:
infile.open("c:/temp.dat)",ios::in|ios::binary);
outfile.open("c:/solident.dat)", ios::out|ios::binary|ios::trunc);
infile.read((char*)&s, sizeof s);
for (;;)
{
if (infile.eof())
break;
infile.read((char *)&s, sizeof (s));
outfile.write((char*)&s, sizeof (s));
}
infile.close();
outfile.close();
My understanding was, that outfile and infile are pretty straightforward: fstream.open, close , clear and it should work (I thought). It seems though that I'm missing something essential, because the simple delete binary struct function in the program seems to be a hit and miss and I've been going around in circles for a few days: parts of it work, then I add a few lines of code and either a function fails or the whole program fails.I tend to blame it on the compiler or devc++ :) but I'm certain it has to be the code that is invalid!
Thanks for help!

Program hangs because of some reason

The following code is supposed to read records from input and store them in a file called file.dat. Then it is supposed to arrange these records in ascending order, but for some reason the program hangs in the second while loop at line "file1.seekg(-(sizeof(r)),std::ios::cur);". Can someone please tell me what's wrong?
#include <iostream>
#include <fstream>
#include <strstream>
int main()
{
std::ofstream file;
file.open("file.dat",std::ios::trunc|std::ios::binary);
if(!file)
std::cout<<"unable to open for output";
struct record
{
char code[6];
char name[20];
int i;
};
record r;
int a = 0;
while(1)
{
std::cout<<"Record " << a + 1 << std::endl;
std::cout<<"Enter character code, name and an int \n";
std::cin.ignore();
std::cin.getline(r.code,6);
std::cin.getline(r.name,20);
std::cin>>r.i;
file.write((char *)&r,sizeof(r));
std::cout<<"\nAdd another (y\\n) : ";
char c;
std::cin>>c;
if(c == 'n')
break;
a++;
std::cout<<'\n'<<'\n';
}
file.close();
std::fstream file1("file.dat",std::ios::in|std::ios::out|std::ios::binary);
if(!file1)
std::cout<<"unable to open file1";
else
{
if(a>0)
{ while(a)
{
file1.seekp(0);
for(int i = a; i>0;i--)
{
record r1;
file1.read((char *)&r,sizeof(r));
file1.read((char *)&r1,sizeof(r1));
if(r1.i < r.i)
{
file1.seekp(-(sizeof(r)*2),std::ios::cur);
file1.write((char *)&r1,sizeof(r));
file1.write((char *)&r,sizeof(r));
file1.seekg(-(sizeof(r)),std::ios::cur);
}
}
a--;
}
}
file1.close();
}
std::ifstream file2("file.dat",std::ios::binary);
if(!file2)
std::cout<<"unable to open file2";
else
while(1)
{
std::cout<<"\n\n";
file2.read((char *)&r,sizeof(r));
if(file2.eof())
break;
std::cout<<r.code<<'\t'<<r.name<<'\t'<<r.i;
}
}
first
change std::get.ignore -> std::cin.ignore()
if you want to discard one character.
it compiled well and created file.dat file..
you might check the record inside file.dat though
If you are trying to ignore the new line character entered after the actual dat, then you have to use:
std::cin.ignore();
If you want more reference on use of ignore go to this LINK