I'm prettty new to c++ programming and haven't got grip on the most basic techniques.
My problem is that I want to read characters into a array and make that array just as long as the input. For example if the input would be 'a', 'b' and 'c' then the length of the array would be 3. In java this would be like this for integers using StdIn package:
int[] n = StdIn.readInts(); //enter the numbers 5,6,7,8 f.x.
StdOut.println(n.length); //would print 4
Hopefully I was clear enough.
In C++ it's very easy to do:
std::vector<int> int_vector;
std::copy(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_inserter(int_vector));
References:
std::vector
std::copy
std::istream_iterator
std::back_inserter
You can easily use std::vector to store your input. Using push_back or emplace_back, for example, you'll be able to push as many elements as you need. You'll be able to retrieve the size of the array via the size member function.
Here's an example:
std::vector<char> vector;
for (int i = 0; i < 3; i++) {
char buffer;
std::cin >> buffer;
vector.push_back(buffer);
}
The above code will ask for 3 characters and store them into vector. The vector interface has a convenient "array-like" interface that you can use. For example to retrieve the third element you can use vector[2].
If you take a look at the implementation of StdIn.readInts, you see it can be described in two steps:
read all the "tokens" from the standard input, where "tokens" are strings (for every line) split by a regex, then
for each tokens, interpret it as integer (parseInt) and "append" to an array (since it knows the number of tokens from the previous step, it creates an array that has enough room for the right number of ints)
This can be mimicked in C++ coding a similar class, with similar methods, or doing the above steps in the moment you need them, considering that std::vector are maybe closer to Java arrays than C++ arrays are, and that std::vector can grow dinamycally.
In your example, to read a list of ints separated by "white spaces",
#include <iostream>
#include <vector>
int main()
{
std::vector<int> n;
int tmp;
while(std::cin >> tmp) {
n.push_back(tmp);
}
std::cout << n.size() << "\n";
return 0;
}
suffices (but look at other answers, there's a nice std::copy solution in the air), but if you want to imitate Java behaviour (if I intended it correctly reading swiftly the code), something like
#include <iostream>
#include <vector>
#include <sstream>
int main()
{
std::vector<int> n;
// read in the "pieces" as string
std::vector<std::string> ns;
std::string tmps;
while(std::cin >> tmps) {
ns.push_back(tmps);
}
// pre C++11 way... try to interpret the "pieces" as int
for (std::vector<std::string>::const_iterator it = ns.begin();
it != ns.end();
++it)
{
int tmp;
if (std::istringstream(*it) >> tmp) {
n.push_back(tmp);
}
}
std::cout << n.size() << "\n";
// post C++11 way, just to test...
for (auto v : n) std::cout << v << "\n";
return 0;
}
should be closer to what Java StdIn.readInt() does (again, according to my understanding of it reading the code on the fly).
If you want to read all the numbers the user inputs, then you can do this:
int number;
std::vector<int> numbers;
while (std::cin >> number)
numbers.push_back(number);
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 accept the input from user
where first line will be Integer to indicate number of testcases
if number is 3
Input will be like
3
Hello world
hey there, I am John
have a nice day
I am using getline to read the input
My code
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int n;
cin >> n;
vector<string> arr;
for(int i=0; i<n; i++){
string s;
getline(cin, s);
arr[i] = s;
}
}
Error:
3
Segmentation fault(core dumped)
arr is an empty vector, so arr[i] = s; is going to access out of bounds. The [] operator does not grow the vector. It can only be used to access already existing elements.
You can't create an element of a vector using the [] indexing operator; your line arr[i] = s; is trying to assign a string to an element that doesn't (yet) exist.
There are several ways around this: first, you could use the push_back function to add a new element to the end of the vector, in each loop; second, you could use the resize member to pre-allocate a specified number of elements (which you can then use in the arr[i] = s; line); third - and perhaps simplest - you can 'pre-allocate' the elements of the vector by specifying the number of elements in the declaration (constructor), like this:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string> // Need this for the "getline()" function definition
using namespace std;
int main()
{
size_t n; // Indexes and operations on std::vector use "size_t" rather than "int"
cin >> n;
cin.ignore(1); // Without this, there will be a leftover newline in the "cin" stream
// std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // More precise, actually!
vector<string> arr(n);
// arr.resize(n); // Alternative to using 'n' in constructor
for (size_t i = 0; i < n; i++) {
string s;
getline(cin, s);
arr[i] = s;
}
for (auto s : arr) cout << s << endl; // Just to confirm the input values
return 0;
}
There are also a few other issues in your code that I have 'fixed' and commented on in the code I posted. Feel free to ask for further clarification and/or explanation.
EDIT: On the use of the cin.ignore(1); line I added, see Why does std::getline() skip input after a formatted extraction? (and the excellent answers given there) for more details.
I am using
string temp ;
vector <int> arr ;
while(getline(cin,temp,' '))
{
arr.push_back(temp);
}
but it's not working as I expected and I am getting a compile time error
no matching function for call to 'std::vector<int>::push_back(std::string&)'|
Please provide a solution in C++ or C
This takes advantage of std::stoi which is part of the C++11 standard. stoi simply takes a string representation of an integer and turns it into its integer form. i.e. "123" -> 123.
string temp ;
vector <int> arr ;
while(getline(cin,temp,' '))
{
arr.push_back(stoi(temp));
}
You have almost got it right, but your vector type is wrong, you are storing strings, not integers.
string temp;
vector<string> arr;
while(getline(cin,temp,' '))
{
arr.push_back(temp);
}
You probably want to read the line as a string first, then separate the integers and afterwards push them into the array.
C++11 (I think?) solution:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <sstream>
int main()
{
std::vector<int> arr;
for (std::string temp; std::getline(std::cin, temp); )
{
std::istringstream iss(temp);
std::copy(std::istream_iterator<int>(iss), std::istream_iterator<int>(), std::back_inserter(arr));
for (const auto & elem : arr)
std::cout << elem << ' ';
std::cout << '\n';
arr.clear();
}
return 0;
}
Problem is you now need a way to stop the infinte loop, but that can be easily solved with a simple condition. It's up to you.
I am trying to create an vector <int> whose size is not pre-defined. It should take in numbers as long as there are numbers in the input terminal and should stop reading when I hit Enter. I tried many solutions including the ones given here and here. In the second case, I can enter a non-integer to terminate the input to the vector. If I use the first solution (code added below), it listens to the input indefinitely.
Code:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
using std::cout;
using std::cin;
using std::vector;
using std::string;
using std::istringstream;
int main()
{
//cout << "Enter the elements of the array: \n";
//vector <int> arr ( std::istream_iterator<int>( std::cin ), std::istream_iterator<int>() );
vector <int> arr;
string buf;
cout << "Enter the elements of the array: \n";
while(getline(cin, buf))
{
istringstream ssin(buf);
int input;
while(ssin >> input)
{
arr.push_back(input);
}
}
cout << "The array: \n";
for(size_t i = 0; i < arr.size(); i++)
{
cout << arr[i] << " ";
}
return 0;
}
1) I don't feel that typing in a character or a very large number to end listening to input is very elegant. However, the solution with istringstream seems to be the way to go. I am not sure why it doesn't work.
2) Is there any way to detect the Enter from keyboard to terminate listening to input? I tried using cin.get(), but it changed the numbers in the vector.
3) Any other methods or suggestions?
Let's take things one step at a time.
We want to read up until enter is pressed. That means you probably want to use std:getline to read a line.
Then you want to parse it, so you want to put the line into an istringstream.
Then you want to read numbers. While you're reading them, you apparently want to ignore anything other than digits, and you want to keep reading even if you get to a group of digits that can't be converted to a number.
That leaves a few things that aren't entirely clear, such as what to do with that input that's too large to convert? Do you want to just skip to the next? Do you want to read some digits as a number, then read remaining digits as another number?
Likewise, what do you want to do if you get something like "123a456"? Should it be skipped completely, read as "123" (and the "a456" ignored)? Should it be read as "123" and "456", and just the "a" ignored?
For the moment let's assume that we're going to read space-separated groups of characters, and convert all those to numbers that we can. If something is too big to convert to a number, we'll ignore it (in its entirety). If we have a group like "123a456", we'll read the "123" as a number, and ignore the "a456".
To achieve this, we can do something like this:
std::string line;
std::getline(infile, line);
std::istringstream input(line);
std::string word;
std::vector<int> output;
while (input >> word) {
try {
int i = std::stoi(word);
output.push_back(i);
}
catch (...) {}
}
For example, given input like: "123a456 321 1111233423432434342343223344 9", this will read in [123, 321, 9].
Of course, I'm just taking a guess about your requirements, and I haven't worked at making this particularly clean or elegant--just a straightforward implementation of one possible set of requirements.
Please see the comments from #LearningC and #M.M.
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
using std::cout;
using std::cin;
using std::vector;
using std::string;
using std::istringstream;
int main()
{
vector <int> arr;
string buf;
int input;
cout << "Enter the elements of the array: \n";
getline(cin, buf);
istringstream ssin(buf);
while(ssin >> input)
{
arr.push_back(input);
}
cout << "The array: \n";
for(size_t i = 0; i < arr.size(); i++)
{
cout << arr[i] << " ";
}
return 0;
}
I am writing a simple console application to read 3 words and keep them in an array. But after taking three inputs from the console it only displays the third word three times in the console. For example, if I give the input: "one", "two" "three" the output shows only "three" 3 times).
Here is my code:
int main(int argc, char *argv[])
{
char* input[30];
char word[30];
int i=0;
for(i=0; i<3 ;++i)
{
cin >> word;
input[i] = word;
}
input[i] = 0;
i=0;
while(input[i])
{
cout << input[i] << endl;
i++;
}
return 0;
}
What I am doing wrong here? Thanks for any help.
You only have one buffer ( char word[30] ), which you are overwriting each time.
When you do:
input[i] = word;
You're assigning the address of the first element in that one and only buffer to each element in input (arrays degrade to pointers when you use the bare name). You end up with three copies of the same address in input[] (which is address of word, which contains the last thing your read from cin)
One approach to fix this would be to use strdup() and assign the newly allocated string to your input[i]
for(i=0; i<3 ;++i)
{
cin >> word;
input[i] = strdup(word);
}
Also ... if you only are going to have three input "words" you only need an array of 3 char pointers:
char *input[3];
and your output loop would look much like your input loop:
for(i=0; i<3 ;++i)
{
cout << input[i] << endl;
}
Edit: Note that this answer was based on your wanting to use arrays. If this isn't homework that requires that, see bobbymcr's answer - when in C++, use C++.
You marked your question as "C++" (not "C") so I will recommend that you actually use C++ idioms to do this. Modern programs should not be using raw char arrays and pointers except for low level programming and interoperability with legacy or barebones C APIs.
Consider using string and vector as they will make your life much easier. Here is a reimplementation of your program using these types. Aside from the iterator stuff (which I admit is a bit strange until you get used to it), it should seem a lot clearer than the equivalent using char *, etc.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main(int argc, char ** argv)
{
vector<string> input;
for (int i = 0; i < 3; ++i)
{
string word;
cin >> word;
input.push_back(word);
}
for (vector<string>::const_iterator it = input.cbegin(); it != input.cend(); ++it)
{
cout << *it << endl;
}
return 0;
}
The problem is here:
char* input[30];
You maybe tempted to think that this is array of character array, but in essence it's not.
You would either need to dynamically allocate space for the array, or simply use two dimensional character array(fixing the max number of words that you can have).
char input[30][30]; // maximum 30 words having at most 29 characters each