How to access numbers in string and convert it to integer? - c++

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

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

converting strings to integers by using "stringstream "

I am trying to convert strings of data to integers, (to use it for some calculations ) by using stringstream , but it fails when there is a space.
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
int main() {
string line;
vector <string>data;
for (int i = 0; i < 10;i++) {
getline(cin,line);
data.push_back(line);
}
///converting digits to int
vector<int> values;
int n;
char ch=',';
for (int i = 0; i < data.size();i++) {
stringstream stream(data[i]);
while( stream >>n ) {
if(stream >> ch) {
values.push_back(n);
}
else {
values.push_back(n);
}
cout<<n<<" ";
}
cout<<endl;
}
return 0;
}
input : 1,182,08 51 15 --> output : 1 182 8 1 5
there are some digits lost after spaces.
so, what can I do to avoid it?
Complete working code based on seccpur's answer. Visual Studio 2017 Community:
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
#define BUFSZ 100 // Set max size of the numbers as a single string
int convertToIntegers(char *s, vector<int> &values);
int main()
{
int count;
int i;
char data[BUFSZ];
vector<int> values;
strcpy_s(data, "1,182,08 51 15");
count = convertToIntegers(data, values);
// for (auto val : values) // Show the result
// cout << val << '\n';
// *** OR ***
for (i = 0; i < count; i++)
cout << values[i] << '\n';
}
//////////////////////////////////////
// Convert a C string to integers
//
int convertToIntegers(char *s, vector<int> &values)
{
vector<string> numbers;
char *next_token;
char* ptr = strtok_s(s, " -.,;", &next_token);
while (ptr)
{
string str(ptr);
numbers.push_back(str);
ptr = strtok_s(NULL, " -.,;", &next_token); // Next number
}
//
// Convert the resulting strings to integers
//
for (auto str : numbers)
values.push_back(stoi(str));
return (int)values.size();
}
If you know you have exactly one character as a separator, either a space, either a comma, the following code will work:
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
int main() {
string line;
vector <string>data;
for (int i = 0; i < 10;i++) {
getline(cin,line);
data.push_back(line);
}
///converting digits to int
vector<int> values;
int n;
char ch=',';
for (int i = 0; i < data.size();i++) {
stringstream stream(data[i]);
while( stream >>n ) {
char c = stream.get();
//if(stream >> ch) {
// values.push_back(n);
//}
//else {
values.push_back(n);
//}
cout<<n<<" ";
}
cout<<endl;
}
return 0;
}
You are using multiple delimiters in the input ( like whitespace : , ; -) which complicates the matter. Here's a possible snippet using std::strtok:
//Enter a line
string line;
getline(cin, line);
// Convert string to char* so that std::strtok could be used later
char *cstr = new char[line.length() + 1];
std::strcpy(cstr, line.c_str());
vector<string> words;
// split line into multiple strings using multiple delimiters
char* ptr = std::strtok(cstr, " -.,;");
while (ptr)
{
string str(ptr);
words.push_back(str);
ptr = strtok(NULL, " -.,;");
}
delete[] cstr;
// Convert string to int
vector<int> values;
for (auto str : words){
values.push_back(std::stoi(str));
}
// Print the values
for (auto val : values){
cout << val << '\n';
}

C++ Hangman Project

I have a problem with my Hangman code.
Here's the error what i get:
error: cannot convert 'std::__cxx11::string {aka std::__cxx11::basic_string}' to 'char' for argument '1' to 'int checkGuess(char, std::__cxx11::string, std::__cxx11::string&)'
Never really seen any errors like this.
Here's my code:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int NUM_TRY = 15;
int checkGuess(char, string, string&);
void main_menu();
string word;
void beolvas(vector <string> &words);
void kiir (vector <string> words);
void betolt (vector <string> words);
string message = "Play!";
int main(int argc, char *argv[])
{
vector <string> words;
string name;
string letter;
beolvas(words);
kiir(words);
betolt(words);
string hide_m(word.length(), '-');
while(NUM_TRY != 0){
main_menu();
cout<<"\n\n\t\t\t\t" <<hide_m;
cout<<"\n\n\t\t\t\tMondj egy betut: ";
getline(cin, letter);
if (checkGuess(letter, word, hide_m)==0)
{
message = "Incorrect letter!";
NUM_TRY = NUM_TRY - 1;
}
if (word == hide_m);
{
cout<<"Congratulations, you guessed the word."<<endl;
cout<<"\t\t\tThe word was "<<word<<endl;
break;
}
if (letter == hide_m)
{
cout<<"Good job. You guessed a letter."<<endl;
}
}
}
void beolvas(vector <string> &words)
{
string sor;
ifstream fin("words.txt");
while(!fin.eof()){
getline(fin, sor);
words.push_back(sor);
}
fin.close();
}
void kiir(vector <string> words)
{
ofstream fout("olvasd.txt");
srand(time(NULL));
int n =rand() % 236;
fout<<words[n]<<endl;
}
void betolt(vector <string> words)
{
ifstream input("olvasd.txt");
while(!input.eof()) {
getline(cin, word);
}
input.close();
}
int checkGuess(char guess, string secretword, string &guessword)
{
int i;
int matches = 0;
int len = secretword.length();
for(i = 0; i < len; i++)
{
if(guess == guessword[i])
{
return 0;
}
if(guess == guessword[i])
{
guessword[i] = guess;
matches++;
}
}
return matches;
}
void main_menu()
{
system("color B"); //Light Aqua
system("cls");
cout<<"\t\t\t\t\t";
cout<<"\n\t\t\tHangman";
cout<< "\n\t\tYou have" <<NUM_TRY <<" tries, to guess the word. ";
cout<<"\n\n\t\t\t\t"+message;
}
checkGuess takes a char type as first parameter, but you are providing letter which is actually of type std::string. This code won't compile.
You can read letter[0] instead to get the first char of the string. Make sure letter.length() is bigger than 0 first.

insert string into vector character by character

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

c++ reverse line using stack compile error no operator matches operand

I'm writing a program to reverse the string using a stack. I'm getting 2 errors in my code. 1. no operator >> matches the operand 2. On the line Reverse(string); it errors say (string)type name is not allowed. Any idea why?
#include <iostream>
#include <string.h>
#include <stack>
using namespace std;
void Reverse(char);
int main()
{
char object;
cout << "Please enter a line of text.\n";
cin >> object;
char * point = new char[object.length() + 1];
strcpy(point, object.c_str());
Reverse(point);
Reverse(point);
printf(" %s", object);
system("pause");
return 0;
}
void Reverse(char *p)
{
stack<char> S;
for (int i = 0; i<strlen(p); i++)
S.push(p[i]);
for (int i = 0; i<strlen(p); i++)
{
p[i] = S.top();
S.pop();
}
}
updated code: error on cin >> object says the initial question no operator matches an operand
#include <iostream>
#include <string.h>
#include <stack>
using namespace std;
void Reverse(string);
int main()
{
string object;
cout << "Please enter a line of text.\n";
cin >> object;
char * point = new char[object.length() + 1];
strcpy(point, object.c_str());
Reverse(point);
printf(" %s", point);
system("pause");
return 0;
}
void Reverse(char *p)
{
stack<char> S;
for (int i = 0; i<strlen(p); i++)
S.push(p[i]);
for (int i = 0; i<strlen(p); i++)
{
p[i] = S.top();
S.pop();
}
}
I am getting error strcpy_s does not take 2 arguments.
#include <iostream>
#include <cstring>
#include <string>
#include <stack>
using namespace std;
void Reverse(char *p)
{
stack<char> S;
for (int i = 0; i<strlen(p); i++)
S.push(p[i]);
for (int i = 0; i<strlen(p); i++)
{
p[i] = S.top();
S.pop();
}
}
int main()
{
string object;
cout << "Please enter a line of text.\n";
cin >> object;
char * point = new char[object.length() + 1];
strcpy_s(point, object.c_str());
Reverse(point);
printf(" %s", point);
system("pause");
return 0;
}
char * point = new char[object.length()+1];//+1 for the null terminator
strcpy(point, object.c_str());
Reverse(point);
printf("%s",point);
allocates space for point then copies http://en.cppreference.com/w/cpp/string/byte/strcpy and you were calling Reverse like this Reverse(char) you need to call it using the name of the char variable like this Reverse(point); since we allocated space we need to delete it after we are done using it.
Please check the modified code below. I can reverse the input string now.
#include <iostream>
#include <string>
#include <stack>
using namespace std;
void Reverse(char *p)
{
stack<char> S;
for (int i = 0; i<strlen(p); i++)
S.push(p[i]);
for (int i = 0; i<strlen(p); i++)
{
p[i] = S.top();
S.pop();
}
}
int main()
{
string object;
cout << "Please enter a line of text.\n";
cin >> object;
char * point = new char[object.length() + 1];
strcpy(point, object.c_str());
Reverse(point);
printf(" %s", point);
system("pause");
return 0;
}