ifstream wont read all integer - c++

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.

Related

Reading a text file into an array of integers

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.

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
}

Read Numeric Data from a Text File in C++

This is the program that needs to write a code to read data from file. The file looks like:
1234 200.55
5678 1234.56
9876 2.33
I need to store the first number as the account number and the second one as the balance of the account.
#include<iostream>
#include<fstream>
using namespace std;
const int MAX_NUM=100;
int read_accts(int acctnum[], double balance[], int max_accts);
int main()
{
int acctnum[MAX_NUM];
double balance[MAX_NUM];
int max_accts=0;
int num_accts;
num_accts = read_accts(acctnum,balance,max_accts);
return 0;
}
int read_accts(int acctnum[],double balance[],int max_accts)
{
ifstream infile;
infile.open("information");
while (infile >> acctnum[max_accts] && max_accts < MAX_NUM)
{
infile >> balance[max_accts];
max_accts++;
}
for (int i=0; i<=max_accts; i++)
{
cout << acctnum[i]<<endl;
cout << balance[i]<<endl;
}
infile.close();
return max_accts;
}
The output of this program is
0
0
It should be same as the text file has. it shouldn't be 0 and 0.
Thanks in advance Any help is appreciated.
First of all, you're printing one too many elements in each array. The printing loop should run from 0 to max_accts (not including), like so:
for (int i=0; i < max_accts; i++)
Now, since you're attempting to read a file named "information", I've created such file with the contents described in your question and ran your code. The output I get is:
1234
200.55
5678
1234.56
9876
2.33
This looks like what you wanted to get (and not zeroes), so your code seems to be working alright. Perhaps you're not opening the right file?
Either correct the name of the file from "information" to something else, or make sure you have a file named "information" in the current working directory.
For the file part of you program, the code below would be a better version of your function. It uses end of file and has the ability to handle of the file doesn't exits
int read_accts(int acctnum[], double balance[], int max_accts)
{
ifstream infile;
infile.open("information");
if (!infile)//check if file exists
{
//add code to handle missing file here
}
while (!infile.eof())
{
infile >> acctnum[max_accts];
infile >> balance[max_accts];
max_accts++;
}
infile.close();
return max_accts;
}
How about using the old school stdio API for a simple task like that?:
int accounts[3], i;
float balance[3];
FILE *fp = fopen("file.txt", "r");
for (i = 0; i < 3; i++)
fscanf(fp, "%d %f", &account[i], &balance[i]);
fclose(fp);

Having Open File Function Trouble

I'm new to c++ coding. I'm trying to write a function that opens specified ".txt" files(I fed up with coping/pasting multiple times).What I need to realize:
Specify filename;
read data and save to double(type) array;
return array;
As far as I understood, c++ can't return array, but it can return pointer. The problem is: how to use it? Any help will be appreciated. :)
P.S My draft code (it's working):
double arr[10];
fstream file;
file.open("input.txt");
if(file.is_open()){
while(file.good()){
for(int i = 0 ; i < 10 ; i++){
file >> arr[i];
}
}
file.close();
}else{
cout<<"[ERROR]: File \"input.txt\" wasn't found!"<<endl;
cout<<"[INFO]: Terminating program...";
Sleep(1000);
exit(0);
}
I dunno how to write as a function. Moreover I dunno how to use it
To start, try this:
std::vector<double> theFunction(const std::string &filename)
{
std::vector<double> arr(10);
std::fstream file(filename);
if (file)
{
for (int i = 0 ; i < 10 && file.good(); i++)
file >> arr[i];
}
return arr;
}
std::vector<double> result = theFunction("input.txt");
if (result.empty())
// Can not read the file

Finding specific primitives within a binary file

Is there any ways to find a specific primitive within a binary file(such as fread in MATLAB or BinaryReadLists in Mathematica)? Specifically, I want to scan my file until it reaches, say a int8_t precision number, then store it in a variable, then scan for another primitive(unsigned char, double, etc..)?
I am rewriting code from MATLAB that does this, so the format of the file is known.
I want to read n bytes of only the specified type (32-bit int, char, ..) in a file. Ex: Read only the first 12 bytes of my file if they return to be 8-bit integers
Maybe the solution to your problem is in understanding the difference between these two doc pages:
http://www.mathworks.com/help/matlab/ref/fread.html
http://www.cplusplus.com/reference/cstdio/fread/
Both versions of fread let you pull in an array of items from a binary file. I'm assuming from your question that you know the size and shape of the array you need.
#include <stdio.h>
int main() {
const size_t NumElements = 128; // hopefully you know
int8_t myElements[NumElements];
FILE *fp = fopen("mydata.bin", "rb");
assert(fp != NULL);
size_t countRead = fread(myElements, sizeof(int8_t), NumElements, fp);
assert(countRead = NumElements);
// do something with myElements
}
Your question makes no sense to me, but here's a bunch of random information on how to read a binary file:
struct myobject { //so you have your data
char weight;
double value;
};
//for primitives in a binary format you simply read it in
std::istream& operator>>(std::istream& in, myobject& data) {
return in >> data.weight >> data.value;
//we don't really care about failures here
}
//if you don't know the length, that's harder
std::istream& operator>>(std::istream& in, std::vector<myobject>& data) {
int size;
in >> size; //read the length
data.clear();
for(int i=0; i<size; ++i) { //then read that many myobject instances
myobject obj;
if (in >> obj)
data.push_back(obj);
else //if the stream fails, stop
break;
}
return in;
}
int main() {
std::ifstream myfile("input.txt", std::ios_base::binary); //open a file
std::vector<myobject> array;
if (myfile >> array) //read the data!
//well that was easy
else
std::cerr << "error reading from file";
return 0;
};
Also, you can use the .seek(position) member of ifstream to skip directly to a specific point in the file, if you happen to know where to find the data you're looking for.
Oh, you just want to read the first 12 bytes of the file as 8 bit integers, and then the next 12 bytes as int32_t?
int main() {
std::ifstream myfile("input.txt", std::ios_base::binary); //open a file
std::vector<int8_t> data1(12); //array of 12 int8_t
for(int i=0; i<12; ++i) //for each int
myfile >> data1[i]; //read it in
if (!myfile) return 1; //make sure the read succeeded
std::vector<int32_t> data2(3); //array of 3 int32_t
for(int i=0; i<3; ++i) //for each int
myfile >> data2[i]; //read it in
if (!myfile) return 1; //make sure the read succeeded
//processing
}