This question might sound stupid but I really want to know that How do I get all the output at last after inputting all the input.Example,For input
3
14
7
6
Output suppose will be
0
0
1
0
But compiler is giving output something like
3
0 14
0 7
1 6
0
Which doesn't look good,so I want to get output like the one we get in IDEONE(i.e all at the last).Is this possible ?IF yes,than please let me know
I'd suppose that you read the input int by int, and the output comes as soon as another int is read, while to achieve the desired behavior you have to read them all first and then process.
std::vector<int> ints;
while (std::cin)
{
int x;
if (std::cin >> x)
ints.push_back(x);
}
for (int x : ints)
{
// do what you want with x
}
Note that the problem is definitely not the compiler, it's just how most terminals work - both standard input stream (stdin) and standard output stream (stdout) are linked with the text that you type/see in the terminal.
Related
Summary & My understanding:
My question can be referred to "using a istream_iterator twice with a same ifstream", which is not a good idea because after the first traversing, the stream is already reached the (end-of-file). Since we use istream_iterator to traverse the whole stream:
Because istream_iterator is a single-pass iterator, so we can't go
back to reload the stream again.
Because the stream is already reached the end-of-file, even we bind a new iterator to it, the iterator still points the end-of-file.
Thanks those ppl who answered my questions!
====================
Update:
I just did some sample test:
with two different ifstream objects, the result is correct.
with two different istream_iterator which bind to the same ifstream obejct, the result is not correct; instead of nothing in file, I got number 2 there.
Just like #aschepler 's answer below, istream_iterator is a single-pass iterator and will invalid after it did the self-increment; but how a brand new iterator still not work for this? Why I have to create two different ifstream objects to make the program work?
Thanks for your answers!
===================Original Question Here==========================
I have a question about a exercise 10.33 on C++ primer 5th (p.407). My problem was occurred at this portion:
using ostream_iterators, write the odd numbers into the first output file, and Write the even numbers into the second file.
Some defination here:
ifstream ifs(argv[1]);
istream_iterator<int> int_in(ifs);
istream_iterator<int> int_in_eof;
ofstream ofs_odd(argv[2]);
ofstream ofs_even(argv[3]);
ostream_iterator<int> int_out_odd(ofs_odd, " ");
ostream_iterator<int> int_out_even(ofs_even, " ");
Actually std::for_each did a good job:
for_each(int_in, int_in_eof, [&int_out_odd, &int_out_even](const int i)
{ *(i & 0X1 ? int_out_odd : int_out_even)++ = i; });
The correct result looks like this:
input file: 1 2 3 4 5 6 7 8 9
output_odd: 1 3 5 6 9
output_even: 2 4 6 8
Then I tried to use copy_if to implement:
//copy odd number to odd file
copy_if(int_in, int_in_eof, int_out_odd, [](const int i)
{return i & 0X1; });
//copy even number to even file
copy_if(int_in, int_in_eof, int_out_even, [](const int i)
{return !(i & 0X1); });
The result looks like this:
input file: 1 2 3 4 5 6 7 8 9
output_odd: 1 3 5 6 9
output_even:
I got nothing inside even file.
My question is the first copy_if changing anything inside the istream ?
Thanks in advance for your help!
istream_iterator is a single-pass iterator, not a ForwardIterator. After you do ++iter, an old copy of iter is invalid.
I have a text file which first describes some lines and then describes some colorful lines:
1 2 3 4
5 6 7 8
9 10 11 12
red 1 0 0 1 2 3 4
green 0 1 0 5 6 7 8
blue 0 0 1 9 10 11 12
The number of lines in each section is unknown at time of execution
I overloaded the std::cin >> operator for these structs:
struct Point { int x, y; }
struct Line { Point a, b; }
struct Color { float r, g, b; std::string name; };
struct ColorfulLine { Line line; Color color; };
(Full example here: http://ideone.com/bMOaL1 [already works - edited according to the accepted answer])
Now I need to iterate over the file using Lines and ColorfulLines:
Line line;
while(cin >> line) { cout << "We've got a line!\n"; }
ColorfulLine color_line;
while(cin >> color_line) { cout << "We've got a colorful line!\n"; }
// actually I'm putting them into std::lists but I skipped this part for simplicity
And here is the problem - the colorful lines are never fetched, i.e. the second loop is not executed.
I have an assumption why it happens but don't know how to fix it:
When std::cin tries to fetch the 4th Line, it fails because instead of a number there's the string "red".
Next, in the second while loop, std::cin tries to read a string (Color.name) but it sees a number, and then fails too.
I tried to put some random word before the ColorfulLines section hoping that when the first loop fails, the second will start reading from the "red" string, but it didn't.
How to fix this?
After the first loop breaks, std::cin is in a bad state. That's why the loop breaks in the first place. Performing reads on a bad stream fails immediately, thus the second loop is never entered.
To solve this, reset the error state after the first loop breaks with
std::cin.clear();
For example, I have a file named Bjarne.txt and in it there's the integers:
16 2 3 4
I have made a program to read the integers available inside the file and output them to me in the console window , however , I'm trying to use cin.unget() and by that get understanding of what it does actually , here's the source code:
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ifstream ifs("Bjarne.txt");
int a;
for(int i = 0;i<4;++i){
ifs>>a;
cout<<endl<<a;
if(i==0){
ifs.unget();
}
}
And the output is:
16 6 2 3
Why is the output like that? ( it should be 16 2 3 4 ) , it only occurs when I put ifs.unget() in the program , so my questions are , what is the purpose of cin.unget() while using I/O files and why is the number 6 ( as part of 16 ) getting outputted?
Thanks in advance for any help.
Something wrong with the documentation?
Makes the most recently extracted character available again.
At the end of your first loop iteration, 6 was the last extracted character (as the final digit of the extracted formatted int with value 16).
Unget does exactly that: it un-gets it.
The next operation has the 6 to work with. So, surprise, you get 6 next time.
I am trying to figure out how to read two matrices from one file and then assign them to two different 2D arrays. The matrices are separated by a new line in the text file. I managed to get the first one to read successfully but now I cant figure out how to read the second one. The way I see it, the the line that separates the two matrices must be considered and checked for. How do I get the program to read and assign the second matrix to an array?
Both matrices and arrays are 4x4.
This is what the text file looks like:
3 4 5 7
5 16 7 12
11 12 3 9
9 8 1 12
15 4 3 6
1 12 3 12
7 8 19 9
11 12 8 5
Here is my code for the first array which works fine.
for (int y = 0; y < 4; ++y )
{
for (int x = 0; x < 4; ++x )
{
infile >> array1[x][y];
}
}
And here is my code for the array I can't figure out.
for (int y = 0; y < 4; ++y )
{
for (int x = 0; x < 4; ++x )
{
if(x == '\n' && y == '\n') //My attempt.
{
infile >> array2[x][y];
}
}
}
Here is the output:
This will check to make sure numbers in file are written to the first array.
3 4 5 7
5 16 7 12
11 12 3 9
9 8 1 12
This will check to make sure numbers in file are written to the second array.
9.21742e-314 1.0572e-307 7.29112e-304 3.87184e-306
1.06498e-307 1.65425e-317 6.79039e-313 4.22748e+266
5.92879e-323 1.06196e-307 6.95089e-308 9.88799e-315
1.79648e-313 8.48798e-314 6.95224e-308 1.06193e-307
Press any key to continue . . .
Any help is appreciated!
When you are reading your file using the "formatted input" operator >>, the kind and amount whitespace (spaces, tabs, newlines) between the items (numbers in your case) is insignificant. This means you do not get to see the empty line at all. If you need to parse a file based on its lines, consider using getline instead and parsing the single lines using a istringstream.
If on the other hand you know the size of both arrays, you can simply read the second array just as you read the first array. The extra empty line just gets ignored.
The reason your code for reading the second array does not work is that you compare the index variables to '\n', which happens to be 10 on most systems. As your index ranges from 0 to 3, the if condition is never true, so nothing gets read at all, so you are seeing a dump of uninitialized memory.
You can read the second array exactly as you read the first. The reason is that, when you start reading from a stream, at first it discards whitespaces till it encounters something that is not whitespace. Then it gets the numbers/character one by one till it encounters whitespace again. So, there is no problem with the newline and you can read the remaining array without problems.
Just need general project help.
Basically I need to do this for 8 players. The numbers come from a file im supposed to call in. The first 5 numbers for for the first 5 games, the next for rebounds, and then for blocks. Im assuming I need to call in a loop to read the first name, last name, points, rebounds and blocks, process that info and then output the information.Any tips/ suggestions?
ex from the text file:
Thomas Robinson 17 28 10 16 10 11 12 13 8 9 1 1 1 0 1
ex from what I'm supposed to return that information to
Game Log
-----------------------------------------------------------------------------
Player Name : Thomas Robinson
-----------------------------------------------------------------------------
Game # Points Rebounds Blocks
-----------------------------------------------------------------------------
1 17 11 1
2 28 12 1
3 10 13 1
4 16 8 0
5 10 9 1
-----------------------------------------------------------------------------
I think this is homework, but since I don't know which functions can be used, and which functions can't, my answers may be can't fit the request.
At a first look, I got three ideas.
1) using ifstream::get()
ifstream in_file;
in_file.open("your_file_name.txt");
char ch;
string str = "";
while(in_file.get() != '\n')
{
str = "";
while((ch = in_file.get()) != ' ')
{
// add ch to str.
str += string(&ch, 1);
}
// push str into an array, vector, stack, etc.
/*...*/
}
in_file.close();
2) read the line into a string, and then use a split function, you can find how to implement a split function everywhere.
3) use the ifstream::getline() function, it provides a delemiter parameter.
you can find the usage of ifstream::get() and ifstream::getline() here and here
The code I provide in 1) is probably not a good practice, you should check the 'EOF' stream error, in_file.open()'s exceptions etc.
btw, the code I first wrote was an error code, you can't use str += string(ch), you should either write str += string(&ch, 1) or str += string(1, ch) or str += ch you can find string's constructors here. Sorry for the error code again.
You can parse the file with the ">>" operator pretty nicely if everything is separated by spaces and newlines. Which is how the ">>" operator works. So, yes, you need a loop. Basically you want the loop to work like this:
(I never knew you could do this in Comp Sci 1. It would've saved me so much trouble...I used to do things like what the other answer is doing.)
(I'm also assuming you know how to open a txt file as an ifstream. If not, see http://www.cplusplus.com/reference/iostream/ifstream/open/.)
int temp;
int n = 0;
int x = 1;
while(textfile >> temp) // Each time through the loop, this will make temp
// the next value in the file. It will stop when
// there's nothing more to read.
{
/* Now it's going to go from left to right through the file, so you
need some logic to put it in the right place. you know that every
five numbers start a new column, so:*/
array[x][n] = temp; //Start x at 1 because you're skipping the first column
n++;
if (n == 5) {
n = 0;
x++; //Every five values, move on to the next column
}
Now your array will have the stuff where it needs to be. Just output it according to plan.