Going to the new c++11 standards [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
CODE-JAM 2010 PROBLEM:
Given a list of space separated words, reverse the order of the words.
INPUT:
The first line of input gives the number of cases, N. N test
cases follow.
OUTPUT:
For each test case, output one line containing "Case #x: "
followed by the list of words in reverse order.
Limits:
N <= 5
INPUT:
3
this is a test
foobar
all your base
OUTPUT:
Case #1: test a is this
Case #2: foobar
Case #3: base your all
#include<iostream.h>
#include<conio.h>
#include<fstream.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
class prog {
char str[50];
public:
void getdata()
{
gets(str);
}
void rev();
void srev();
void display()
{
cout<< str;
}
};
void prog::srev()
{
int i,j,len;
char temp;
len=strlen(str);
for(i=0,j=len-1;i<len/2;i++,j--)
{
temp=str[i];
str[i]=str[j];
str[j]=temp;
}
}
void prog::rev()
{
int i,k=0;
char word[50];
strcat(str," ");
for(i=0;str[i]!='\0';i++)
{
if(str[i]!=' ')
{
word[k]=str[i];
k++;
}
else
{
while(k>0)
{
cout<<word[--k];
}
cout<<str[i];
}
}
}
void main()
{ clrscr();
fstream file;
int n;
cout<<"\n\n\t";
cin>>n;
prog p[10];
file.open("cj.txt",ios::in|ios::out|ios::binary);
for(int i=0;i<n;i++)
{
cout<<"\n\t";
p[i].getdata();
file.write((char*)&p[i],sizeof(p[i]));
}
file.seekg(0);
for(i=0;i<n;i++)
{
cout<<"\n\n\t";
p[i].srev();
p[i].rev();
}
}
I wrote this program in c++98 version, with turbo 3.0 as the IDE. It worked fine giving the desired ouput in the desired limits.
My question is, as C++ has rolled out C++11 Standard, what changes I have to do in my above code?
Also, can anyone provide me some good links to read out about the exact implementations in the libraries, as the changes must be innumerous, at one place?

For a more idiomatic approach, please see Reversing order of words in a sentence. I modified Stefan's answer a little bit:
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
int main()
{
std::string sentence = "Your sentence which contains ten words, two of them numbers";
std::istringstream stream(sentence);
std::vector<std::string> words;
std::copy(std::istream_iterator<std::string>(stream),
std::istream_iterator<std::string>(),
std::back_inserter(words));
std::reverse(words.begin(), words.end());
for ( size_t i(0); i < words.size(); ++i )
{
std::cout << words[i] << " ";
}
std::cout << "\n";
}
Also, since the problem from what I understand specifies a max amount of letters/words that will be given, you can get rid of std::reverse:
words.resize(20); // replace 20 with max amount
std::copy(std::istream_iterator<std::string>(stream),
std::istream_iterator<std::string>(),
words.rbegin());
Two other contrived examples:
std::reverse_copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, " "));
std::copy(words.rbegin(), words.rend(), std::ostream_iterator<std::string>(std::cout, " "));

Your code needs considerable revision to follow C++98. At least offhand, I don't see any reason it would need further revision to follow C++11, though you might be able to make the code a little more readable using some of the new features of C++11.
In C++98/03, I'd probably write the code something like this:
int main() {
int num;
std::cin >> num;
for (int i=0; i<num; i++) {
std::string line;
std::getline(line, std::cin);
std::istringstream in(line);
std::vector<std::string> words((std::istream_iterator<std::string>(in)),
std::istream_iterator<std::string>());
std::copy(words.rbegin(), words.rend(),
std::ostream_iterator<std::string>(std::cout, " "));
}
}
In going to C++11, the primary change I'd make would be to use "uniform initialization":
std::vector<std::string> words{std::istream_iterator<std::string>(in),
std::istream_iterator<std::string>()};
A few people have written code to (for one example) use a range-based for loop in cases like this, so the loop would end up something like:
for (auto i : range(0, num))
I guess if you had a lot of other code that could use this, it might be worthwhile, but I see little point in it for one loop.

Related

How do you allow comma to be used for user input for integer based input c++?

I am pretty new to c++ and I am trying to make a program that prints out the number based on user input. But when you add a , it breaks the code since it is not part of integers. What should I do?
I made a simplified code because I want to do more with the integers:
#include <iostream>
using namespace std;
int main(){
int player_input;
cout << "Insert the number" << endl;
cin >> player_input;
cout << player_input;
return 0; //the code doesn't work if you add a comma in cin when you run such as "3,500"
}
Read the input in as a string:
std::string input;
std::cin >> input;
Remove the commas, using the erase-remove idiom:
input.erase(std::remove(input.begin(), input.end(), ','), input.end());
which from C++20 you can write like this:
std::erase(input, ','); // C++20
Convert the string to an int:
int player_input = std::stoi(input);
With <locale>, you might do:
#include <locale>
template<typename T> class ThousandsSeparator : public std::numpunct<T> {
public:
ThousandsSeparator(T Separator) : m_Separator(Separator) {}
protected:
T do_thousands_sep() const override { return m_Separator; }
std::string do_grouping() const override { return "\03"; }
private:
T m_Separator;
};
int main() {
ThousandsSeparator<char> facet(',');
std::cin.imbue(std::locale(std::cin.getloc(), &facet));
int n;
std::cin >> n;
// ...
}
Demo
I think #Jarod42 is on the right general track, but I don't think there's usually a good reason to define your own locale for this task. In most cases you're doing to have a pre-defined locale you can use to do the job. For example, this code:
#include <locale>
#include <iostream>
int main() {
std::cin.imbue(std::locale("en-US"));
int i;
std::cin >> i;
std::cout << i << "\n";
}
...let's me enter a number like 3,400, and it'll print it back out as 3400, to show that it read all of that as a single number.
In a typical case, you'd probably want to simplify things even a bit further by using a nameless locale (std::cin.imbue(std::locale(""));, as this will normally at least try to use a locale matching the what the operating system is configured for, so it would support an American entering 3,400, and (for example) a German entering 3.400 instead.

Printing exactly same as input

This is my answer for a question at Baekjoon.
The question was to write a program that prints exactly same as input. The input can be as big as 100 lines and each line contains at most 100 characters(numbers , alphabet, space). No line starts or ends with a space.
example input)
Hello
nice too meet
ya
example output)
Hello
nice too meet
ya
Below is my code for the question. I've tested all the cases that could happen within my knowledge except 100 lines of 100 characters. It worked for me. But it keeps failing the test. Can anyone please find what the cause is?
#include <iostream>
using namespace std;
int main()
{
char* line[100];
int count=0;
for (int i = 0; cin.getline((line[i]= new char), 100); i++,count++) {
if (cin.eof()) break;
}
for(int i=0; i<count;i++){
cout << line[i] << endl;
}
return 0;
}
Learn the standard library. C++ is all about not re-inventing wheels. There's a buffer called std::ostringstream that will do it all, without all those assumptions about the input. Plus, it will be highly optimized for streaming.
#include <iostream>
#include <sstream>
int main() {
std::ostringstream buffer{};
buffer << std::cin.rdbuf();
std::cout << buffer.str();
return 0;
}
... or (less efficiently), you could use a string as your buffer. Lot's of ways to do this.
#include <string>
#include <iostream>
int main() {
std::string buffer{};
{ char ch;
while (std::cin.get(ch)) buffer.push_back(ch);
}
std::cout << buffer;
return 0;
}

Enter a string and divide it in words [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I need to code a program based which can compare words of a sentence or paragraph to a database, as if it were a text corrector. My problem here is that I have to enter on the console the text I want to correct as a string and then divide it in words stored in a vector of strings in C++. I tried a thousand ways but I cannot get it done.
Here is the code I last tried:
std::cout << "Enter the text: ";
std::string sentence;
std::vector<std::string> vText;
while (getline(std::cin, sentence)){
std::stringstream w(sentence);
std::string word;
while(w >> word)
vText.push_back(word);
}
When I execute this code, I got nothing, as if the program did nothing. Can you help me please?
This is the final thing (a piece):
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
int main(){
std::cout << "Introduzca una frase: ";
std::string frase;
std::vector<std::string> vTextoAnalizar;
while (getline(std::cin, frase)){
std::stringstream w(frase);
std::string palabra;
while(w >> palabra)
vTextoAnalizar.push_back(palabra);
}
for (int i=0;i<vTextoAnalizar.size();i++){
std::cout << vTextoAnalizar[i] << std::endl;
}
return 0;
}
Firstly, welcome to stack exchange. Your question has been down voted as you have not made a reasonable effort to ask a good question.
Please take particular note of How to create a Minimal, Complete, and Verifiable example.
I think what you are trying to do is something like this:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
std::vector<std::string> read_text() {
std::cout << "Enter the text: ";
std::string sentence;
std::string word;
std::vector<std::string> vText;
while(getline(std::cin, sentence)){
std::stringstream ss(sentence);
while ( getline( ss, word, ' ' ) ) {
if (word.compare("quit") == 0)
return vText;
vText.push_back(word);
}
}
}
int main() {
std::vector<std::string> test_vector = read_text();
std::cout << "Vector : " << std::endl;
for (int i=0;i<test_vector.size();i++){
std::cout << test_vector[i] << std::endl;
}
}
This will split on spaces, and add your words to the vector at the end of each sentence. I imagine that there are more intelligent ways of parsing, but this should get your test code working.
Hope that helps.

Elegant solution to take input to a vector<int>

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;
}

Make array as big as the input using 'cin' in c++

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);