Want to read line by line but fstream read only first line - c++

A very simple program: read a file line by line (each line contains integer) then do something and write the output to a file.
int main()
{
ifstream fin ("f:\in.txt");
ofstream fout ("f:\out.txt");
int a;
while (fin >> a) {
int b = (a >> 6) & 255;
fout << b << endl;
}
return 0;
}
The input as multiple lines like this:
93859312
2635577168
2929619024
312396812
3019231016
3139200356
...
But the while loops is iterated only one time!! and output only contains
183
Which corresponds to the first input line. Why???

The numbers after the first one are larger than an int can represent.
Instead of int a;, use long long int a;
The largest value than an int can represent is 2,147,483,647:
What is the maximum value for an int32?
Your first value is less than this, but your second is not.
Thus (fin >> a) fails (i.e. is not true), and your program exits from the while loop.

Related

How to use file.eof() while reading in integers from a file?

I am writing a program that reads in data from a file. The file contains lines of integers, such as
5 6 2 8 6 7
2 5 3
4 0 9 1 3
The first integer of each line corresponds to how many numbers there are in that line. My goal is to read in each line, store the numbers in a vector, and do some operation on them. Here is what I have done:
int main(){
vector<int> vec;
int amount;
int nums;
ifstream file ("file.txt");
while(!(file.eof())){
file >> amount;
cout << amount << endl;
for (int i = 0; i < amount; i++){
file >> nums;
vec.push_back(nums);
}
printArray(vec);
bubbleSort(vec);
vec.clear();
}
return 0;
}
Unfortunately, the last line always gets read twice. I looked online and saw that the eof() function should not be used to maintain loops. What else could I use in this situation?
Thanks.
operator>> sets the stream's eofbit flag if it tries to read past EOF. You can use that condition to break your loops. But you have to actually perform a read operation BEFORE you can evaluate eof(). See Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong? for more details on that.
Since you are dealing with line-based text, you can use std::getline() to read each line first, and then you can use std::istringstream to parse each line, eg:
int main()
{
vector<int> vec;
ifstream file ("file.txt");
string line;
while (getline(file, line)) {
istringstream iss(line);
int amount, nums;
iss >> amount;
cout << amount << endl;
for (int i = 0; (i < amount) && (iss >> nums); ++i){
vec.push_back(nums);
}
printArray(vec);
bubbleSort(vec);
vec.clear();
}
return 0;
}
Alternatively, you can simply take advantage of the fact that operator>> skips whitespace, including line breaks, eg:
int main()
{
vector<int> vec;
int amount, nums;
ifstream file ("file.txt");
while (file >> amount) {
cout << amount << endl;
for (int i = 0; (i < amount) && (file >> nums); ++i){
vec.push_back(nums);
}
printArray(vec);
bubbleSort(vec);
vec.clear();
}
return 0;
}
Although, this approach would be a little less resilient to errors in the input data, compared to the std:getline() approach. If the actual amount of numbers in a given line does not match the specified amount at the beginning of the line, this approach will get its reading of the file out of sync. Worse, if a given line contains any non-integer values, this approach will fail to read any subsequent data at all.
In the std:getline() approach, if a given line is malformed, the code will simply move on to the next line and continue on like nothing bad happened.

Perform calculation seperately on values from file in C++ [duplicate]

This question already has answers here:
Read file line by line using ifstream in C++
(8 answers)
Closed 3 years ago.
So I have a input file which contains several different integer values(each in a seperate line), now I need to read each value, find the square root and get the output. The issue I am having is that my code only reads the first value from the input file. I have a feeling I am supposed to be using a loop to read each value seperately, so if someone can help me out it would be really appreciated.
float file_inp() //reads values from file and calculates the square root
{
float y = 0;
ifstream fin;
fin.open("input.txt",ios::in);
if (fin)
{
int x = 0;
fin >> x;
y=sqrt(x);
}
return y;
}
int main()
{
float y = 0;
cout << file_inp();
system("Pause");
return 0;
}
The main problem is that you have a function that reads the file and returns one number.
No amount of looping can make that function produce more than one number.
Instead of one function that does all the work, it's often better to have functions that do a little bit of work and use them over and over.
It's also a good idea to separate I/O from data processing.
This the common "elementwise processing of whitespace-separated input" loop:
int main()
{
std::ifstream input("input.txt"); // No 'ios::in'; it's already an input stream.
SomeType piece;
while (input >> piece) // Read until you can't read no more.
{
process(piece); // Do whatever you want to do.
}
}
Adjust types and processing as necessary.
In your case,
int main()
{
std::ifstream input("input.txt");
int x;
while (input >> x)
{
std::cout << std::sqrt(x) << std::endl;
}
}

Unable to have function properly populate array from text file, seems to skip first line/be one off

So I have two simple questions. One is my function okay for reading a text file composed of one number on each line and passing it an array inside main()? And is the text file opening/closing properly or do I not understand the code?
And secondly, I can't seem to fill my array correctly. There's 92 numbers/lines, but I can only seem to get 91 elements. It seems to skip the first number, but I'm not sure why. When I'm debugging I can see "number" reading the the first line, but I don't know where it goes.
The text file is 92 numbers with decimals, with a number in each line like this..and the first number is in the first line, no space above and no vertical space between the numbers.
31.11
25.22
...
int getTempData(double temperatures[]) {
ifstream input("pgm6.txt");
if (!input)
return 1; // closes input file
string number;
while (input >> number)
for (int i = 0; i < 91; i++)
{
input >> temperatures[i];
}
}
and inside main()
const int ARRAY_SIZE = 91;
double temperatures[ARRAY_SIZE];
getTempData(temperatures);
Edit: Thanks so much for the help everyone. I learned my lesson in not using code I don't quite understand from here: https://www.reddit.com/r/learnprogramming/comments/2wwv6i/c_creating_writing_to_and_displaying_text_files/
#include <fstream> // Instead of <iostream>
#include <string>
using namespace std; // Nothing too much wrong with this...
int main() {
ifstream input("input.txt"); // Open the file "input.txt" for reading
(if = input file)
if ( !input ) // Did the file open correctly?
return 1;
ifstream output("output.txt"); // Open the file "output.txt" for writing
(of = output file)
if ( !output ) // Did the file open correctly?
return 1; // C++ automatically closes the input file!
string word;
**while ( input >> word )** // Read a word while the file isn't at its
end
output << word << '\n'; // Write the word on its own line
// C++ automatically closes the output file
// C++ automatically closes the input file
}
What you are trying to achieve seems to boil down to this:
#include <fstream>
int getTempData(double temperatures[]) {
std::ifstream input("pgm6.txt");
int i;
for (i = 0; i < 92 && input >> temperatures[i]; i++) {
// deliberate empty line
}
// input will close file on exiting function
return i; // returns number of elements found
}
int main() {
const int ARRAY_SIZE = 92;
double temperatures[ARRAY_SIZE];
getTempData(temperatures);
}
while (input >> number)
This reads the first number and throws it away. Simply remove this line of code.
Also, you should probably add error checking to input >> temperatures[i];. And your function needs to return something if all is well -- currently there is no return statement at the end. Also, your loop only collects 91 elements.

How to read integer value from file in C++

How can read integer value from file? For example, these value present in a file:
5 6 7
If I open the file using fstream then how I can get integer value?
How can read that number and avoid blank space?
ifstream file;
file.open("text.txt");
int i;
while (file >> i) {
cout << i << endl;
}
ifstream f(filename);
int x, y, z;
f >> x >> y >> z;
ifstream f;
f.open("text.txt");
if (!f.is_open())
return;
std::vector<int> numbers;
int i;
while (f >> i) {
numbers.push_back(i);
}
It's really rare that anyone reads a file Byte by Byte ! ( one char has the size of one Byte).
One of the reason is that I/O operation are slowest. So do your IO once (reading or writing on/to the disk), then parse your data in memory as often and fastly as you want.
ifstream inoutfile;
inoutfile.open(filename)
std::string strFileContent;
if(inoutfile)
{
inoutfile >> strFileContent; // only one I/O
}
std::cout << strFileContent; // this is also one I/O
and if you want to parse strFileContent you can access it as an array of chars this ways: strFileContent.c_str()

new >> how would i read a file that has 3 columns and each column contains 100 numbers into an array?

int exam1[100];// array that can hold 100 numbers for 1st column
int exam2[100];// array that can hold 100 numbers for 2nd column
int exam3[100];// array that can hold 100 numbers for 3rd column
int main()
{
ifstream infile;
int num;
infile.open("example.txt");// file containing numbers in 3 columns
if(infile.fail()) // checks to see if file opended
{
cout << "error" << endl;
}
while(!infile.eof()) // reads file to end of line
{
for(i=0;i<100;i++); // array numbers less than 100
{
while(infile >> [exam]); // while reading get 1st array or element
???// how will i go read the next number
infile >> num;
}
}
infile.close();
}
int exam1[100];// array that can hold 100 numbers for 1st column
int exam2[100];// array that can hold 100 numbers for 2nd column
int exam3[100];// array that can hold 100 numbers for 3rd column
int main() // int main NOT void main
{
ifstream infile;
int num = 0; // num must start at 0
infile.open("example.txt");// file containing numbers in 3 columns
if(infile.fail()) // checks to see if file opended
{
cout << "error" << endl;
return 1; // no point continuing if the file didn't open...
}
while(!infile.eof()) // reads file to end of *file*, not line
{
infile >> exam1[num]; // read first column number
infile >> exam2[num]; // read second column number
infile >> exam3[num]; // read third column number
++num; // go to the next number
// you can also do it on the same line like this:
// infile >> exam1[num] >> exam2[num] >> exam3[num]; ++num;
}
infile.close();
return 0; // everything went right.
}
I assume you always have 3 numbers per line. If you know the exact number of lines, replace the while with a for from 0 to the number of lines.
Rule # 1 about reading data from a file: don't trust the contents of the file. You never know with absolute certainty what is in the file until you've read it
That said, one correct way to read lines of data from a file, where each line is composed of multiple whitespace-delimited fields would be to use a combination of getline and stringstream:
std::string line;
while (std::getline(infile, line))
{
std::stringstream ss(line);
int a, b, c;
if (ss >> a >> b >> c)
{
// Add a, b, and c to their respective arrays
}
}
In English, we get each line from the file stream using getline, then parse the line into three integers using a stringstream. This allows us to be certain that each line is formatted correctly.
We check to ensure the extraction of the integers succeeded before we add them to the arrays to ensure that the arrays always have only valid data.
There is other error handling that might be desirable:
In the example, if extraction of the integers from the line fails, we just ignore that line; it could be a good idea to add logic to abort the process or report an error.
After we get three integers, we ignore the rest of the line; it might be a good idea to add checks to ensure that there is no more data on the line after the required integers, depending on how strict the file's formatting needs to be.
After we finish reading the file, we should test to be sure eof() is set and not fail() or bad(); if one of those two flags is set, some error occurred when reading the file.