Why do I see the contents of binary files? - c++

Why I can open and view binary files . odd appearance that is impossible ?
http://codepad.org/OwX99H0p
Enter a string str -> char arr1[] -> FILEOUT.DAT
FILEOUT.DAT -> char arr2[] -> Printed screens
The code in question:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void NhapMang(char *&arr, string str , int &n)
{
n = str.length();
arr = new char[n];
for (int i = 0; i < n;i++)
{
arr[i] = str[i];
}
}
void XuatMang(char *arr, int n)
{
for (int i = 0; i < n;i++)
{
cout << arr[i];
}
}
void GhiFile(ofstream &FileOut, char *arr, int n)
{
FileOut.open("OUTPUT.DAT", ios::out | ios::binary);
FileOut.write(arr, n*sizeof(char));
FileOut.close();
}
void DocFile(ifstream &FileInt, char *&arr, int n)
{
FileInt.open("OUTPUT.DAT", ios::in | ios::binary);
arr = new char[n];
FileInt.read(arr, n*sizeof(char));
FileInt.close();
}
int main()
{
char *arr1;
int n1;
fflush(stdin);
string str;
getline(cin, str);
NhapMang(arr1, str,n1);
ofstream FileOut;
GhiFile(FileOut, arr1, n1);
char *arr2;
int n2 = n1;
ifstream FileInt;
DocFile(FileInt, arr2, n2);
XuatMang(arr2, n2);
delete[] arr1;
delete[] arr2;
system("pause");
return 0;
}

You're ultimately storing data in a file. What this data represents is up to you, keep in mind, it's all '1's and '0's in the end. When you open the file you've created with a text editor, it will try to interpret this data as text which doesn't give a readable result.
Imagine storing a liquid in a bottle. If you don't label it, no one knows what it is. If you then pour this liquid in your car, it will try to use this as gasoline and potentially wreck your engine. Computers, fortunately, are much more forgiving.
Most files store information about how the data can be interpreted in their headers so programs can check if the file type is supported or not. So trying to open this file in a media player for example is most likely telling you that this format is not supported instead of trying to interpret the data as a media.

Related

Read from the file from different functions

I'm trying to read from the same file from another function but it doesn't work.
I guess the problem is that I'm trying to read from ifstream &input but I don't know the other way to implement that
#include <iostream>
#include <fstream>
using namespace std;
class Student{
public:
char name[40]; // i cant use string
int age;
void Input(ifstream &input)
{
input.getline(name, 40);
input >> age;
}
};
void Read(Student *students, int &numberOfStudents)
{
ifstream input("test.txt");
input >> numberOfStudents;
students = new Student[numberOfStudents];
for (int i = 0; i < numberOfStudents; ++i)
students[i].Input(input);
input.close();
}
int main()
{
int size = 0;
Student *students = NULL;
Read(students, size);
for (int i = 0; i < size; ++i)
cout << students[i].name << endl << students[i].age << endl;
return 0;
}
I made my input file
3
1
2
3
4
5
6
(if the program was working correctly i should've get 1 - name age - 2 etc)
but what i got is no names with ages = 1 2 3 respectively
The program does not work because you define:
void Read(Student *students, int &numberOfStudents)
And then
int size = 0;
Student *students = NULL;
Read(students, size);
The students pointer is passed-by value so Read() can not change the memory address outside the function.
To fix this simply pass the the pointer by-reference:
void Read(Student *& students, int &numberOfStudents)
Lastly as I commented you need to account white space e.g. '\n' line ending
In the file when using >> operator to extract data:
void Input(ifstream &input)
{
input.getline(name, 40);
input >> age;
input.ignore(1);
}
Same for reading the number of students in the file.

C++ Storing Items in Array and Setting each Token

My name is Faith and I am a beginner programmer in C++. I am working on a project where I have to read in two file and be able to separate the items in each file to its own variable. The first file has two pieces of information separated by "," and the second has three pieces of information. So far, I think I've done well with reading the files and getting each line in the file. Also I've separated each item by "," now I am trying to store those items in its on variable. Please Help! I've tried starting this project over multiple times and this is the only method I know how to implement to do this.
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
using namespace std;
class Manufactuer{
string upcode;
string company_name;
public:
void setupcode(string value){
upcode= value; }
void setcompany_name(string value){
company_name= value; }
string getupcode(){ return upcode;}
string getcompany_name(){return company_name;}
};
class Products{
string product_num;
string quantity;
string product_name;
public:
void setproduct_num(string value){
product_num= value; }
void setproduct_name(string value){
product_name= value; }
void setquantity(string value){
quantity = value;}
string getproduct_num(){ return product_num;}
string getquantity(){return quantity;}
string getproduct_name(){return product_name;}
};
int main(int argc, const char * argv[]) {
//opens the csv file
std::ifstream mccodesfile;
std::ifstream salesfile;
mccodesfile.open("mccodes.csv");
if(!mccodesfile){// file couldn't be opened
cout<<"Failed: file could not be opened"<<endl<<"Press Enter to Close:";
cin.get();
return 0;
}else
cout<<"Successfully opened file!"<<endl;
salesfile.open("sales.csv");
if(!salesfile){// file couldn't be opened
cout<<"Failed: file could not be opened"<<endl<<"Press Enter to Close:";
cin.get();
return 0;
}else
cout<<"Successfully opened file!"<<endl;
Manufactuer* upccodes;
int count; //how many elements in the array
int size; //how large the array
count = 0;
size = 2;
upccodes= (Manufactuer*)malloc(size*sizeof(Manufactuer)); //Malloc dynamatically reserve memory for variable pointer
string line;
while (getline(mccodesfile,line)) {// Taking every line from the file and putting in the variable line
Manufactuer newcode = Manufactuer(); //creating a upcode object
istringstream ss(line);
string token; //setting up split values
bool haveReadUPCode = false;
while (getline(ss,token,',')){// Separated values by comma
if(!haveReadUPCode){
newcode.setupcode(token);
haveReadUPCode = true;
}else{
newcode.setcompany_name(token);
}
}
if (count == size){
size = size * 2;
upccodes= (Manufactuer*)realloc(upccodes,size*sizeof(Manufactuer)); //Double the size while keeping the same elements
}
upccodes[count++]= newcode;
// cout<<line<<endl;
}
for (int i = 0; i<count; i++){
// cout<<upccodes[i].getcompany_name()<<endl; //Prints Manufactuers name--Works!
}
for (int i=0; i<count; i++) {
// cout<<upccodes[i].getupcode()<<endl; //Prints UPCcodes--Works
}
Products* product;
product= (Products*)malloc(size*sizeof(Products)); //Malloc dynamatically reserve memory for variable pointer
while(getline(salesfile, line)){{// Taking every line from the file and putting in the variable line
Products newProduct = Products(); //creating a product object
istringstream ss(line);
string token; //setting up split values
bool haveReadProduct = false;
while (getline(ss,token,',')){// Separated values by comma
if(!haveReadProduct){
newProduct.setproduct_num(token);
haveReadProduct = true;
} else{
newProduct.setproduct_name(token);
newProduct.setquantity(token);
}
}
if (count == size){
size = size * 2;
product= (Products*)realloc(product,size*sizeof(Products)); //Double the size while keeping the same elements
}
product[count++]= newProduct;
//cout<<line<<endl; //LINES ARE Printing!
}
}
for (int i = 0; i<count; i++){
// cout<<product[i].getproduct_name()<<endl; //Prints Product name--Works
}
for (int i = 0; i<count; i++){
//cout<<product[i].getproduct_num()<<endl; //Prints Product number--Works
}
}

'std::string' has no member named 'get' list[i]=user.get;

I get this error in my code and I know why it's there. But I don't now how to fix it and achieve what I want to achieve.
list[i]=user.get; << this line of code is me trying to put a string into a char array. How would I convert the string into char while still being able to keep user.length() and getline so I can know how big my dynamic array should be?
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char *list;
string user;
int counter[26];
int data;
cout<< "Enter in a line of text (all lowercase)"<<endl;
//cin>>user;
getline(cin, user);
//cin.get(user);
cout<< user.length()<<endl;
list = new char [user.length()];
for(int i=0; i<user.length(); i++)
{
list[i]=user.get;
}
cout<< list[0]<<endl;
/*
char alphabet [26];
for (int i=0; i<25; i++)
{
data=i+97;
alphabet[i]=data;
cout<< data;
}
for (int i=0; i<25; i++)
{
if (list[i]==alphabet[i])
counter[i]++;
cout<< list[0];
}
*/
return 0;
}
You can find the string documented here.
The c_str() method returns a pointer to the underlying char array that you can memcpy or strcpy into a char array of your own.
std::size_t user_length = user.length() + 1;
char* list = new char [user_length];
strncpy(list, user.c_str(), user_length);
...
delete [] list;
Replace
list[i]=user.get;
With
list[i]=user.at(i);

Getting heap corruption when writing to a file

Im trying to write a powerset to a file, but I get a heap corruption if my starting array is bigger than size 6, and im not sure why. It works fine with any size of array 6 or under. Cant figure this out.
Also, test.txt is where I read in the array. If the file contains"1,2,3,4,5,6" it works fine, but it it contains "1,2,3,4,5,6,7" I get heap corruption.
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include "N26.h"
#include <math.h>
using namespace std;
void increaseArray(int* theArray, int size)
{
int i = size;
int n = i+1;
int* newArray = new int[n];
for(int cnt=0;cnt<n;cnt++)
{
newArray[cnt] = theArray[cnt];
}
newArray[n-1]= NULL;
theArray = newArray;
return;
}
void printPowerSet(int *s, int n)
{
int i=0,j=0;
ofstream myFile;
double SetSize=pow(2.0,n);
myFile.open("powerset1.txt", std::ios_base::app);
cout<<"{size of original}"<< n <<endl;
cout<<"{number of sets}"<< SetSize-1 <<endl;
for(i=1;i<SetSize;++i)
{
for(j=0;j<n;++j)
{
if(((i>>j)&1)==1)
{
myFile << s[j] <<",";
}
}
myFile<<endl;
}
return;
}
int main()
{
ifstream myFile;
int item;
string input ="";
string fileName = "test.txt";
myFile.open(fileName);
while(myFile)
{
int k = 1;
int* transaction= new int[1];
if(!getline(myFile,input))
break;
istringstream ss(input);
while(ss)
{
if(!getline(ss,input, ','))
break;
input.erase(remove_if(input.begin(), input.end(), isspace), input.end());
item = atoi(input.c_str());
transaction[k-1] = item;
increaseArray(transaction,k);
k++;
}
for(int i =0; i<k-1;i++)
{
cout << transaction[i];
}
printPowerSet(transaction, k-1);
cout << endl;
transaction=NULL;
}
system("Pause");
return 0;
}
Your increaseArray() function doesn't work because you're only changing a local copy of the pointer. You'd have to pass a double pointer or a pointer reference to do what you want.
Example of a reference to pointer:
void increaseArray(int*& theArray, int size)
Instead, I'd recommend using a std::vector, since this will grow automatically.
I doubt this has any bearing on your problem, but I don't see that you ever delete, either. You are leaking memory. Before reassigning your pointer with a new allocation, delete the old allocation:
delete [] theArray; // The "[]" is important!
theArray = newArray;
In addition to Fred's answer.
Look at what's going on inside increaseArray(), specifically these lines:
int i = size;
int n = i+1;
int* newArray = new int[n];
for(int cnt=0;cnt<n;cnt++)
{
newArray[cnt] = theArray[cnt];
}
You allocate an array of size + 1 elements, and then iterate over the original. That's off-by-one, i.e. you are accessing one element outside of the original array. That might get you a segmentation fault depending on how new lays out the heap, but sure is undefined behavior.

segmentation fault when calling close on ifstream object

I am trying to read a text file into a two dimensional character array. When I call close on the ifstream object after extracting the data, I get a segmentation fault.
This works:
problem::problem(obj *o1, obj* o2, char *state_file)
{
ifstream infile;
string line;
infile.open(state_file, ios::in);
getline(infile,line);
infile.close();
}
This doesnt:
problem::problem(obj *o1, obj* o2, char *state_file)
{
ifstream infile;
string line;
//data is char data[6][7] and is declared in the header
//line is EXACTLY 7 characters lone
infile.open(state_file, ios::in);
for(int i = 5;i >= 0;i--)
{
getline(infile,line);
for(int j = 0;j < 7;j++)
data[i][j] = line[j];
}
cerr << "PROGRAM OK" << endl;
infile.close();
cerr << "The program doesn't get here" << endl;
//Some more constructor code
}
Why am I getting a segmentation fault when I call infile.close()?
SSCCE version that works with the same input file:
#include <string>
#include <fstream>
using namespace std;
class func
{
public:
func(char *);
private:
char data[6][7];
};
func::func(char *state_file)
{
ifstream infile;
string line;
infile.open(state_file, ios::in);
for(int i = 5;i >= 0;i--)
{
getline(infile,line);
for(int j = 0;j < 7;j++)
data[i][j] = line[j];
}
infile.close();
}
int main(int argc, char *argv[])
{
func *obj = new func(argv[1]);
delete obj;
return 0;
}
From main:
obj *p1 = new obj(&something);
obj *p2 = new obj(&something);
problem *p;
if(argc == 3)
p = new problem(p1, p2, argv[2]); //SEGFAULTS HERE
else
p = new problem(p1, p2);
from the header with the class declaration:
public:
problem(obj *, obj *);
problem(obj *, obj *, char *);
private:
char data[6][7];
Are you sure that your file always contains at least six lines?
The usual way to "iterate" on a ifstream is:
ifstream is("test.txt");
string line;
while(getline(is, line))
{
cout<<line<<endl;
}
I figured it out. The problem had something to do with how the object file was being linked during the build process. Removing all the .o files and rebuilding from scratch solved the problem. Thank you everyone for your input. I apologize for not doing a clean build from the beginning and wasting your time.