How to use vector<vector<string>> in c++? - c++

I saw in c++ code the following:
vector<vector<string>> arr(n);
I was unable to understand how to use it...
Can anyone explain what is it and how to use var arr?

This is definition of 2 dimension-array of strings with size n.
You can use all places in the upper vector as another string vector.
Look at the following example:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string a = "AAAA";
string b = "BBBB";
string c = "CCCC";
int n = 3;
vector<vector<string>> arr(n);
arr[0].push_back(a); // I add string 'a' to end of first vector in 'arr'
arr[0].push_back(b);
arr[1].push_back(c);
for (int i = 0; i < arr[0].size() ; i++) { // print all string in first vector of 'arr'
cout << arr[0][i] << " ";
}
}

Related

How can I convert an char array to string without dealing with the string as an array

int main() {
char arr[10] = {};
string str;
arr[0] = 'h';
arr[1] = 'e';
arr[2] = 'y';
for (int i = 0; i < 10; i++) {
str[i] = arr[i];
}
cout << str;
}
Why this code is not printing hey?
I didn't forget to include the libraries I just put the important part of the code.
when I try to cout str[1] as an example it cout 'e' but when I try to cout the string as it is it doesn't print anything.
I apologize in advance if my explanation is a bit vague but you forgot to include the <iostream> and <string> libraries in your header. Also, since you are using the string library, you must include the using namespace std; within the scope of your string str;. There is a bit more optimization that you can do to your code. For example, in this case, it is optimal to iterate up to the size of your array instead of iterating through to 10 as most of your array is empty. Also, because you are adding char values to a string object, you can just concatenate the empty string with the value at arr[i].
#include <iostream>
#include <string>
int main ()
{
using namespace std; //must include this as string object requires it
char arr[10];
string str;
arr[0]='h';
arr[1]='e';
arr[2]='y';
for (int i = 0; i < sizeof(arr); i++)
{
str += arr[i]; //adds arr[i] to the end of str
}
cout << str; //prints string
}
I hope this helps and was clear enough!

std::cin string to int array with variable length input

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

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

How do I read a stringstream into a char *[40] / char ** array?

I am working on creating a UNIX shell for a lab assignment. Part of this involves storing a history of the past 10 commands, including the arguments passed. I'm storing each command as a C++ string, but the parts of the program that actually matter, and that I had no input in designing (such as execve) use char * and char ** arrays exclusively.
I can get the whole command from history, and then read the program to be invoked quite easily, but I'm having a hard time reading into an arguments array, which is a char *[40] array.
Below is the code for a program I wrote to simulate this behavior on a test string:
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
char *chars[40];
string test = "Hi how are you";
stringstream testStream;
testStream << test;
int i = 0;
while (true)
{
string test_2;
testStream >> test_2;
if (testStream.fail())
{
break;
};
chars[i] = (char *)test_2.c_str();
i++;
}
for (int i=0; i < 4; i++)
{
cout << chars[i];
}
cout << "\n";
}
I get the feeling it has something to do with the array being declared as an array of pointers, rather than a multi-dimensional array. Am I correct?
This line:
chars[i] = (char *)test_2.c_str();
leaves chars[i] 'dangling' when you go back round the loop or fall off the end. This is because test_2.c_str() is only valid while test_2 is in scope.
You'd do better to do something like this:
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
int main()
{
std::vector <std::string> args;
std::string test = "Hi how are you";
std::stringstream testStream;
testStream << test;
int i = 0;
while (true)
{
std::string test_2;
testStream >> test_2;
if (testStream.fail())
break;
args.push_back (test_2);
i++;
}
auto char_args = std::make_unique <const char * []> (i);
for (int j = 0; j < i; ++j)
char_args [j] = args [j].c_str ();
for (int j = 0; j < i; ++j)
std::cout << char_args [j] << "\n";
}
Now your vector of strings remains in scope while you are building and using char_args.
Live demo

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.