C++ Read txt and put each line into Dynamic Array - c++

I am trying to read input.txt file, and trying to put each line into the array as string (later on I will use each element of array in initializing obj that's why I am putting each line into the array).
string* ptr = new string;
// Read Mode for Input
fstream input;
input.open("input.txt", ios::in);
int size = 0;
if (input.is_open()) {
string line;
while (getline(input, line)) {
cout << line << endl;
ptr[size] = line;
size++;
}
input.close();
}
for (int i = 0; i < size-1; i++) {
cout << "array: " << ptr[i] << endl;
}
I am getting error as:
Proxy Allocated, drain it

Don't use arrays; use std::vector. The std::vector behaves like an array and uses Dynamic Memory:
std::string s;
std::vector<std::string> database;
while (std::getline(input, s))
{
database.push_back(s);
}
Keep it simple. :-)

As was noted in the comments, if you don't know how many lines in the file then you need a container which grows on request at runtime. The natural choice is std::vector :
std::fstream input("input.txt", std::ios::in);
std::vector<std::string> lines;
std::string line;
while (getline(input, line)) {
lines.push_back(line); // std::vector allocates more memory if needed
}
for (int i = 0; i < lines.size(); i++) {
std::cout << lines[i] << std::endl;
}

Related

c++ nested while loop runs only once

Please can you advise, why the inner loop runs only once?
I'd like to add suffix to each line of input file and then store the result in output file.
thanks
For example:
Input file contains:
AA
AB
AC
Suffix file contains:
_1
_2
Output file should contain:
AA_1
AB_1
AC_1
AA_2
AB_2
AC_2
My result is :
AA_1
AB_1
AC_1
Code:
int main()
{
string line_in{};
string line_suf{};
string line_out{};
ifstream inFile{};
ofstream outFile{"outfile.txt"};
ifstream suffix{};
inFile.open("combined_test.txt");
suffix.open("suffixes.txt");
if (!inFile.is_open() && !suffix.is_open()) {
perror("Error open");
exit(EXIT_FAILURE);
}
while (getline(suffix, line_suf)) {
while (getline(inFile, line_in))
{
line_out = line_in + line_suf;
outFile << line_out << endl;
}
inFile.close();
outFile.close();
}
}
IMHO, a better method is to read the files into vectors, then iterate through the vectors:
std::ifstream word_base_file("combined_test.txt");
std::ifstream suffix_file("suffixes.txt");
//...
std::vector<string> words;
std::vector<string> suffixes;
std::string text;
while (std::getline(word_base_file, text))
{
words.push_back(text);
}
while (std::getline(suffix_file, text))
{
suffixes.push_back(text);
}
//...
const unsigned int quantity_words(words.size());
const unsigned int quantity_suffixes(suffixes.size());
for (unsigned int i = 0u; i < quantity_words; ++i)
{
for (unsigned int j = 0; j < quantity_suffixes; ++j)
{
std::cout << words[i] << suffix[j] << "\n";
}
}
Edit 1: no vectors
If you haven't learned about vectors or like to thrash your storage device you could try this:
std::string word_base;
while (std::getline(inFile, word_base))
{
std::string suffix_text;
while (std::getline(suffixes, suffix_text))
{
std::cout << word_base << suffix_text << "\n";
}
suffixes.clear(); // Clear the EOF condition
suffixes.seekg(0); // Seek to the start of the file (rewind).
}
Remember, after the inner while loop, the suffixes file is at the end; no more reads can occur. Thus the file needs to be positioned at the start before reading. Also, the EOF state needs to be cleared before reading.

Adding words from a text file to a vector c++

I am trying to add each word from a file to a vector but if I make the size of the vector (500) and I only have 20 words in the file. The size of the vector is still considered 500. How do I fix this?
Am I doing this a bad way? Could this be made simpler?
void loadFile(string fileName)
{
vector<string> fileContents(500);
int p = 0;
ifstream file;
file.open(fileName);
if (!file.is_open()) return;
string word;
while (file >> word)
{
fileContents[p] = word;
p++;
}
for (int i = 0; i < fileContents.size(); i++)
{
cout << fileContents[i] << endl;
}
}
You could also use a more direct approach, copying immediately from the input stream.
std::vector<std::string> loadFile(std::string fileName) {
std::ifstream file(fileName);
assert(file);
std::vector<std::string> fileContents;
std::copy(std::istream_iterator<std::string>(file),
std::istream_iterator<std::string>(),
std::back_inserter(fileContents));
return fileContents;
}
#drescherjm in the comments gave me the correct answer.
void loadFile(string fileName)
{
vector<string> fileContents;
ifstream file;
file.open(fileName);
if (!file.is_open()) return;
string word;
while (file >> word)
{
fileContents.push_back(word);
}
for (int i = 0; i < fileContents.size(); i++)
{
cout << fileContents[i] << endl;
}
}

Trouble with pointers and reading information into an array

I'm having some issues when trying to read in some values to a dynamically allocated array. Everything looks okay to me, but when the code is run, only the last entry into the array is shown. The code is below. If you could give me some recommendations I would appreciate it.
ifstream infile;
infile.open("MovieStatistics.txt");
int numOfStudents = 0;
string first, last, line;
int movies;
int *numMovies = nullptr;
string *names = nullptr;
if (!infile) {
cout << "Error opening file";
} else {
while (getline(infile, line)) {
numOfStudents++;
stringstream ss(line);
ss >> first >> last >> movies;
}
numMovies = new int[numOfStudents];
names = new string[numOfStudents];
}
for (int i = 0; i < numOfStudents; i++) {
names[i] = first + " " + last;
numMovies[i] = movies;
}
Your problem is you assign first and last inside the read loop but you don't store the values in an array or vector so they contain the last values.
To get it to work you could edit the code to:
ifstream infile;
infile.open("data.txt");
int numOfStudents = 0;
string first, last, line;
int movies;
int *numMovies = nullptr;
string *names = nullptr;
// get the number of students
while (getline(infile, line))
numOfStudents++;
numMovies = new int[numOfStudents];
names = new string[numOfStudents];
// clear the buffer
infile.clear();
infile.seekg(0, ios::beg);
int i = 0;
while(getline(infile, line)){
stringstream ss(line);
ss >> first >> last >> movies;
names[i] = first + " " + last;
numMovies[i] = movies;
++i;
}
for(int i = 0; i < numOfStudents; i++)
cout << names[i] << endl;
// don't forget to free memory:
delete[] movies;
delete[] names;
infile.close();
What I recommend is to use class vector:
std::ifstream infile("data.txt");
std::string sLine;
std::vector<std::string> vecNames;
while(getline(infile, sLine))
vecNames.push_back(sLine);
auto size = vecNames.size();
//for(auto x : vecNames)
// std::cout << x << std::endl;
for(int i(0); i != size; ++i)
std::cout << vecNames[i] << std::endl;
infile.close();
So you loop over the file, repeatedly reading data into first, last and movies — overwriting the previous values each time.
Much later, you take the current value of those variables, and write it to your dynamic arrays numOfStudents times.
You probably want to rewind the stream and loop over the file again so that you can pull out all the data; you never actually stored each sample the first time around.

How do I get an input file to read into a string array in C++?

For some reason the full lines from my input file are not reading into the array, only the first word in each line. I am currently using the getline call, but I am not sure why it is not working. Here is the what I have for the call to populate the array. The txt file is a list of songs.
const int numTracks = 25;
string tracks[numTracks];
int count = 0, results;
string track, END;
cout << "Reading SetList.txt into array" << endl;
ifstream inputFile;
inputFile.open("SetList.txt");
while (count < numTracks && inputFile >> tracks[count])
{
count++;
getline(inputFile, track);
}
inputFile.close();
while (count < numTracks && inputFile >> tracks[count])
The >> operator reads a single word. And this code reads this single word into the vector in question.
getline(inputFile, track);
True, you're using getline(). To read the rest of the line, after the initial word, into some unrelated variable called track. track appears to be a very bored std::string that, apparently, gets overwritten on every iteration of the loop, and is otherwise completely ignored.
Your loop is using the operator>> to read the file into the array. That operator reads one word at a time. You need to remove that operator completely and use std::getline() to fill the array, eg:
const int numTracks = 25;
std::string tracks[numTracks];
int count = 0;
std::cout << "Reading SetList.txt into array" << std::endl;
std::ifstream inputFile;
inputFile.open("SetList.txt");
while (count < numTracks)
{
if (!std::getline(inputFile, tracks[count])) break;
count++;
}
inputFile.close();
Or:
const int numTracks = 25;
std::string tracks[numTracks];
int count = 0;
std::cout << "Reading SetList.txt into array" << std::endl;
std::ifstream inputFile;
inputFile.open("SetList.txt");
while ((count < numTracks) && (std::getline(inputFile, tracks[count]))
{
count++;
}
inputFile.close();
Alternatively, consider using a std::vector instead of a fixed array, then you can use std::istream_iterator and std::back_inserter to get rid of the manual loop completely:
class line : public std::string {}
std::istream& operator>>(std::istream &is, line &l)
{
return std::getline(is, l);
}
...
std::vector<std::string> tracks;
std::cout << "Reading SetList.txt into array" << std::endl;
std::ifstream inputFile;
inputFile.open("SetList.txt");
std::copy(
std::istream_iterator<line>(inputFile),
std::istream_iterator<line>(),
std::back_inserter(tracks)
);
inputFile.close();

c++ initializing array storage size

void start ( string fname )
{
string FirstElement;
int count = 0 ;
fstream Infile;
Infile.open( fname.c_str(), ios::in ); // Open the input file
while(!Infile.eof()) // using while to look for the total lines
{
count++;
}
//read to the array
string data_array[]; //initializing an array
for(int i=0; !Infile.eof(); i++){
Infile >> data_array[i]; // storing the value read from file to array
}
//Display the array
// for(int i=1; i<11; i++){
// cout << data_array[i] << endl;
//}
cout << data_array[0] << endl;
cout << count << endl;
return;
}
I have a text files contain values lines by lines
My plan was to use the while loop to do a total count of the lines
and place it in the "string data_array[]" but somehow it doesnt work that way.
anyone can advise me on how can I make it in a way that It can have a flexible storage size going according to the numbers of values in the text files? thanks
For flexible storage as you call it, you may use STL's container, such as std::vector<T> or std::list<T>. Other issues are highlighted in inline comments.
// pass by reference
void start(const std::string& fname)
{
// use std::ifstream, instead of std::fstream(..., std::ios::in);
std::ifstream Infile(fname.c_str());
// prefer std::vector to raw array
std::vector<std::string> data_array;
std::string line;
// read line by line
while (std::getline(Infile, line))
{
data_array.push_back(line); // store each line
}
// print out size
std::cout << data_array.size() << std::endl;
// display the array, note: indexing starts from 0 not 1 !
for(int i = 0; i < data_array.size(); ++i)
{
std::cout << data_array[i] << std::endl;
}
}