Store text lines from a file into a char array

I'm trying to modify this function so it will read lines of text from the file that the user is prompted to enter and store that line into the buffer array so can be copied into my text array. I have tried for hours trying to find a way to get this to work with no luck. The function and program work great otherwise. Any help would be greatly appreciated, I'm still fairly new to C++ programming.

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

struct text
{
	char* word{ nullptr };
};



 void FillArray(text*& ray, int& count)
{
	string filename;
	ifstream inFile;

	cout << "If the executable is not in the same directory as the\nfile, then a directory needs to be provided\n\n";

	cout << "Enter the file name:  ";
	getline(cin, filename);

	char buffer[256] = "";

	string line;
	ifstream myfile(filename);
	if (myfile.is_open())
	{

		while (!myfile.eof())
		{
			getline(myfile, line);
			count++;
		}
			
		ray = new text[count];

		for (int i = 0; i < count; ++i)
		{
			cout << "Please enter the Faculty's name: ";// Want this to get this line from the file instead of the user input.
				
			cin.getline(buffer, 255);
			ray[i].word = new char[strlen(buffer) + 1];
			strcpy(ray[i].word, buffer);
		}

		myfile.close();

		}
	else cout << "can't open the file";
	system("PAUSE");

}
Hello ejulien18,

First it really helps to post a full program that can be compiled and run.

Second if the program uses an input file include that with your post. Or at least a good sample including any part of the file that is a problem. It helps everyone to be able to use the same information and not have to guess at it.

My first question is the character pointer and array that you create required for the assignment? Or is this just something that you have used before?

You have used "new" to create an array, but you did not use "delete" to free the memory when you are finished. This leaves you with a memory leak.

Although it works putting the progam in an if/else statement it really is bad form and might limit what you can do.

When dealing with an input file I like to use this:
1
2
3
4
5
6
7
8
9
10
11
const std::string inFileName{ "" };  // <--- Put File name here.

std::ifstream inFile(inFileName);

if (!inFile)
{
    std::cout << "\n File " << std::quoted(inFileName) << " did not open." << std::endl;
    //std::cout << "\n File \"" << inFileName << "\" did not open." << std::endl;

    return 1;
}

This way if the stream is not open and usable you leave the program to fix the problem. Also if the file does not open there is no reason to continue with the program. This will also eliminate the need for the if/else statements.

The while loop on line 26 does not work the way that you are thinking it does. By the time the while condition becomes false you will have processed that you could not read.

On line 38 you need to use 256 as the "getline" will take up to 255 or (256 - 1) leaving the last element of the array for the (\0) to terminate the string. Here you are cutting your-self 1 short of what you could store in the array.

Something does not look right with line 40, but I am not sure what that is yet.

Andy
Sorry, I couldn't get any help anywhere posting the entire program. It was apparently a bother to deal with for some.

I don't need to to do it this way, it is just the way I was able to make progress. My assignment is to create a hex dump utility that prompts the user for the filename and then display the hexadecimal values as well as the translated ASCII characters.

I know I have problems with my code and my approach. I have just been really struggling with pointers and dynamic arrays, but I am very passionate to learn and expand my programming knowledge.

Here is my code:

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#define _CRT_SECURE_NO_WARNINGS
#include <fstream>
#include <iostream>
#include <string>
using std::ios;
using std::ifstream;
using std::cout;
using std::endl;
using std::string;
using std::cin;
using std::ofstream;
using namespace std;

struct text
{
	char* word{ nullptr };
};

void FillArray(text*& ray, int& count)
{
	string filename;
	ifstream inFile;

	cout << "If the executable is not in the same directory as the\nfile, then a directory needs to be provided\n\n";

	cout << "Enter the file name:  ";
	getline(cin, filename);

	char buffer[256] = "";

	string line;
	ifstream myfile(filename);
	if (myfile.is_open())
	{

		while (!myfile.eof())
		{
			getline(myfile, line);
			count++;
		}

		ray = new text[count];

		for (int i = 0; i < count; ++i)
		{
			cout << "Please enter the Faculty's name: ";


			cin.getline(buffer, 255);
			ray[i].word = new char[strlen(buffer) + 1];
			strcpy(ray[i].word, buffer);
		}

		myfile.close();

	}
	else cout << "can't open the file";
	system("PAUSE");

}

void WriteArrayToFile(text* ray, int num_faculty)
{
	ofstream fout("Output.bin", ios::out | ios::binary);

	if (fout.is_open())
	{
		int str_length = 0;

		// Write the size of the dynamic array first
		fout.write(reinterpret_cast<char*>(&num_faculty), sizeof(num_faculty));

		// Now we need a for loop to write out each peice of the array
		for (int i = 0; i < num_faculty; i++)
		{
			// Get length of name including '\0'
			str_length = strlen(ray[i].word) + 1;

			// Write out length of word
			fout.write(reinterpret_cast<char*>(&str_length), sizeof(str_length));

			// Write out the word string 
			fout.write(ray[i].word, str_length);

			// Write out length of department
			fout.write(reinterpret_cast<char*>(&str_length), sizeof(str_length));

		}

		fout.close();
	}
	else
	{
		cout << "Could not open file for writing." << endl;
	}
}

void DeleteArray(text*& ray, int& num_words)
{
	for (int i = 0; i < num_words; ++i)
	{
		delete[] ray[i].word;
	}

	delete[] ray;
	ray = nullptr;
	num_words = 0;
}

int main()
{
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

	text* cse = nullptr;
	string* test = nullptr;
	int num_words = 0;

	FillArray(cse, num_words);

	WriteArrayToFile(cse, num_words);
	DeleteArray(cse, num_words);

	return 0;
}


An input file could be something like this:

1
2
3
4
This
is my
input
file


Thanks for a detailed reply. I could use any help I could get.
Why this mix with C and C++?
This task would be a breeze with std::string and std::vector.
Maybe something like this??

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#define _CRT_SECURE_NO_WARNINGS
#include <fstream>
#include <iostream>
#include <string>

using std::ios;
using std::ifstream;
using std::cout;
using std::string;
using std::cin;
using std::ofstream;

struct text
{
	char* word {};
};

size_t FillArray(text*& ray)
{
	string filename;
	size_t count {};

	cout << "If the executable is not in the same directory as the\nfile, then a directory needs to be provided\n\n";

	cout << "Enter the file name:  ";
	getline(cin, filename);

	ifstream myfile(filename);

	if (myfile) {
		for (string line; getline(myfile, line); ++count);

		myfile.clear();
		myfile.seekg(0);
		cout << "count " << count << '\n';

		ray = new text[count];

		for (size_t i = 0; i < count; ++i) {
			string line;

			getline(myfile, line);
			cout << line << '\n';
			ray[i].word = strcpy(new char[line.size() + 1], line.c_str());
		}
	} else
		cout << "can't open the file";

	return count;
}

void WriteArrayToFile(const text* ray, size_t num_faculty)
{
	ofstream fout("Output.bin", ios::binary);

	if (fout) {
		// Write the size of the dynamic array first
		fout.write(reinterpret_cast<char*>(&num_faculty), sizeof(num_faculty));

		// Now we need a for loop to write out each piece of the array
		for (size_t i = 0; i < num_faculty; ++i) {
			// Get length of name including '\0'
			size_t str_length {strlen(ray[i].word) + 1};

			// Write out length of word
			fout.write(reinterpret_cast<char*>(&str_length), sizeof(str_length));

			// Write out the word string
			fout.write(ray[i].word, str_length);

			// Write out length of department
			// THIS IS THE SAME AS WRITE LENGTH OF WORD ???
			//fout.write(reinterpret_cast<char*>(&str_length), sizeof(str_length));
		}
	} else
		cout << "Could not open file for writing.\n";
}

void DeleteArray(text*& ray, size_t& num_words)
{
	for (size_t i = 0; i < num_words; ++i)
		delete[] ray[i].word;

	delete[] ray;

	ray = nullptr;
	num_words = 0;
}

int main()
{
	//_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

	text* cse {};
	size_t num_words {FillArray(cse)};

	WriteArrayToFile(cse, num_words);
	DeleteArray(cse, num_words);

	return 0;
}


Which for the given input file, creates the output file as (in hex):


04 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 54 68 69 73 00 06 00 00 00 00 00 00 00 69 73 20 6D 79 00 06 00 00 00 00 00 00 00 69 6E 70 75 74 00 05 00 00 00 00 00 00 00 66 69 6C 65 00


Last edited on
Exactly what I needed. Thanks seeplus!
Topic archived. No new replies allowed.