std::cin string to int array with variable length input - c++

I have a task where i need to revert a list of variable length numbers. This could be "1 2 3" or "5 6 7 8 9 10".
The sorting itself works fine.
But I can't figure out how to read the user input (with variable length) and then only execute the reverseSort once.
How can I read the user input into an array where each index is based on the space between the numbers?
Here is my code:
#include <iostream>
#include <string>
using namespace std;
bool sorted = true;
int temp;
int * arr;
int arrLength = 5;
int arrs;
// int arr = {1,2,3,4,5};
void reverseSort(int arr[], int n){
sorted = true;
for (int i = 0; i < n-1; i++){
if (arr[(i + 1)] > arr[i]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sorted = false;
}
}
if (!sorted){
reverseSort(arr,n);
}
}
int main(void){
// get user input !?!?!?!?!
cin >> arrs;
cout << arrs;
reverseSort(arr,arrLength);
for (int i = 0; i < arrLength; i++){
std::cout << arr[i] << " ";
}
return 0;
}

If you don't know number of inputs you need struct that can be resized. std::vector is good for it. For adding new data you can use member function push_back.
You can read the input line as std::string (by std::getline) and you can open new stream with read data (std::istringstream). Further one can read values from new stream.
And I think you can use std::sort instead of reverseSort (but for 'reverse' you need use std::greater as comparator).
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <algorithm>
int main(void){
std::vector<int> arrs;
// read only one line
std::string input;
std::getline(std::cin, input);
std::istringstream row(input);
int x;
while (row >> x)
{
arrs.push_back(x);
}
//like your reverseSort
std::sort(arrs.begin(), arrs.end(), std::greater<int>{});
for (auto var : arrs) {
std::cout << var << "; ";
}
return 0;
}

Related

C++ string array about nums

Say the strings is "Asah1234&^%736hsi)(91",
than storage 1234,736,91 in three arrays
In general,i want to put each continuous nums in each array.
Queations: how many arrays i will need,what's the size of each group of numbers,how to make the loop.
I want to write a fuction to do it.
#include<iostream>
using namespace std;
void splitString(string str)
{
string num;
for (int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
num.push_back(str[i]);
}
cout << num << endl;
}
int countnum( string str)
{
string num;
int sum = 0;
for (int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
sum++;
}
cout << sum << endl;
return 0;
}
int main()
{
const int MAXLEN = 100;
char str[MAXLEN];
printf("please enter strings:");
scanf_s("%s", str, MAXLEN);
splitString(str);
countnum( str);
return 0;
}
Maybe I have a misunderstanding here. Then please comment and I will delete the answer.
This is a standard task and will be solved with a regex. It is just the definition of a variable and initialzing this variable with its range constructor. So, a one-liner.
There is no further statement needed.
Please see:
#include <iostream>
#include <string>
#include <regex>
#include <vector>
std::regex re{ R"(\d+)" };
int main() {
// The input string with test data
std::string test{"Asah123&^%736hsi)(918"};
// Define a variable numbers and use the range constructor to put all data in it
std::vector numbers(std::sregex_token_iterator(test.begin(), test.end(), re), {});
// Show the result on the screen
for (const auto& n : numbers) std::cout << n << "\n";
return 0;
}

Displaying all prefixes of a word in C++

I am trying to do is display all the suffixes of a word as such:
word: house
print:
h
ho
hou
hous
house
What I did is:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char cuvant[100];
int i,k;
cin>>cuvant;
for(i=0;i<strlen(cuvant);i++)
{
for(k=0;k<i;k++)
{
if(k==0)
{
cout<<cuvant[k]<<endl;
}else
{
for(k=1;k<=i;k++){
if(k==i) cout<<endl;
cout<<cuvant[k];
}
}
}
}
}
What am I doing wrong?
You're over-complicating it. Here's a simpler way:
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string s;
std::cin >> s;
for (std::string::size_type i = 0, size = s.size(); i != size; ++i)
std::cout << std::string_view{s.c_str(), i + 1} << '\n';
}
If you don't have access to a C++17 compiler, you can use this one:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
int main() {
std::string s;
std::cin >> s;
for (auto const& ch : s) {
std::copy(s.c_str(), (&ch + 1),
std::ostream_iterator<decltype(ch)>(std::cout));
std::cout << '\n';
}
}
Even so, I think it would be better for your learning progress to use a debugger to finger out the problem yourself. Here the problems with your code:
For the i=0 (the first iteration of your outer loop) the for(k=0;k<i;k++) will not be executed at all, as k<0 evaluates to false.
And having a running variable (k) that you change in two for loops that are nested, is most of the time also an indication that something is wrong.
So what you want to do: You want to create each possible prefix, so you want to create n strings with the length of 1 to n. So your first idea with the outer loop is correct. But you overcomplicate the inner part.
For the inner part, you want to print all chars from the index 0 up to i.
int main() {
char cuvant[100];
std::cin >> cuvant;
// loop over the length of the string
for (int i = 0, size = strlen(cuvant); i < size; i++) {
// print all chars from 0 upto to i (k<=0)
for (int k = 0; k <= i; k++) {
std::cout << cuvant[k];
}
// print a new line after that
std::cout << std::endl;
}
}
But instead of reinventing the wheel I would use the functions the std provides:
int main() {
std::string s;
std::cin >> s;
for (std::size_t i = 0, size = s.size(); i < size; i++) {
std::cout << s.substr(0, i + 1) << std::endl;
}
}
For this very simple string suffix task you can just use:
void main()
{
std::string s = "house";
std::string s2;
for(char c : s)
{
s2 += c;
cout << s2 << endl;
}
}
For more complicated problems you may be interested to read about Suffix Tree
Your code is wrong, the following code can fulfill your requirements
#include <iostream>
using namespace std;
int main()
{
char cuvant[100];
int i,k;
cin>>cuvant;
for(i=0;i<strlen(cuvant);i++)
{
for (k = 0; k <= i; ++k)
{
cout<<cuvant[k];
}
cout<<endl;
}
}

C++ determinable array input in one line

I'm pretty new to c++ and can't seem to find correct way to code this. I have array of n digits, my code now:
int main()
{
int n,i;
cin >> n;
int a[n];
for (i=1;i<=n;i++)
{
cin >> a[i];
}
return 0;
}
This way every element of array has to be input in different line, is it possible to put all elements of a array in one line, with space between them.
I am assuming your question is "what is the correct way to do this?"
I would do it this way:
#include <iostream>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
int main()
{
int n;
cin >> n;
vector<int> v;
int i = 0;
int value;
while (i++ < n && cin >> value)
{
v.push_back(value);
}
char const* sep = "";
for (auto item : v)
{
cout << sep << item;
sep = " ";
}
cout << endl;
}
Note that this code is making assumptions that the input is well formed. If you need something that is more robust in handling possibly malicious input, that would require extra effort. This code, as given, will give-up-trying-and-continue which may or may not be suitable for your purposes.
The following code snippet of your program is a Variable Length Array(VLA) and this is only supported in C since ISO C99.
cin >> n;
int a[n];
And as previously pointed out, you can also use std::vector instead.
int main()
{
int size;
std::cin >> size;
int *array = new int[size];
delete [] array;
return 0;
}
References:
http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
How to create a dynamic array of integers
Without using stl container , one can implement like so:
#include <iostream>
#include <string>
#include "stdlib.h"
void GetInput(int* inputs, int n)
{
// store the entered numbers in a char[]
std::string word;
std::cout << "enter numbers (separate by space) ";
std::getline(std::cin, word);
char ch[100];
strcpy_s(ch, word.c_str());
char *temp = ch;
// parse the char[] for integers
for (int i = 0; strcmpi(temp, "") != 0 && i <= n; temp++,i++) {
*(inputs +i) = std::strtol(temp, &temp, 10);
}
}
int main()
{
int n = 3;
int inputs[10];
GetInput(inputs,n);
for (int j = 0; j < n; j++)
std::cout << inputs[j] << " \n";
return 0;
}
Output:

C++ reading char values gives different letters sometimes

I have to write a short routine that will write out only upper case letters in reversed order. I managed to muster up code that somehow works, but whenever I test out my code with one specific input:
7 ENTER a b C d E f G
Instead of getting G E C I get
G (special) r E
I can't see what causes the problem, especially because it works for so many other cases. Here's the code:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
char stringa[n];
int length = 0;
for (int i = 0; i <= n-1; i++) {
char letter;
cin >> letter;
if (isupper (letter)) {
stringa[((n-i) - 1)] = letter;
length = length +1;
} } for ( int i =0; i<=length-1; i++) {
cout << ciag[i]
The main problem is that you are not populating your array correctly.
You are not initializing the content of the array before filling it, so it contains random garbage. Then you are filling specific elements of the array using indexes that are the directly related to each uppercase character's original position in the input, rather than the position they should appear in the output.
Since you are not initializing the array, and the input has mixed lower/upper casing, your array is going to have gaps containing random data:
stringa[0] = G
stringa[1] = <random>
stringa[2] = <random>
stringa[3] = <random>
stringa[4] = E
stringa[5] = <random>
stringa[6] = <random>
stringa[7] = <random>
stringa[8] = C
stringa[9] = <random>
stringa[10] = <random>
stringa[11] = <random>
stringa[12] = <random>
stringa[13] = <random>
stringa[14] = R
stringa[15] = E
stringa[16] = T
stringa[17] = N
stringa[18] = E
stringa[19] = <random>
stringa[20] = <random>
That is what you are seeing appear in your garbled output.
Try something more like this instead:
#include <iostream>
#include <vector>
#include <cctype>
int main()
{
int n;
std::cin >> n;
std::vector<char> stringa(n); // 'char stringa[n];' is not standard!
int length = 0;
for (int i = 0; i < n; ++i)
{
char letter;
std::cin >> letter;
if (std::isupper (letter))
{
stringa[length] = letter;
++length;
}
}
for (int i = length-1; i >= 0; --i)
{
std::cout << stringa[i];
}
return 0;
}
Or:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cctype>
int main()
{
int n;
std::cin >> n;
std::vector<char> stringa(n); // 'char stringa[n];' is not standard!
int length = 0;
for (int i = 0; i < n; ++i)
{
char letter;
std::cin >> letter;
if (std::isupper (letter))
{
stringa[length] = letter;
++length;
}
}
std::reverse(stringa.begin(), stringa.begin()+length);
for (int i = 0; i < length; ++i)
{
std::cout << stringa[i];
}
return 0;
}
Both approaches produces the following array content during the first loop, and then simply output it in reverse order in the second loop:
stringa[0] = E
stringa[1] = N
stringa[2] = T
stringa[3] = E
stringa[4] = R
stringa[5] = C
stringa[6] = E
stringa[7] = G
Alternatively, I would suggest using std::getline() instead of a reading loop to obtain the user's input, and then simply manipulate the resulting std::string as needed:
#include <iostream>
#include <string>
#include <algorithm>
bool IsNotUpper(char ch)
{
return !std::isupper(ch);
}
int main()
{
std::string stringa;
std::getline(std::cin, stringa); // returns "7 ENTER a b C d E f G"
// so std::isupper() will return false for everything not in A-Z
std::setlocale(LC_ALL, "C");
stringa.erase(
std::remove_if(stringa.begin(), stringa.end(), &IsNotUpper),
stringa.end());
// returns "ENTERCEG"
std::reverse(stringa.begin(), stringa.end());
// returns "GECRETNE"
std::cout << stringa;
return 0;
}
Or, if using C++11 and later, you can use a lambda instead of a function for the std::remove_if() predicate:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string stringa;
std::getline(std::cin, stringa);
std::setlocale(LC_ALL, "C");
stringa.erase(
std::remove_if(
stringa.begin(), stringa.end(),
[](char ch){return !std::isupper(ch);}
),
stringa.end());
std::reverse(stringa.begin(), stringa.end());
std::cout << stringa;
return 0;
}
Your algorithm just doesn't make any sense. You are expecting the characters to be in the array with no gaps but you skip an entry in the array when the input isn't a capital letter. Instead, put the capital letters in consecutive slots in the array in the forward direction and then traverse it in reverse order afterwards.

sorting array of strings one off

This code is supposed to make a array of strings, randomly order them, and then print the order. Unfortunately it adds a blank line in one of the spaces ( i think this is getline's doing). Any ideas how to fix that? I tried setting array [0] = NULL; it complains about operators...
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <string>
#include <cstdlib>
using std::cout;
using std::endl;
using namespace std;
void swap (string &one, string &two)
{
string tmp = one;
one = two;
two = tmp;
}
int rand_loc (int size)
{
return (rand() % size);
}
int main()
{
srand(time(NULL));
int size;
cin >> size;
string *array = new string[size];
//array[0] = NULL ;
for (int x = 0; x < size; x++)
{
getline(cin, array[x]);
}
//for (int x = 0; x < size; x++)
//{
// swap (array[rand_loc(size)], array[rand_loc(size)]);
//}
cout << endl;
for (int x = 0; x < size; x++)
{
//out << array[x] << endl;
int y = x + 1;
cout<<y<<"."<<" "<<array[x]<<endl;
}
delete[] array;
}
The first call to getline() will immediately hit the newline that the user entered after inputting size, and will therefore return an empty string. Try to call cin.ignore(255, '\n'); before the first call to getline(). This will skip up to 255 (an arbitrarily selected number) characters until a \n is encountered (and the newline will be skipped as well).
Edit: As #Johnsyweb and #ildjarn point out, std::numeric_limits<streamsize>::max() is a much better choice than 255.