Array/File Functions

Write a function named arrayToFile . The function should accept three arguments: the name of a file, a pointer to an int array, and the size of the array. The function should open the specified file in binary mode, write the contents of the array to the file, and then close the file.

Write another function named fileToArray . This function should accept three arguments: the name of a file, a pointer to an int array, and the size of the array. The function should open the specified file in binary mode, read its contents into the array, and then close the file.

Need help please..


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 void arraytofile(string str, int *ptr, int size)
{
	fstream file;
	file.open("str", ios::out | ios::binary);
	if(file.fail())
	{
		cout<<"file opening failed"<<endl;
	}
	
	file.clear();
	file.seekg(0);
	for(int i=0; i<size; i++)
	{
		file.write(reinterpret_cast<char *>(ptr[i]), sizeof(ptr));
	}
	
	file.close();
}

void filetoarray(string str, int *ptr, int size)
{
	fstream file;
	file.open("str", ios::in | ios::binary);
	if(file.fail())
	{
		cout<<"file is not opened"<<endl;
	}
	
	for(int i=0; i<size; i++)
	{
		file.read(reinterpret_cast<char *>(ptr), sizeof(ptr));
	}
	file.close();
}


int main()
{
	int size=5;
	int array[size]= {'1','2','3','4','5'};
	int *intptr=NULL;
	intptr=array;
	string str;
	cout<<"enter the name of the file"<<endl;
	cin>>str;
	
	arraytofile(str, intptr, size);
	
	cout<<"data is written into file"<<endl;
	
	int array2[size];
	int *secptr=NULL;
	secptr=array2;
	
	filetoarray(str, secptr, size);
	cout<<"data is in array"<<endl;
}
file.open(str, ios::out | ios::binary);

No quotes surrounding the file name string, you are trying to open a file named "str"
You didn't say what problems you were having, but after adding the appropriate header files and some whitespace to make reading easier I was able to figure out what was going wrong.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <fstream>
#include <string>
#include <iostream>

void arraytofile(std::string str, char* ptr, int size)
{
   std::fstream file(str, std::ios::out | std::ios::binary);

   if (!file.is_open())
   {
      std::cout << "file opening failed!!!!\n";

      // if the file failed to open do NOT continue trying to use it!
      return;
   }

   for (int loop { }; loop < size; loop++)
   {
      file.write(reinterpret_cast<char*>(&ptr[loop]), sizeof(char));
   }
}

void filetoarray(std::string str, char* ptr, int size)
{
   std::fstream file(str, std::ios::in | std::ios::binary);

   if (!file.is_open())
   {
      std::cout << "file is not opened!!!!!\n";
      return;
   }

   for (int loop { }; loop < size; loop++)
   {
      file.read(reinterpret_cast<char*>(&ptr[loop]), sizeof(char));
   }
}


int main()
{
   const int size = 5;

   char array[size] = { '1','2','3','4','5' };
   char* intptr = array;

   std::string str;

   std::cout << "enter the name of the file: ";
   std::cin >> str;
   std::cout << '\n';


   std::cout << "data is written to the file\n\n";
   arraytofile(str, intptr, size);

   char array2[size];
   char* secptr = array2;

   filetoarray(str, secptr, size);

   std::cout << "Data in the file:\n";

   for (int loop { }; loop < size; loop++)
   {
      std::cout << secptr[loop] << ' ';
   }
   std::cout << '\n';
}

enter the name of the file: test.txt

data is written to the file

Data in the file:
1 2 3 4 5

You mixed up using your arrays as if it an array of ints and an array of chars. Since you initialized the first array with char values every usage of it became a char array or char* pointer.

Using binary format for simple data types is a bit of overkill. It works best with complex data types, for example a class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <fstream>
#include <iomanip>
#include <string>
#include <iostream>

class Human
{
public:
   Human() : Name(""), DOB(""), Age(0) { }
   Human(std::string inName, std::string inDOB, unsigned short inAge)
      : Name(inName), DOB(inDOB), Age(inAge) { }

public:
   std::string    Name;
   std::string    DOB;
   unsigned short Age;
};


int main()
{
   Human Input("Joe Schmuckatelli", "May 1956", 61);

   std::ofstream fsOut("MyBinary.txt", std::ios_base::out | std::ios_base::binary);

   if (!fsOut.is_open())
   {
      std::cout << "Unable to open file for writing!!!!!\n";
   }
   else
   {
      std::cout << "Writing one object of Human to a binary file\n\n";
      fsOut.write(reinterpret_cast<const char*> (&Input), sizeof(Input));
      fsOut.close();

      std::ifstream fsIn("MyBinary.txt", std::ios_base::in | std::ios_base::binary);

      if (!fsIn.is_open())
      {
         std::cout << "Unable to open file for reading!!!!!\n";
      }
      else
      {
         Human somePerson;
         fsIn.read(reinterpret_cast<char*> (&somePerson), sizeof(somePerson));
         fsIn.close();

         std::cout << "Reading information from binary file:\n";
         std::cout << "Name = " << somePerson.Name << '\n';
         std::cout << "Age  = " << somePerson.Age << '\n';
         std::cout << "DOB  = " << somePerson.DOB << '\n';
      }
   }
}

Writing one object of Human to a binary file

Reading information from binary file:
Name = Joe Schmuckatelli
Age  = 61
DOB  = May 1956
Thank you so much Furry,
You are really master of C++.
it is working well.


I didn't get one thing, why you used char *ptr ... in both functions instead of using int * ptr.
why you used char *ptr ... in both functions instead of using int * ptr.
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

int main()
{
   // not what you think it is.  '1' = 49!
   int myInt = '1';

   char myChar = '1';

   std::cout << myInt << '\t' << myChar << '\n';
}
49      1


You are really master of C++.

HA-HA-HA-HA-HA-HA! Great joke, there.

Oh, you were serious?

Not even close, really. There are others here who are much better at making C++ dance. I can barely make it shuffle around like a zombie.
HA-HA-HA-HA-HA-HA! Great joke, there.

Oh, you were serious?



Yes, you quite expert. Thank you so much.
If you absolutely must pass your array(s) as int*:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <fstream>
#include <string>
#include <iostream>

void arraytofile(std::string str, int* ptr, int size)
{
   std::fstream file(str, std::ios::out | std::ios::binary);

   if (!file.is_open())
   {
      std::cout << "file opening failed!!!!\n";

      // if the file failed to open do NOT continue trying to use it!
      return;
   }

   for (int loop { }; loop < size; loop++)
   {
      // notice you are taking the size of the actual data type being written
      // otherwise the alignment is all FUBARed
      file.write(reinterpret_cast<char*>(&ptr[loop]), sizeof(int));  
   }
}

void filetoarray(std::string str, int* ptr, int size)
{
   std::fstream file(str, std::ios::in | std::ios::binary);

   if (!file.is_open())
   {
      std::cout << "file is not opened!!!!!\n";
      return;
   }

   for (int loop { }; loop < size; loop++)
   {
      file.read(reinterpret_cast<char*>(&ptr[loop]), sizeof(int));
   }
}


int main()
{
   const int size = 5;

   int array[size] = { 1, 2, 3, 4, 5 };  // initialize with ints, not chars.
   int* intptr = array;

   std::string str;

   std::cout << "enter the name of the file: ";
   std::cin >> str;
   std::cout << '\n';


   std::cout << "data is written to the file\n\n";
   arraytofile(str, intptr, size);

   int array2[size];
   int* secptr = array2;

   filetoarray(str, secptr, size);

   std::cout << "Data in the file:\n";

   for (int loop { }; loop < size; loop++)
   {
      std::cout << secptr[loop] << ' ';
   }
   std::cout << '\n';
}
Furry Guy wrote:
It works best with complex data types, for example a class:

That actually crashed.

Are you sure that sizeof(somePerson) is legitimate when it contains strings that may be of arbitrary length?
Alright, I got i.

Are you sure that sizeof(somePerson) is legitimate when it contains strings that may be of arbitrary length?


Actually you are right.
sizeof gives actual size of any type of data in bytes whereas get the length of an array of chars/string. It doesn't care about the value of the variable.
Are you sure that sizeof(somePerson) is legitimate when it contains strings that may be of arbitrary length?


VS 2017/2019 and LLVM/GCC (Code::Blocks) don't have problems, exit code 0.

What compiler did you use that has problems?
I used g++.

However, I can't see how it would know how many bytes to read without knowing the length of the strings.
The example code I posted seems to be a "one-off" weird bit of code, that "just worked."

It was a pre-C++11 bit of code.

I was wondering how it was able to process the length of strings back when I first saw the code.

But it worked across multiple compilers, even changing what the strings held so dealt with difference sizes and padding alignments.

It never had problems when I did limited testing, so figured there was some C+++ FM going on I didn't understand.

Other binary file examples I saw use char arrays with fixed sizes, easy to understand why that works.

It has been a while since I looked at that code sample and when I resurrected it the fact it worked fooled me into being complacent. And stupid.

@shoaib yehya,

Still think I'm a master of C++? I told you I wasn't.
It may be that strings start with a minimum capacity (probably different on different systems) and as long as you don't exceed that then things would be "fine".
I did some further testing, and even without changing any of the string data in the class, a recompile with VS and C:B can crash.

Change any of the string data and it is a hit and miss "fall down and go boom" situation.

Most of the times crash, but sometimes it doesn't.

I made a simple, easily preventable, noob mistake; assumed a few test cases that worked meant it was code without problems.

Mea Culpa. And all that jazz.

Learned a couple of lessons today.

I know they won't be the last.
Last edited on
Still think I'm a master of C++? I told you I wasn't.


Atleast you are doing better than me.

secondly, what if we use strlen/strin.lenght() function for that ??
It will include NUllpointer as well.
What compiler did you use that has problems?


using old version,
Dev c++.
strlen() does not include the null-terminator, but requires a null-terminator to know when to stop looping.
e.g. { 'h', 'e', 'l', 'l', 'o', '\0' } --> will return 5.

string.length() is not null-terminated (e.g. you can push_back a null character and the length will be incremented).
strlen() does not include the null-terminator, but requires a null-terminator to know when to stop looping.
e.g. { 'h', 'e', 'l', 'l', 'o', '\0' } --> will return 5.



Alright thanks Ganado
Topic archived. No new replies allowed.