I need to read some files containing a lot of numbers (int). Lines of every file are different.
1
3
5
2
1
3
2
I have to read one of those files and create an array of int dynamically.
I'm going to read the file twice because I'm not able to know the length of the file.
Do you know another way ?
This is what I did:
int main()
{
int *array;
int tmp, count;
ifstream fin("inputfile");
while(fin >> tmp)
count++;
array = new int[count];
fin.close();
fin.open("inputfile");
int i=0;
while(fin >> tmp)
array[i++]=tmp;
delete[] array;
return 0;
}
Thanks for your help.
Use a std::vector rather that a raw array.
That way you can add to the vector as you read each item, rather than having to read the file once in order to work out how many items are in the file and then again to populate the array.
int main()
{
std::vector<int> data;
int tmp;
ifstream fin("inputfile");
while(fin >> tmp)
{
data.push_back(tmp)
}
return 0;
}
Here is an idiomatic way of reading numbers from a file into an std::vector<int>:
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
int main()
{
std::ifstream is("inputfile");
std::istream_iterator<int> start(is), end;
std::vector<int> numbers(start, end);
std::cout << "Read " << numbers.size() << " numbers" << std::endl;
}
if there are same numbers of int in a line for all files, you can get the count of line of the file by calculating the size of it, and then the lines of this file is equal to size(file)/(n*sizeof(int)), n is the number of int for every line. I think you can try instead of read the file twice.
If you don't want use std::vector, you can add a count for in the while loop, if it reaches the up limit of the array, realloc another buffer with size*2 and copy the data to it, then start read the file again.
vector use the same logic.
Related
I am trying to read integers from a file to an array, but when I try to read the elements of said array, I get numbers that have little to nothing to do with the numbers in the file.
#include <fstream>
#include <istream>
#include <iterator>
#include <string>
using namespace std;
//Main Function
int main()
{
//Declare variables and ask user for file names
string f1, f2;
int s1, s2, n = 0;
cout<<"Please enter the names of the files you would like to merge, file extensions included."<<endl;
cout<<"File 1 Name: ";
cin>>f1;
cout<<"File 2 Name: ";
cin>>f2;
//Opening files
ifstream fs1, fs2;
fs1.open(f1);
fs2.open(f2);
//Checking if both files exist
if (fs1 && fs2)
{
//Getting length of files
s1 = distance(istream_iterator<int>(fs1), istream_iterator<int>());
s2 = distance(istream_iterator<int>(fs2), istream_iterator<int>());
//Declaring arrays and writing values to them
int a1[s1], a2[s2];
while(!fs1.eof())
{
fs2 >> a2[n];
n++;
}
//Closing files
fs1.close();
fs2.close();
//Reading array
for (int i=0; i<s2; i++)
{
cout<<a2[i]<<endl;
}
}
//If the requested files do not exist
else
{
cout<<"No file exists with that name."<<endl;
}
}
I have two text files, file1.txt and file2.txt. The code opens the files, determines the number of integers within, and creates an array with the number of integers.
file1.txt: 45 69 87 3 9 32 11 9 6 66
file2.txt: 4
The output I get when reading the array for file1.txt (a1[]) gives very unexpected numbers:
File 1 Name: file1.txt
File 2 Name: file2.txt
0
0
1878276352
6421656
4
6422016
3756032
48
16
4199922
As you can see, this is not the output I expected. file2.txt only consists of the number 4, and its ouput was simply 16
I am somewhat new to c++ and programming in general, so you might have to bear with me. Does anybody see what I've done wrong?
I am using Code::Blocks and gcc is my compiler. Thank you for your time.
Tested, using std:
std::vector<int> read_file(std::string filename) {
int n;
std::vector<int> vector;
std::ifstream file;
file.open(filename);
if (file.is_open()) {
std::string line;
while (std::getline(file, line)) {
std::istringstream is(line);
while (is >> n) {
vector.push_back(n);
}
}
file.close();
}
return vector;
}
int main() {
std::vector<int> vector = read_file("file1.txt");
for (auto element: vector) {
std::cout << element << std::endl;
}
}
Note: int a1[s1], a2[s2]; doesn't comply with the ISO C++ standard. For details, see Why aren't variable-length arrays part of the C++ standard? If you cannot know the length of an array prior to runtime, consider using std::vector.
It is as #user4581301 says, you need to rewind the files, since std::distance() will read the files to the end.
Otherwise you will already be at the end of the files, and you won't read any data into your arrays, which means your arrays will be holding uninitialized memory.
Here is a solution:
// Rewind the files
fs1.clear();
fs2.clear();
fs1.seekg(0);
fs2.seekg(0);
// Read into array 1
for (n = 0; fs1 >> a1[n]; ++n) {}
// Read into array 2
for (n = 0; fs2 >> a2[n]; ++n) {}
seekg() sets the position in the stream to the given offset. seekg(0) resets to the beginning of the stream.
clear() clears the stream's internal error state flags, including the eofbit.
I'm just beginning to learn C++ and I am having some trouble with a program. It's supposed to sort numbers from an external file. I've managed to successfully code the sorting algorithm, but I am having trouble working with the external file. I am just testing some things out in a separate program to gain an understanding of how things like ifstream work. I should be able to figure out how to implement it into my program once I gain a better understanding of how it works.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main() {
using namespace std;
int count;
ifstream InFile;
InFile.open ("unsorted.txt");
InFile >> count;
int numbers[count];
for(int a = 0; a < count; a++)
InFile >> numbers[a];
cout << numbers << endl;
}
Currently, the output for this is 0x7ffc246c98e0 I am not sure why this is the case I'm just attempting to print my file of integers. Could anyone help explain what I am doing wrong? I'd be very thankful.
When you do
cout << numbers << endl;
you print the pointer to the first element of the array.
You want
cout << numbers[a] << '\n';
to print the current element.
Furthermore, if that's all your program is doing, then you don't actually need the array. All you need is a single int variable:
int value;
for (int a = 0; a < count; ++a)
{
InFile >> value;
cout << value << '\n';
}
That also solve the problem with the variable-length array (since there isn't any).
If you intend to use count variable to count the file size or something, it is where your code goes wrong. You can't count the length of the file as like as you are trying.
while( getline ( InFile, line ) )
{
count += line.length();
}
Maybe, try like this!!!
If you use
InFile>>count;
it would try to store all the string from InFile stream to count, which is not intended.
I am trying to run this but the file is constantly failing to load. What I am trying to do is load a dictionary into an Array with each level of an array accounting for one word.
#include <iostream>
#include <string>
#include <fstream>>
#include <time.h>
#include <stdlib.h>
using namespace std;
int Rand;
void SetDictionary(){
srand(time(NULL));
Rand = rand() % 235674;
fstream file("Hangman.txt");
if(file.is_open()){
string Array[235675];
for(int X = 0; X < 235673; X++){
file >> Array[X];
}
cout << Array[Rand];
}else{
cout << "Unable To Open File\n";
}
}
int main(){
SetDictionary();
}
vector<string> words;
{
ifstream file("Hangman.txt");
string word;
while (file >> word)
{
words.push_back(word);
}
}
string randword = words[rand() % words.size()];
At first, I see you do not reuse Array after cout << Array[Rand] is done. You do not need array at all in this case. Read the file line by line into temp variable and cout this variable if condition X==Rand, then break.
At second, the implementation could be improved. Assumed you are trying to cout random word from file. It would be 1000-times faster to generate Rand as 0..file-size, then offset to this Rand. Now you are "inside" desired word and the task is to read back and forward for the work begin and end respectively. This algorithm will show a bit different probability distribution.
At third. If you plan to reuse file data, it would be much faster to read whole file into memory, and then do split by words, storing words offsets as arrays of integers.
At last. With really huge dictionaries (or if the program run on limited memory) it is possible to store words offsets only, and re-read dictionary contents on-the-fly.
How can I read integers from a file to the array of integers in c++? So that, for example, this file's content:
23
31
41
23
would become:
int *arr = {23, 31, 41, 23};
?
I actually have two problems with this. First is that I don't really know how can I read them line by line. For one integer it would be pretty easy, just file_handler >> number syntax would do the thing. How can I do this line by line?
The second problem which seems more difficult to overcome for me is - how should I allocate the memory for this thing? :U
std::ifstream file_handler(file_name);
// use a std::vector to store your items. It handles memory allocation automatically.
std::vector<int> arr;
int number;
while (file_handler>>number) {
arr.push_back(number);
// ignore anything else on the line
file_handler.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
don't use array use vector.
#include <vector>
#include <iterator>
#include <fstream>
int main()
{
std::ifstream file("FileName");
std::vector<int> arr(std::istream_iterator<int>(file),
(std::istream_iterator<int>()));
// ^^^ Note extra paren needed here.
}
You can just use file >> number for this. It just knows what to do with spaces and linebreaks.
For variable-length array, consider using std::vector.
This code will populate a vector with all numbers from a file.
int number;
vector<int> numbers;
while (file >> number)
numbers.push_back(number);
Here's one way to do it:
#include <fstream>
#include <iostream>
#include <iterator>
int main()
{
std::ifstream file("c:\\temp\\testinput.txt");
std::vector<int> list;
std::istream_iterator<int> eos, it(file);
std::copy(it, eos, std::back_inserter(list));
std::for_each(std::begin(list), std::end(list), [](int i)
{
std::cout << "val: " << i << "\n";
});
system("PAUSE");
return 0;
}
I have a large file (50x11k) of a grid of numbers. All i am trying to do is place the values into a vector so that i can access the values of different lines at the same time. I get a seg fault everytime (i cannot even do a cout before a the while loop). Anyone see the issue?
If there is an easier way to do this then please let me know. Its a large file and I need to be able to compare the values of one row with another so a simple getline does not work, Is there a way to jump around a file and not "grab" the lines, but just "examine" the lines so that I can later go back an examine that same line by putting in that number? Like looking at the file like a big array? I wanna look at the third line and 5 character in that line at the same time i look at the 56th line and 9th character, something like that.
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
//int g_Max = 0;
int main() {
vector<vector<string> > grid;
ifstream in("grid.txt");
int row = 0;
int column = 0;
string c;
if (!in) {
cout << "NO!";
}
while (!in.eof()) {
c = in.get();
if ( c.compare("\n") == 0) {
row++;
column = 0;
}
else {
c = grid[column][row];
cout << grid[column][row];
column++;
}
}
return 0;
}
vector<vector<string> > grid;
This declares an empty vector, with no elements.
c = grid[column][row];
This accesses elements of the vector, but there are no elements.
If you change it to use vector::at() instead of vector::operator[] like so:
c = grid.at(column).at(row);
then you'll get exceptions telling you you're accessing out of range.
You need to populate the vector with elements before you can access them. One way is to declare it with the right number of elements up front:
vector<vector<string> > grid(11000, std::vector<string>(50));
You probably also want to fix your IO loop, testing !in.eof() is usually wrong. Why not read a line at a time and split the line up, instead of reading single characters?
while (getline(in, c))
If all you need is to access all lines at once why you don't declare it as std::vector<std::string> and each line is an string??
std::string s;
std::vector<std::string> lines;
while( std::getline(in, s) ) lines.push_back( s );
std::cout << "File contain " << lines.size() << " line" << std::endl;
std::cout << "Char at [1][2] is " << lines[1][2] << std::endl; // assume [1][2] is valid!