Reading a text file into an array of integers - c++

Given a file with some empty lines, some lines containing only integers, how would I make an array containing all of the integers? I have found methods for strings, but I need a list of integers. I want to do this using getline, but getline gives a string for "line"
A nonfunctioning example which returns the number of integers in the file and modifies a given array:
int getLinesFromFile(string fileName, int arr[], int arrLen) {
ifstream userFile;
userFile.open(fileName);
if (userFile.is_open()) {
int line;
int arrCount = 0;
while (getline(userFile, line)) {
if (tline.length() != 0 && arrCount < arrLen) {
arr[arrCount] = line;
arrCount++;
}
}
return arrCount;
}
else {
return -1;
}
userFile.close();
}

You can just use the >>-operator to read values. It will ignore any whitespace, including empty lines, between values. Here is a modified version of your function that uses it:
int getLinesFromFile(std::string fileName, int arr[], int arrLen) {
std::ifstream userFile(fileName);
int count = 0;
while(count < arrLen) {
int value;
userFile >> value;
if (!userFile.good())
return -1;
arr[count++] = value;
}
return count;
}
Note that you don't need to open and close the file manually, RAII will take care of that for you. Also, if the file could not be opened successfully, or if any other error occured while reading the file, userFile.good() will return false, so you can use that to detect and return an error. It's unclear if your function is supposed to read exactly arrLen values or if less is also valid. But at least you should take care not to write past the end of the provided array.

Related

I have a text file with each line containing an integer. I want to open the text tile and count the number of integers in the file

void DataHousing::FileOpen() {
int count = 0;
// attempt to open the file with read permission
ifstream inputHandle("NumFile500.txt", ios::in);
if (inputHandle.is_open() == true) {
while (!inputHandle.eof()) {
count++;
}
inputHandle.close();
}
else {
cout << "error";
}
cout << count;
}
This is getting stuck in the while loop. But shouldn't the while loop end when it gets to the end of file? Also, I'm not even sure yet if it is counting correctly.
A fairly easy way to do this would be to use std::cin instead. Assuming that you want to count the number of integers in a file you can just use a while loop like so:
int readInt;
int count = 0;
while(std::cin >> readInt){
count++;
}
Then you just pass in the file as an argument parameter to your executable as so:
exec < filename
If you prefer to go through the route you're going then you can just replace your while loop condition with !inputHandle.eof() && std::getline(inputHandle, someStringHere) Then proceed to check if someStringHere is an int and increment your count if it is like so:
int count = 0;
std::string s;
ifstream inputHandle("NumFile500.txt", ios::in);
if (inputHandle.is_open() == true) {
while (!inputHandle.eof() && std::getline(inputHandle, s)) {
if(check to see if it's a number here)
count++;
}
inputHandle.close();
}

Txt to 2 different arrays c++

I have a txt file with a lot of things in it.
The lines have this pattern: 6 spaces then 1 int, 1 space, then a string.
Also, the 1st line has the amount of lines that the txt has.
I want to put the integers in an array of ints and the string on an array of strings.
I can read it and put it into an array , but only if I'm considering the ints as chars and putting into one array of strings.When I try to separate things I have no idea on how I'd do it. Any ideas?
The code I used for putting everything in an array was this:
int size()
{
ifstream sizeX;
int x;
sizeX.open("cities.txt");
sizeX>>x;
return x;
};
int main(void)
{
int size = size();
string words[size];
ifstream file("cities.txt");
file.ignore(100000,'\n');
if(file.is_open())
{
for(int i=0; i<size; i++)
{
getline(file,words[i]);
}
}
}
Just to start I'm going to provide some tips about your code:
int size = size();
Why do you need to open the file, read the first line and then close it? That process can be done opening the file just once.
The code string words[size]; is absolutely not legal C++. You cannot instantiate a variable-length-array in C++. That C feature has been not included in C++ standard (some ref). I suggest you to replace with std::vector, which is more C++ code.
Here I write a snippet of function which perform what you need.
int parse_file(const std::string& filename,
std::vector<std::string>* out_strings,
std::vector<int>* out_integers) {
assert(out_strings != nullptr);
assert(out_integers != nullptr);
std::ifstream file;
file.open(filename, std::ios_base::in);
if (file.fail()) {
// handle the error
return -1;
}
// Local variables
int num_rows;
std::string line;
// parse the first line
std::getline(file, line);
if (line.size() == 0) {
// file empty, handle the error
return -1;
}
num_rows = std::stoi(line);
// reserve memory
out_strings->clear();
out_strings->reserve(num_rows);
out_integers->clear();
out_integers->reserve(num_rows);
for (int row = 0; row < num_rows; ++row) {
// read the line
std::getline(file, line);
if (line.size() == 0) {
// unexpected end of line, handle it
return -1;
}
// get the integer
out_integers->push_back(
std::stoi(line.substr(6, line.find(' ', 6) - 6)));
// get the string
out_strings->push_back(
line.substr(line.find(' ', 6) + 1, std::string::npos));
}
file.close();
return 0;
}
You can definitely improved it, but I think it's a good point where to start.
The last suggest I can give you, in order to improve the robustness of your code, you can match each line with a regular expression. In this way you can be sure your line is formatted exactly how you need.
For example:
std::regex line_pattern("\\s{6}[0-9]+\\s[^\\n]+");
if (std::regex_match(line, line_pattern) == false) {
// ups... the line is not formatted how you need
// this is an error
}

C++, reading chars into a vector<char> from a file, character by character

I am trying to read in the first 7 chars of a file named "board.txt" into a vector<'char> but I am having issues for some reason. I am not too familiar with C++ so any advice would be appreciated, here is the code I have so far
//rack
int charCount = 0;
char ch;
ifstream rackIn("board.txt");
while(rackIn.get(ch) && charCount < 7){
this->getMyRack().push_back(ch);
}
And here is the function getMyRack used in the code above:
vector<char> board::getMyRack(){
return this->myRack;
}
myRack is a char vector
I tried to test this in my main using this:
for (int i = 0; i < test->getMyRack().size(); ++i){
cout << test->getMyRack().at(i);
}
but it does not output anything, why are the chars i am reading in not being added into my char vectors?
Because you don't put char in your vector. Your function getMyRack() returns vector but not address of your vector. You can add method to your class board for adding char, for example:
void board::addChar(char c){
this->myRack.push_back(c);
}
And then call this function:
while(rackIn.get(ch) && charCount < 7){
this->addChar(ch);
}
Or change the return type of your function.
read line one or (how much lines required) from file to a string
create substring of 7 chars from beginning
std::ifstream file("board.txt");
std::string str;
// to read single line
std::getline(file, str);
// to read 7 chars
str= str.substr(0,7);
vector<char> char_buf;
for(size_t i =0; i <= str.size();i++)
{
char_buf.push_back(str[i])
}
// use the char_buf
easier or second way is use
#include<fstream> // for ifstream
#include <cstdlib> // for exit()
std::string file_name ="board.txt";
std::ifstream input_stream;
std::vector<char> char_buf;
input_stream.open(file_name);
if(input_stream.fail()) { exit(0);}
int char_no=0;
while(i<=7)
{
char c = input_stream.get();
char_buf.push_back(c);
i++;
}
// use char_buf
std::string str;
int char_count=0;
// Read the next line from File untill it reaches the 7.
while (std::getline(in, str)&& char_count!=7)
{
// Line contains string of length > 0 then save it in vector
if (str.size() > 0)
your_char_vector.push_back(str);
char_count++;
if(char_count==7)
break;
}

ifstream wont read all integer

When i read TestData.txt file it gives me wrong output. What am i doing wrong. I am using int array so i can do MergeSort after saving data into array.
TestData.txt
-------------------
31791 564974 477059 269094 972335
739154 206345 634644 227684 398536
910177 507975 589785 67117 395140
598829 372499 364165 450187 996527
700285 263407 918021 661467 457544
656297 846316 221731 240676 68287
913 141702 845802 477617 109824
{
int myArray[1000];
int i;
//reading givin data
const char* filename= "TestData.txt";
ifstream file(filename);
if(file.is_open())
{
for(i = 0; i <=999; ++i)
{
file >> myArray[i];//storing data to array
}
}
Need to check if you ifstream is end of file, in that case you get garbage value from out of the file bound.
With One modification, the code would be OK.
Change:
for(i = 0; i <=999; ++i)
to:
for(i = 0; i <=999 && !file.eof(); ++i)
You are reading 1000 enties from your file which contains clearly less than 1000 integers.
The first values of your array must be correct, but after you reach the end of your file the operator>> will not ready anything.
For example here is one way to write it:
const char* filename= "TestData.txt";
std::vector<int> myArray;
std::ifstream file(filename);
if(file.is_open())
{
int v;
while(file >> v) {
myArray.push_back(v);
}
}
int if I'm not wrong can keep data from -32768 to 32767.
So if u have bigger values than that (which you have, from your source file), you won't have the results you are expecting.
btw, it would be nice to know also what output you are getting.

Getting weird number when trying to read a number from file

I'm trying to read a number from a text file, and I'm not allowed to use a binary file.
I've tried two methods to do this, and both return a strange result.
The first method:
char *theNumber;
int i = 0;
while(data>>text)
{
theNumber[i] = text;
i++;
}
returns some weird accented characters.
The second
int theNumber;
while(data>>text)
{
theNumber = text; // I tried theNumber<<text; as well
}
When I cout the result of this one it returns some big number when the text file contained 123.
string filename;
char text;
int p; //first prime number
int q; //second prime number
unsigned long long toBeEncrypted;
cout<<"Enter name of file to encrypt: ";
cin>>filename;
ifstream data;
ofstream encryptedData;
encryptedData.open("RSA_cipher.txt");
cout<<"Please enter two prime numbers:"<<endl;
p = getPrime(1);
q = getPrime(2);
//doing stuff with file
int theNumber;
data >> theNumber;
//int i = 0;
/*while(data>>text)
{
theNumber[i] = text;
i++;
}*/cout<<theNumber;
...//other stuff unrelated to the problem
This code:
char *theNumber;
int i = 0;
while(data>>text)
{
theNumber[i] = text;
i++;
}
Has Undefined Behavior, because you are using theNumber[i] to access an array which you haven't even allocated. You should have done:
char theNumber[255]; // Buffer size depends on the particular application
int i = 0;
while(data>>text)
{
theNumber[i] = text;  
i++;
}
The second attempt:
theNumber = text;
May or may not work, depending on how you defined text. This is impossible to answer without knowing the definition of text.
Anyway, if you want to read in a number from an input stream, just do:
int number;
data >> number;
UPDATE:
In the last code snippet you updated, the data stream is constructed, but never open. It is not associated to any file. Therefore, attempting to read from that stream won't succeed, and nothing will be stored into number (which is uninitialized).
ifstream data;
// data is not associated to any file after construction...
int theNumber;
data >> theNumber;
This does not create storage for your number.
char *theNumber;
It's a pointer. It points somewhere arbitrary, since you haven't assigned an address to it.
Try this.
char theNumber[10]; // Whatever size you need.
Or this.
int theNumber;
You didn't allocate any memory for char *theNumber;.
The theNumber points to a random location and you are printing random characters