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;
}
Related
I am a C++ beginner, and I have been working on a project in which you have to input some integers separated by a space and the program will have to output all possible arrangements of the integers. I know that in python, this could be done using [int(item) for item in input().split()], but I don't know how to do the same in C++. I want to use a easy method built-in in C++. Can anyone provide some opinion? Any help will be appreciated.
You see, you create a vector of integers from the string and then simply permute the vector:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
int main() {
std::string str;
std::getline(std::cin, str);
std::istringstream iss(str);
std::vector<int> vec;
int temp = 0;
while (iss >> temp) {
vec.push_back(temp);
}
//you now have a vector of integers
std::sort(vec.begin(), vec.end()); //this is a must as `std::permutations()` stops when the container is lexicographically sorted
do {
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>{std::cout, " "});
std::cout << "\n";
} while (std::next_permutation(vec.begin(), vec.end()));
return 0;
}
To know how to output all permutations of all possible lengths, take a look at
How to create a permutation in c++ using STL for number of places lower than the total length
I am trying to read this csv file, let's call it "file.csv", and I'm trying to put it into a vector of double.
This csv contains numbers like:
755673.8431514322,
684085.6737614165,
76023.8121728658,
...
I tried using stringstream, and it successfully input these number to the vector but the input numbers is not like I wanted. Instead, the inputted numbers are
7556373, 684085, 76023.8
How can I read the whole digits without throwing any of it away?
This is my code
vector<long double> mainVector;
int main()
{
ifstream data;
data.open("file.csv");
while (data.good())
{
string line;
stringstream s;
long double db;
getline(data, line, ',');
s << line;
s >> db;
mainVector.push_back(db);
}
}
How to read the whole digits without throwing any of it.
As #user4581301 mentioned in the comments, I guess you are missing std::setprecision() while outputting.
However, you do not need std::stringstream to do the job. Convert line(which is a string directly to double using std::stold and place into the vector directly as follows.
That being said, use of std::stold will make sure not to have wrong input to the vector, by throwing std::invalid_argument exception, if the conversion from string to double was unsuccessful. (Credits to #user4581301)
#include <iostream>
#include <fstream>
#include <vector> // std::vector
#include <string> // std:: stold
#include <iomanip> // std::setprecision
int main()
{
std::vector<long double> mainVector;
std::ifstream data("file.csv");
if(data.is_open())
{
std::string line;
while(std::getline(data, line, ','))
mainVector.emplace_back(std::stold(line));
}
for(const auto ele: mainVector)
std::cout << std::setprecision(16) << ele << std::endl;
// ^^^^^^^^^^^^^^^^^^^^
return 0;
}
As a learner in c++, I decided to play with complex numbers, using the standard library. Now I need to read and write an array of complex from/to text files. This works simply for writing, without supplemental tricks :
void dump(const char *filename){
ofstream result;
result.open (filename);
for(int k=0;k<15;k++){
result<< outputs[k] <<endl;
}
result.close();
}
The data are parenthesized and written line by line looking like : (real,im)...
Now, I guess reading (and loading an array of complex) should be as trivial as reading. However, despite my research, I have not found the right way to do that.
My first attempt was naive :
void readfile(const char *filename){
string line;
ifstream myfile (filename);
if (myfile.is_open())
{
int k=0;
while ( getline (myfile,line) ){
k++;
cout << line << endl;
inputs[k]= (complex<float>) line; //naive !
}
myfile.close();
}
else cout << "Unable to open file";
}
Is there a way to do that simply (without a string parser ) ?
Assuming you have an operator<< for your_complex_type (as has been mentioned, std::complex provides one), you can use an istream_iterator:
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
std::ifstream input( "numbers.txt" );
std::vector<your_complex_type> buffer{
std::istream_iterator<your_complex_type>(input),
std::istream_iterator<your_complex_type>() };
}
This will read all numbers in the file and store them in an std::vector<your_complex_type>.
Edit about your comment
If you know the number of elements you will read up-front, you can optimize this as follows:
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
std::ifstream input( "numbers.txt" );
std::vector<your_complex_type> buffer;
buffer.reserve(expected_number_of_entries);
std::copy(std::istream_iterator<your_complex_type>(input),
std::istream_iterator<your_complex_type>(),
std::back_inserter(buffer));
}
std::vector::reserve will make the vector reserve enough memory to store the specified number of elements. This will remove unnecessary reallocations.
You can also use similar code to write your numbers to a file:
std::vector<your_complex_type> numbers; // assume this is filled
std::ofstream output{ "numbers.txt" };
std::copy(std::begin(numbers), std::end(numbers),
std::ostream_iterator<your_complex_type>(output, '\n') );
C++ version:
std::complex<int> c;
std::ifstream fin("filename");
fin>>c;
C version:
int a,b;
FILE *fin=fopen("filename","r");
fscanf(fin,"(%d,%d)\n",&a,&b);
C++ read multiple lines with multiple complex values on each line
#include <stdio.h>
#include <fstream>
#include <complex>
#include <iostream>
#include <sstream>
int main ()
{
std::complex<int> c;
std::ifstream fin("test.in");
std::string line;
std::vector<std::complex<int> > vec;
vec.reserve(10000000);
while(std::getline(fin,line))
{
std::stringstream stream(line);
while(stream>>c)
{
vec.push_back(c);
}
}
return 0;
}
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.
A novice at C++, i am trying to create a stats program to practice coding. i am hoping to get a text file, read it and store values into arrays on which i can perform mathematical operations. i am stuck here
main ()
{
char output[100];
char *charptr;
int age[100];
ifstream inFile;
inFile.open("data.txt");
if(!inFile)
{
cout<<"didn't work";
cin.get();
exit (1);
}
inFile.getline(output,100);
charptr = strtok(output," ");
for (int x=0;x<105;x++)
{
age[x] = atoi(charptr);
cout<<*age<<endl;
}
cin.get();
}
in the code above, I am trying to store subject ages into the int array 'age', keeping ages in the first line of the file. I intend to use strtok as mentioned, but i am unable to convert the tokens into the array.
As you can obviously see, I am a complete noob please bear with me as I am learning this on my own. :)
Thanks
P.S: I have read similar threads but am unable to follow the detailed code given there.
There are a few issues with the for loop:
Possibility of going out-of-bounds due to age having 100 elements, but terminating condition in for loop is x < 105
No check on charptr being NULL prior to use
No subsequent call to strtok() inside for loop
Printing of age elements is incorrect
The following would be example fix of the for loop:
charptr = strtok(output, " ");
int x = 0;
while (charptr && x < sizeof(age)/sizeof(age[0]))
{
age[x] = atoi(charptr);
cout << age[x] << endl;
charptr = strtok(NULL, " ");
x++;
}
As this is C++, suggest:
using std::vector<int> instead of a fixed size array
use the std::getline() to avoid specifying a fixed size buffer for reading a line
use std::copy() with istream_iterator for parsing the line of integers
For example:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
int main ()
{
std::vector<int> ages;
std::ifstream inFile;
inFile.open("data.txt");
if(!inFile)
{
std::cout<<"didn't work";
std::cin.get();
exit (1);
}
std::string line;
std::getline(inFile, line);
std::istringstream in(line);
std::copy(std::istream_iterator<int>(in),
std::istream_iterator<int>(),
std::back_inserter(ages));
return 0;
}