insert string into vector character by character - c++

I'm trying to insert the characters of the string into a char vector but place the letters in reverse order . can anyone tell me why this doesn't work
int main()
{
string a = "Hello";
vector<char> arr(5);
for(int i = 4 ; i == 0 ; i--)
{
arr.push_back(a[i]);
cout << arr[i];
}
return 0;
}
im trying to push back the character in reverse order 1 by 1

Their are several problems with your code:
you are creating a vector whose size is initially 5, and then you are attempting to push 5 additional chars into it, for a total of 10 chars. You need to either:
initialize it's capacity instead of its size.
initialize the size as you are, but use arr[4-i] instead of arr.push_back() inside your loop.
your loop is never entered at all, since i == 0 is never true.
Try something more like this instead:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello";
size_t len = a.size();
vector<char> arr;
arr.reserve(len);
for(int i = len-1; i >= 0; i--) {
arr.push_back(a[i]);
}
for(size_t i = 0; i < len; ++i) {
cout << arr[i];
}
return 0;
}
Alternatively:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello";
size_t len = a.size();
vector<char> arr(len);
for(int i = len-1; i >= 0; i--) {
arr[len-1-i] = a[i];
}
for(size_t i = 0; i < len; ++i) {
cout << arr[i];
}
return 0;
}
Another way to deal with this in a more C++-ish way is to use iterators instead:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello";
vector<char> arr;
arr.reserve(a.size());
for(auto iter = a.rbegin(); iter != a.rend(); ++iter) {
arr.push_back(*iter);
}
for(auto ch : arr) {
cout << ch;
}
return 0;
}
Alternatively:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello";
vector<char> arr(a.size());
auto arr_iter = arr.begin();
for(auto a_iter = a.rbegin(); a_iter != a.rend(); ++a_iter, ++arr_iter) {
*arr_iter = *a_iter;
}
for(auto ch : arr) {
cout << ch;
}
return 0;
}
And then you can get rid of the manual loops altogether:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
int main() {
string a = "Hello";
vector<char> arr;
arr.reserve(a.size());
copy(a.rbegin(), a.rend(), back_inserter(arr));
cout.write(arr.data(), arr.size());
return 0;
}
Alternatively:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
string a = "Hello";
vector<char> arr(a.size());
copy(a.rbegin(), a.rend(), arr.begin());
cout.write(arr.data(), arr.size());
return 0;
}
Alternatively:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello";
vector<char> arr(a.rbegin(), a.rend());
cout.write(arr.data(), arr.size());
return 0;
}

I'm not sure why you're complicating matters when a vector is perfectly capable of taking an iterator in the constructor? The vast majority of your code can therefore be replaced with a simple:
vector<char> arr(a.rbegin(), a.rend());
The complete program below shows this in action:
#include <iostream>
#include <string>
#include <vector>
using std::cout; using std::string; using std::vector;
int main() {
string a = ")-: yug emosdnah a si xaP";
vector<char> arr(a.rbegin(), a.rend());
for (auto ch: arr) cout << ch;
cout << '\n';
}

for(int i = 4 ; i == 0 ; i--)
That means to keep going while i is equal to zero - but i starts out at four, so the for loop terminates immediately.
You probably meant
for(int i = 4 ; i >= 0 ; i--)

Related

Converting all to uppercase

Hey so I'm very new to c++ and trying to convert a word a user enters to all uppercase
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int size=10;
int i =0;
char arr[size];
cout<<"Enter a word"<<endl;
cin.get(arr,size);
for(i = 0; i < 10; i++)
{
if(islower(arr[i]))
{
cout<<toupper(arr[i])<<endl;
}
}
return 0;
}
I'm getting numbers when I run this. What do I fix?
Don't write C-like C++, use the standard library to your advantage. Use an std::string and do something like this instead:
#include <iostream>
#include <algorithm>
#include <string>
int main() {
std::string input;
std::cin >> input;
std::transform(input.begin(), input.end(), input.begin(), ::toupper);
std::cout << input << std::endl;
return 0;
}
Or alternatively with a lambda:
std::transform(input.begin(), input.end(), input.begin(), [](unsigned char c){ return std::toupper(c); });
It is the time to learn one of bit-wise applications
#include <iostream>
#include <string>
int main()
{
int mask = 0xDF;
std::string str = "aBcdeqDsi";
for(int i(0); i < str.size(); ++i)
std::cout << static_cast<char>(str[i] & mask);
std::cout << std::endl;
return 0;
}

String concatenation does not work

I'm trying to concatenate two strings and the result string is not concatenated at all. I don't know where is the problem. The line that is a problem is that line
tempString = tempString+ result;
Here is the full code
#include <iostream>
#include <cstdio>
#include <list>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <limits>
#include <functional>
#include <algorithm>
#include <cmath>
#include <string>
#include <ostream>
#include <sstream>
#include <bitset>
#include <numeric>
#include <fstream>
#include <stdint.h>
using namespace std;
#define OTHER 3
#define SQUARE 1
#define RECTANGLE 2
static std::string accum(const std::string &s)
{
string result = "";
string tempString = "";
for (size_t i = 0; i < s.length(); i++)
{
int temp = i+1;
if (i == 0)
{
result[i] += s[i];
result[i] = toupper(result[i]);
tempString = tempString+ result;
tempString += "-";
}
else
{
if (i!=1)
{
tempString += '-';
}
while (temp > 0)
{
tempString+=s[i];
temp--;
}
}
}
for (int i = 0; i < tempString.size(); i++)
{
if (tempString[i] == '-')
{
tempString[i + 1] = toupper(tempString[i + 1]);
}
}
return tempString;
}
int main() {
string result = accum("abcd");
}
Change this line:
result[i] += s[i];
to this:
result += s[i];

How to access numbers in string and convert it to integer?

I am using stoi function here and it is giving invalid argument error...
Here, the input file is something like "S13S12S11S10S1". I want to save the numbers in an array rank like rank[0]=13 rank[1]=12 and so on...
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
ifstream fin("input.txt");
string input;
fin>>input;
int count=0;
int val;
int rank[4];
for(int i=0 ; i < input.size(); i++)
{
string s1,s2;
s1=input[i];
s2=input[i+1];
if(s1[0]!='S' && s1[0]!='H' &&s1[0]!='D' && s1[0]!='C')
{
int a=stoi(s1);
rank[count]=a;
if(s2[0]!='S' && s2[0]!='H' &&s2[0]!='D' &&s2[0]!='C')
{
int temp;
int b=stoi(s2);
rank[count]=10+b;
count++;
i++;
}
else{
count++;
}
}
}
for (int count=0; count<=4 ; count++)
{
cout<<rank[count];
cout<<"\n";
}
}
You can tokenize the input string, using 'SHDC' for delimiters. And then use atoi to convert the tokens to integers. I would use a vector to store your rank values, if your input file(s) could have a varying number of tokens.
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
ifstream fin("input.txt");
string input;
fin >> input;
const char *delimiters = "SHDC";
char *next_token = NULL;
char *token = strtok_s(const_cast<char*>(input.c_str()), delimiters, &next_token);
vector<int> values;
while (token != NULL) {
values.push_back(atoi(token));
token = strtok_s(NULL, delimiters, &next_token);
}
for (int i = 0; i < values.size(); ++i) {
cout << values[i] << endl;
}
}

How to alphabetically sort strings?

I have been trying to use this c++ program to sort 5 names alphabetically:
#include <iostream>
#include <cstring>
#include <conio.h>
using namespace std;
int main()
{
char names[5][100];
int x,y,z;
char exchange[100];
cout << "Enter five names...\n";
for(x=1;x<=5;x++)
{
cout << x << ". ";
cin >> names[x-1];
}
getch();
for(x=0;x<=5-2;x++)
{
for(y=0;y<=5-2;y++)
{
for(z=0;z<=99;z++)
{
if(int(names[y][z])>int(names[y+1][z]))
{
strcpy(exchange,names[y]);
strcpy(names[y],names[y+1]);
strcpy(names[y+1],exchange);
break;
}
}
}
}
for(x=0;x<=5-1;x++)
cout << names[x];
return 0;
}
If I enter Earl, Don, Chris, Bill, and Andy respectively, I get this:
AndyEarlDonChrisBill
Could someone please tell me whats wrong with my program?
You could use std::set or std::multiset (if you will allow repeated items) of strings, and it will keep the items sorted automatically (you could even change the sorting criteria if you want).
#include <iostream>
#include <set>
#include <algorithm>
void print(const std::string& item)
{
std::cout << item << std::endl;
}
int main()
{
std::set<std::string> sortedItems;
for(int i = 1; i <= 5; ++i)
{
std::string name;
std::cout << i << ". ";
std::cin >> name;
sortedItems.insert(name);
}
std::for_each(sortedItems.begin(), sortedItems.end(), &print);
return 0;
}
input:
Gerardo
Carlos
Kamilo
Angel
Bosco
output:
Angel
Bosco
Carlos
Gerardo
Kamilo
You can use the sort function:
#include <algorithm>
#include <vector>
using namespace std;
...
vector<string> s;
sort(s.begin(),s.end());
You are using too much unnecessary loops. Try this simple and efficient one. You need to just swap when a string is alphabetically latter than other string.
Input
5
Ashadullah
Shawon
Shakib
Aaaakash
Ideone
Output
Aaaakash
Ashadullah
Ideone
Shakib
Shawon
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s[200],x[200],ct,dt;
int i,j,n;
cin>>n;
for(i=0;i<n;i++)
{
cin>>s[i];
}
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(s[i]>s[j])
{
ct=s[i];
s[i]=s[j];
s[j]=ct;
}
}
}
cout<<"Sorted Name in Dictionary Order"<<endl;
for(i=0;i<n;i++)
{
cout<<s[i]<<endl;
}
return 0;
}
Your code implements a single-pass of bubble sort. Essentially missing the 'repeat until no changes are made to the array' loop around the outside.
The code does not take care when the names are already in order. Add the following
else if(int(names[y][z])<int(names[y+1][z]))
break;
To the if statement.
Putting this here in case someone needs a different solution.
/* sorting example */
#include <iostream>
using namespace std;
bool isSwap( string str1, string str2, int i)
{
if(str1[i] > str2[i])
return true;
if(str1[i] == str2[i])
return isSwap(str1,str2,i+1);
return false;
}
int main()
{
string str[7] = {"you","your","must","mike", "jack", "jesus","god"};
int strlen = 7;
string temp;
int i = 0;
int j = 0;
bool changed = false;
while(i < strlen-1)
{
changed = false;
j = i+1;
while(j < strlen)
{
if(isSwap(str[i],str[j],0))
{
temp = str[i];
str[i] = str[j];
str[j] = temp;
changed = true;
}
j++;
}
if(changed)
i = 0;
else
i++;
}
for(i = 0; i < strlen; i++)
cout << str[i] << endl;
return 0;
}

c++ formating error with cstrings when using tolower

Hi so I am trying to take a cstring and make it lowercase, but when I am printing the cstring at the end I am getting a weird format box where some of the letters should be. Do anyone have any ideas?
#include <string>
#include <iostream>
#include <string.h>
using namespace std;
int main ()
{
int i=0;
char* str="TEST";
char c;
char* cstr = new char[strlen(str) + 1];
while (str[i])
{
c = str[i];
c = tolower(c);
strcat(cstr, &c);
i++;
}
cout << cstr << endl;
return 0;
}
The problem is that you are calling strcat incorrectly. The second parameter is not a null-terminated string.
You really don't need to call strcat at all. Just write directly to the output string:
Try:
while (str[i])
{
c = str[i];
c = tolower(c);
cstr[i] = c;
i++;
}
cstr[i] = 0;
or, equivalently:
while(str[i])
{
cstr[i] = tolower(str[i]);
i++;
}
cstr[i] = 0;
strcat expects a null-terminated char*, so by giving the address of a local char you are invoking undefined behavior.
Additionally, new char[std::strlen(str) + 1] does not initialize the array to 0s, meaning cstr won't be properly null-terminated either; adding () to the new[] causes the array to be value-initialized.
Try this instead:
#include <cstddef>
#include <cctype>
#include <cstring>
#include <ostream>
#include <iostream>
int main()
{
char const* str = "TEST";
char c[2] = { };
char* cstr = new char[std::strlen(str) + 1]();
std::size_t i = 0;
while (str[i])
{
c[0] = static_cast<char>(std::tolower(str[i++]));
std::strcat(cstr, c);
}
std::cout << cstr << std::endl;
delete [] cstr;
}
The second argument of strcat is supposed to be a null terminated string, not the address of a single character. strcat isn't appropriate for this use.
int main ()
{
const char* str="TEST";
char* cstr = new char[strlen(str) + 1];
cstr[strlen(str)] = 0;
for (int i = 0; str[i]; ++i) {
cstr[i] = tolower(str[i]);
}
cout << cstr << endl;
}
#include <cstddef>
#include <cctype>
#include <cstring>
#include <ostream>
#include <iostream>
#include <string>
int main()
{
std::string str = "TEST";
std::string cstr;
for (std::string::const_iterator it = str.begin(); it!= str.end(); ++it)
cstr.push_back(tolower(*it));
std::cout << cstr << std::endl;
}
Or even shorter:
#include <algorithm>
#include <iterator>
...
std::transform(str.begin(), str.end(), std::back_inserter(cstr), tolower);