I compiled the following code with g++ 12.2.1:
#include <iostream>
#include <ranges>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
std::vector<int> vi;
std::ranges::copy(std::views::istream<int>(std::cin) | std::views::take(3), std::back_inserter(vi));
for (auto i : vi)
std::cout << i << ' ';
}
Input:
1 2 3
4
Output: 1 2 3
Why do I have to enter 4 numbers instead of 3 and discard the last one? How to solve?
When you finish typing 1 2 3, views::istream<int>(std::cin) | views::take(3) did not reach the end, because its iterator just points to the last element and doesn't pass the end.
You can use CTRL+D (for linux) or CTRL+Z (for Windows) to terminate the input like
1 2 3
Ctrl + D
Related
I have a couple of problems, that I think are closely connected, but I couldn't get them fixed following what I previously found on the website.
My problems are related to the double use of cin in my main function. I need to read numbers from keyboard in order to either build small vectors or store single coefficients. I cannot know in advance the length of the vectors that I am going to build.
Here are the lines involved:
#include <vector>
#include <iostream>
#include <limits>
int main() {
...
double a=0;
std::vector<double> coefficients;
while (std::cin>>a) {
coefficients.push_back(a);
}
...
std::vector<double> interval;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
while(std::cin>>a) {
interval.push_back(a);
}
std::cout<<interval.size()<<std::endl;
std::cout<<*interval.cbegin()<<" "<<*(interval.cend()-1)<<std::endl;
...
}
I am using both macOS with g++ 6.3.0 and Linux with g++ 5.3.0. The flags I send to the compiler are -Wall -std=c++14 -o.
On the macOS machine the second cin is completely skipped, while on the Linux one the second reading process does not behave like it is expected to. I mean that if i give -1 1 at the second cin, the printed vector size is 0 and, obviously, the program stops because of a segmentation fault.
At each cin I enter the requested numbers in a single line, like 1 0 0 1, then press enter and then ctrl+D.
Thanks in advance to all! :)
Your call of std::cin.ignore(...) set the fail bit of the stream. This makes it impossible to enter the loop. You need to move the std::cin.clear() call right before the loop, in order to make it run. Also you have an out-of-bound read when there are no data in the second container.
#include <vector>
#include <iostream>
#include <limits>
#include <string>
int main() {
double a=0;
std::vector<double> coefficients;
while (std::cin>>a) {
coefficients.push_back(a);
}
std::cout << coefficients.size() << '\n';
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'X');
std::cin.clear();
char c;
std::cin>>c;
if(c != 'X')
{
std::cerr << "Invalid separator\n";
return 1;
}
std::vector<double> interval;
while(std::cin >> a) {
interval.push_back(a);
}
std::cout<< interval.size()<<std::endl;
if(interval.size())
std::cout<<*interval.cbegin()<<" "<<*(interval.cend()-1)<<std::endl;
return 0;
}
With the following data file,
$ cat data.txt
12 23
42
X
1 2
3 4 5
this output is generated:
$ ./a.out < data
3
5
1 5
You need to add a linefeed '\n' as a second parameter to cin.ignore() so it kills the ignore on an enter press
Why does the following program output
1 2 3 4 4 4
and not
1 2 3 4 5 6
for each of the values provided?
#include <iostream>
#include <iterator>
#include <vector>
#include <string>
#include <sstream>
int main()
{
std::vector<int> numbers;
std::stringstream ss;
ss << " 1 2";
std::istream_iterator<int> start{ss},end;
ss << " 3 4";
numbers.push_back(*start++);
numbers.push_back(*start++);
numbers.push_back(*start++);
ss << " 5 6";
numbers.push_back(*start++);
numbers.push_back(*start++);
numbers.push_back(*start++);
std::cout << "numbers read in:\n";
for (auto number : numbers) {
std::cout << number << " ";
}
std::cout << "\n";
}
Its not iterator doing as you might have thought. It's ss that is invalidated after iterator progressing. Initialiy stringstream constains 1 2 3 4 and is in valid state. But is invalidated by the third iterator dereference, so next operation ss << " 5 6" fails. To fix this, clear flags of stringstream variable:
//...
ss.clear();
ss << " 5 6";
//...
Output:
numbers read in:
1 2 3 4 5 6
Use stream iterators with some caution. When a valid istream_iterator reaches the end of the underlying stream, it becomes equal to the end-of-stream iterator.
And then dereferencing or incrementing it further invokes undefined behavior, in your case you just got a copy of the most recently read object.
Also keep in mind that the first object from the stream is read when the iterator is constructed.
I written a code to create two random number with a given range. I want to write the output result (two random numbers). In script file, I want to write the output in same line for each iteration as my expected result
My current output is
1 0
1 0
2 1
2 3
0 0 //output of second iteration
1 1
2 2
1 3
My expected result is
1 0 0 0
1 0 1 1
2 1 2 2
2 3 1 3
This is my full code
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <time.h> /* time */
#define random(x) (rand()%x)
int main(int argc, char **argv) {
unsigned int time_ui = static_cast<unsigned int>( time(NULL) );
srand( time_ui );
int number1;
int number2;
int range=atoi(argv[1]);
number1 = random(range);
number2 = random(range);
//std::cout<< number1 << "\t" <<number2;
std::ofstream myfile;
myfile.open ("report.txt", std::ios::app);
myfile << number1 << "\t" <<number2<<'\n';
myfile.close();
return 0;
}
My script file is
#!/bin/bash
a=1
iter=0
for ((iter; iter <= 1; iter++))
do
a=1
while [ $a -lt 4]
do
./random_num $a
a=`expr $a + 1`
done
done
Note that there is a newline character that you output in your C++ code, which makes it nearly impossible to "unoutput". I would suggest moving the logic from the bash into the C++ code or vice versa. C++ has options such has setfill which can help you control this.
I have a text file which that contains only numbers inside , and i have successfully pulled the numbers from the file and stored it inside an array:
my problem is that the array is "string" and i cant do mathematical operations on the array like Addition and Subtraction
I have tried to use atoi(array[i][j].c_str()) to convert it to intger
but it gives me only the first digit of a number!
my program looks like this for now , its a mess I know :(
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
int main()
{
ifstream iFile("input.txt");
string line;
string array[7][7];
for (int i=0;i<7;i++){
for (int j=0;j<6;j++){
getline(iFile,line);
if (!line.empty()){
array[i][j]=line;
}
else {
break;
}
}
}
cout<<"number of processes is: "<<array[0][0]<<endl;
cout<<"resource types: "<<array[1][0]<<endl<<endl;
cout<<"Allocation Matrix:"<<endl;
cout<<" A B C D"<<endl;
cout<<"0: "<<array[2][0]<<endl;
cout<<"1: "<<array[2][1]<<endl;
cout<<"2: "<<array[2][2]<<endl;
cout<<"3: "<<array[2][3]<<endl;
cout<<"4: "<<array[2][4]<<endl;
cout<<"Max Matrix:"<<endl;
cout<<" A B C D"<<endl;
cout<<"0: "<<array[3][0]<<endl;
cout<<"1: "<<array[3][1]<<endl;
cout<<"2: "<<array[3][2]<<endl;
cout<<"3: "<<array[3][3]<<endl;
cout<<"4: "<<array[3][4]<<endl;
cout<<"Need Matrix:"<<endl;
cout<<" A B C D"<<endl;
//cout<<"0: "<<array[3][1]+array[2][1]<<endl;
//int c= atoi(array[3][1].c_str());
//int c2= atoi(array[3][1].c_str());
//cout<<c+c2<<endl;
return 0;
}
my input.txt file looks like this:
5
4
0 0 1 2
1 0 0 0
1 3 5 4
0 6 3 2
0 0 1 4
0 0 1 2
1 7 5 0
2 3 5 6
0 6 5 2
0 6 5 6
1 5 2 0
1:0 4 2 0
edit:
note:if there is an empty line >> stop!
the program is based on banker algorithm which takes the first number from the input.txt as the numbers of of processes
then takes the second number as the numbers of of resource types
then takes the next numbers that there is no empty line between them as Allocation Matrix
then takes the next numbers that there is no empty line between them as max Matrix
and here is my problem when i want do Subtraction between Allocation Matrix and max Matrix because both are strings !
as for 1:0 4 2 0 it means do some operations with process number 1
You can use atoi but in c++ you have better options.
in c++ you can easily use stringstream to convert these types.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int convert_str_to_int(const string& str) {
int val;
stringstream ss;
ss << str;
ss >> val;
return val;
}
int main () {
string str = "1024";
int val = convert_str_to_int(str);
cout << "Val is: " << val << ", val/2 is " << val/2 << endl;
}
I am trying to learn stringstream and I have the following code:
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
stringstream os;
os.str("Purohit");
os << "Vipul" << endl;
cout << os.str() << endl;
}
When I compile it and run it, I get the following output:
Vipul
t
Why? Shouldn't this output Purohit Vipul?
This is because str method replaces the content of stringstresm, without placing the buffer pointer for the subsequent writes at the end of the stream. That is why when you output "Vipul\n" it writes over the "Purohit" string that you placed into the stream earlier:
Initial state
0 1 2 3 4 5 6
P u r o h i t
^
After the << write:
0 1 2 3 4 5 6
V i p u l \n t
You could call seekg to set the position before appending the "Vipul" string, but an easier fix would be to use << for both writes.