Convert char array to a string with cin.getline(.) - c++

hi guys so my question is how to convert a char array to a string. here is my code:
#include<iostream>
using namespace std;
int main()
{
while (true) {
char lol[128];
cout << "you say >> ";
cin.getline(lol,256);
cout << lol << endl;;
}
return 0;
}
so I want to convert lol to a string variable like "stringedChar" (if thats even english lol)
so I can do stuff like:
string badwords[2] = {"frick","stupid"};
for (int counter = 0; counter < 2;counter++) {
if(strigedChar == badwords[counter]) {
bool isKicked = true;
cout << "Inappropriate message!\n";
}
}
Sorry im just a c++ begginer lol

Do something like this :
as char lol[128];
into string like: std::string str(lol);
Line : cin.getline(lol,256); <--> should be changed to cin.getline(lol,128)

Just invoke std::getline() on a std::string object instead of messing about with a char array, and use std::set<std::string> for badwords as testing set membership is trivial:
#include <iostream>
#include <set>
#include <string>
static std::set<std::string> badwords{
"frick",
"stupid"
};
int main() {
std::string line;
while (std::getline(std::cin, line)) {
if (badwords.count(line) != 0) {
std::cout << "Inappropriate message!\n";
}
}
return 0;
}
Note that this tests whether the entire line is equal to any element of the set, not that the line contains any element of the set, but your code appears to be attempting to do the former anyway.

First off, you have a mistake in your code. You are allocating an array of 128 chars, but you are telling cin.getline() that you allocated 256 chars. So you have a buffer overflow waiting to happen.
That said, std::string has constructors that accept char[] data as input, eg:
#include <iostream>
using namespace std;
int main()
{
while (true) {
char lol[128];
cout << "you say >> ";
cin.getline(lol, 128);
string s(lol, cin.gcount());
cout << s << endl;;
}
return 0;
}
However, you really should use std::getline() instead, which populates a std::string instead of a char[]:
#include <iostream>
#include <string>
using namespace std;
int main()
{
while (true) {
string lol;
cout << "you say >> ";
getline(cin, lol);
cout << lol << endl;;
}
return 0;
}

Related

Optimize an algorithm to find multiple specific substrings of a string

I'm new to C++ coding and just started solving competitive programming problems. I want to solve the following task: https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1620.
I want to find a substring of a string. The problem is that the code below is slow and I fail the submission by getting the "time limit exceeded" "error". What can I do to speed up the code?
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string.h>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
stringstream ss;
string m;
char prob[100000];
char substring[1000];
int howManyCases = 0;
int numberOfTests = 0;
cin >> numberOfTests;
cin.ignore();
while(numberOfTests--)
{
cin >> prob >> howManyCases;
while(howManyCases--)
{
cin >> substring;
if (strstr(prob,substring)) {
ss << 'y' << "\n";
}
else
{
ss << 'n' << "\n";
}
}
}
m = ss.str();
cout << m;
return 0;
}
i would make you of <algorithm> header:
std::string parent_string = "some string lala";
std::string sub_string = "lala";
auto found = parent_string.find(sub_string);
it will return iterator to where substring is. Then I wou;d use this clause:
if (found != std::string::npos) std::cout << "y\n";
else std::cout << "n\n";
If there is no limitation to the use of standard libraries, It's always a better choice to use it instead of creating your own algorithms (that may not handle some special cases you won't think of ).
Also, swap those huge ugly c-style arrays to std::string.

Is there a way to search an element of a vector<String>, then check if it contains a particular char, if it does print it

The final element in the vector is the char to search for.
Here’s my code:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
vector<string> words;
string in;
while(cin>>in)
{
words.push_back(in);
}
int size = words.size()
string check = words.at(size-1);
}
I tried your code and the loop was infinite. Try asking a set number of words then use the find method for each string. Here's an example.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> words;
string in;
cout << "Enter 5 words: \n";
for (int i{0}; i < 5; ++i)
{
cout << "Word: ";
cin >> in;
words.push_back(in);
}
cout << "What character do you want to search for? ";
char c;
cin >> c;
for (auto word : words)
{
if (word.find(c) != string::npos)
{
cout << "Character \"" << c << "\" found in " << word << endl;
}
}
return 0;
}
Edit: I noticed that you tried to use int to store the size for the string. Use size_t instead. I also think you meant to use the length method of the string, which also returns size_t.

How to erase non-alphabet characters from a string without going out of range

I am trying to this function to return without numbers, spaces, or other characters and I am supposed to use the .erase function. I understand that my loop keeps going out of range, but I have no clue how to fix it and I've been stuck on this for a while. If the user types "dogs are a lot of fun" and I need the function to return and output "dogsarealotoffun" Thanks for the help.
#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;
//function to output string without spaces, numbers, or punctuations
string alphabetOnly (string input){
int size;
int i= 0;
size = (int)input.size();
while (input[i] < size){
if (isalpha(input[i])){
i++;
}
else
input.erase(input[i]);
}
return input;
}
int main() {
string input;
cout << "Enter a string to test: ";
getline(cin, input);
cout << "alphabetOnly: " << alphabetOnly(input) << endl;
}
EDITED: I was too hasty in my previous answer (as I am learning I need to speak from tested code rather than off the top of my head) and needed to debug. The problem is in the else case you need to erase the char, NOT increment i because the length of the string just changed, and also since the length of the string changed you need to reset size to be the new length. Sorry for the hasty answer earlier, I was speaking without actually using the compiled code.
#include <iostream>
#include <cctype>
#include <string>
//function to output string without spaces, numbers, or punctuations
std::string alphabetOnly (std::string input){
int size;
int i= 0;
size = (int)input.size();
while (i < size){
if (isalpha(input[i])){
i++;
}
else{
input.erase(i,1);
//do not increment i here since the index changed becauase of erase
size = (int)input.size();
}
}
return input;
}
int main() {
std::string input;
std::cout << "Enter a string to test: ";
std::getline(std::cin, input);
std::cout << input;
std::cout << "alphabetOnly: " << alphabetOnly(input) << std::endl;
return 0;
}
something like this:
#include <iostream>
#include <string>
#include <algorithm>
//function to output string without spaces, numbers, or punctuations
std::string alphabetOnly (std::string input)
{
auto not_alpha = [](char c) { return !std::isalpha(c); };
input.erase(std::remove_if(begin(input),
end(input),
not_alpha),
std::end(input));
return input;
}
int main() {
std::string input;
std::cout << "Enter a string to test: ";
getline(std::cin, input);
std::cout << "alphabetOnly: " << alphabetOnly(input) << std::endl;
}
http://coliru.stacked-crooked.com/a/340465d41ecd8c8e
There's quite a few things wrong with your code, but to start with here's your main error corrected.
#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;
//function to output string without spaces, numbers, or punctuations
string alphabetOnly (string input){
int size;
int i= 0;
size = (int)input.size();
while (i < size){
if(isalpha(input[i]))
{
i++;
}
else
input.erase(input.begin( ) + i );
}
return input;
}
int main() {
string input;
cout << "Enter a string to test: ";
getline(cin, input);
cout << "alphabetOnly: " << alphabetOnly(input) << endl;
}
But this is awfully inefficient because you swhift all the remaining unchecked characters each time you delete.
You should use something like
input.erase( remove_if( input.begin(), input.end(), not( isalpha ) ), input.end( ));
This is known as the remove-erase idiom, whihc you can lookup anywhere.

string subscript out of range c++

I need a help in a very basic c++ code.
My program is about guessing name game the problem which i faced is in reading string char by char
#include <iostream>
#include <time.h>
#include <iomanip>
#include <stdlib.h>
#include <fstream>
#include <string>
using namespace std;
void Play(int, int,int, string[], string[]);
string GetRandomName(int, int, int , string[], string[]);
const int ArrayMax = 100;
void Play(int selection, int FArraySize, int MArraySize,string Female[], string Male[])
{
int MAX_TRIES = 3;
int i=0;
ofstream ofFile;
ifstream InFile;
int num_of_wrong_guesses=0;
char letter;
string GuessedName;
GuessedName = GetRandomName(selection, FArraySize, MArraySize, Female, Male);
cout << "Guess the following name:" << endl;
while (GuessedName[i]!= 0 ){
cout<<"?";
i++;
}
cout << "\nEnter a guess letter? or * to enter the entire name" << endl;
cin >> letter;
return;
}
I don't complete coding...
the problem is in the while loop how can i solve it without using cstring?
could you help me?
int i = 0;
while(GuessedName[i] != 0)
{
cout << "?";
i++;
}
Seems like you are trying to print sequence of ? with the length of the string to guess. But you cannot treat std::string as c-string. When its length is n, GuessedName[n] is string subscript out of range - you cannot access one element past end - it's not null-terminated. Use for loop:
for(int i = 0; i < GuessedName.length(); ++i)
cout << "?";
Or simply:
cout << std::string(GuessedName.length(), '?');
Change the while loop like this:
while (GuessedName[i]){
cout<<"?";
i++;
}

Storing a variable in C++

The problem is that file won't be read...Apparently there's a problem with an array but I don't really know how fix this issue...I'm a beginner to C++ 'arrays' and 'strings'...
My file should read the code, then translate the file, then output the text into a new file..
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <fstream>
#include <math.h>
#include <stdio.h>
#include <string>
#include <string.h>
using namespace std;
int main()
{
// Declarations
string reply;
string inputFileName;
ifstream inputFile;
ofstream outFile;
char character;
cout << "Input file name: ";
getline(cin, inputFileName);
// Open the input file.
inputFile.open(inputFileName.c_str());
// Check the file opened successfully.
if ( ! inputFile.is_open()) {
cout << "Unable to open input file." << endl;
cout << "Press enter to continue...";
getline(cin, reply);
return 1;
}
// This section reads and echo's the file one character (byte) at a time.
while (inputFile.peek() != EOF) {
inputFile.get(character);
//cout << character;
//Don't display the file...
char cipher[sizeof(character)];
//Caesar Cipher code...
int shift;
do {
cout << "enter a value between 1-26 to encrypt the text: ";
cin >> shift;
}
while ((shift <1) || (shift >26));
int size = strlen(character);
int i=0;
for(i=0; i<size; i++)
{
cipher[i] = character[i];
if (islower(cipher[i])) {
cipher[i] = (cipher[i]-'a'+shift)%26+'a';
}
else if (isupper(cipher[i])) {
cipher[i] = (cipher[i]-'A'+shift)%26+'A';
}
}
cipher[size] = '\0';
cout << cipher << endl;
}
cout << "\nEnd of file reached\n" << endl;
// Close the input file stream
inputFile.close();
cout << "Press enter to continue...";
getline(cin, reply);
return 0;
}
To make it short: You're on c++ so just don't use the whole C stuff.
Don't use character arrays, use std::string
Don't use islower(char) but use std::islower(char,locale)
Don't use C-style arrays but std::array (compile time constant size) or std::vector (dynamic size)
You'll want to have it more like this:
#include <string>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <locale>
int main (void)
{
std::string input_filename;
std::cout << "Input file name: ";
std::getline(std::cin, input_filename);
unsigned int shift;
do
{
std::cout << "Enter a value between 1-26 to encrypt the text: ";
std::cin >> shift;
}
while ((shift == 0) || (shift > 26));
try
{
std::string filestring;
std::ifstream input(input_filename, std::ios_base::in);
if (input)
{
input.seekg(0, std::ios::end);
filestring.reserve(input.tellg());
input.seekg(0, std::ios::beg);
filestring.assign
(std::istreambuf_iterator<char>(input),
std::istreambuf_iterator<char>());
}
else
{
std::string error_string("Reading failed for: \"");
error_string.append(input_filename);
error_string.append("\"");
throw std::runtime_error(error_string);
}
std::string result;
result.reserve(filestring.size());
std::locale const loc;
for (auto character : filestring)
{
char const shifter(std::islower(character, loc) ? 'a' : 'A');
result.push_back((character-shifter+shift)%26+shifter);
}
std::cout << result << std::endl;
}
catch (std::exception & e)
{
std::cout << "Execution failed with an exception: " << std::endl;
std::cout << e.what() << std::endl;
}
}
This solution requires C++11 support. If you do not have C++11 you can replace the loop with:
size_t const N(filestring.length());
for (size_t i(0u); i<N; ++i)
{
char const shifter(std::islower(filestring[i], loc) ? 'a' : 'A');
result.push_back((filestring[i]-shifter+shift)%26+shifter);
}
From looking at your code, "character" is declared as a char which means it can only store one byte of information. Yet later on you start using it as if it was an array of characters.
You are also declare "cipher" as a char array that you manual manage like a string which is error prone. The real issue however is that you're mixing C-like code in C++. In other words, the way your code is written isn't considered idiomatic C++.
Pixelchemist already went over the important points so I'll just present a minimal refactored working example of your above code:
#include <iostream>
#include <string>
#include <fstream>
#include <stdlib.h>
using namespace std;
int main()
{
string filename;
cout << "enter input file: ";
cin >> filename;
ifstream inputFile( filename.c_str() );
string plaintext;
do
{
plaintext += inputFile.get();
}while(inputFile);
cout << plaintext << endl;
string &ciphertext = plaintext;
//Caesar Cipher code...
int shift = rand() % 26 + 1;
for(size_t i = 0; i < ciphertext.size(); ++i)
{
if (islower(ciphertext[i])) {
ciphertext[i] = (ciphertext[i] - 'a' + shift) % 26 + 'a';
}
else if (isupper(ciphertext[i])) {
ciphertext[i] = (ciphertext[i] - 'A' + shift) % 26 + 'A';
}
}
cout << ciphertext << endl;
}
You'll notice in the refactor that I've done away with char and char[] arrays altogether and replaced it with std::string. I'm also performing the cipher operation inplace on the plaintext input. This is done by making a reference alias to plaintext called ciphertext for readability. Also in my example, the shift is done randomly for prototyping but you should change it to take it as a user input instead.
You are working with a single char, thats e.g. just one letter or a number. So the whole thing with size handling is useless, because the size is always 1. You probably should use const char*. But then you can't use filestream.get() at all, because it only returns a single char (not and cstring aka const char*).
And you can use fstream.get() as condition for the loop, so you don't need to ask for the eof flag.
char my_char;
std::ifstream infstream("filename.txt");
if(!infstream.isopen())
return -1;
while(infstream.get(my_char) {
//do some stuff
}
or
std::string my_string;
std::ifstream infstream("filename.txt");
if(!infstream.isopen())
return -1;
while(infstream >> my_string) {
//do some stuff
}
for dynamic arrays in C++ use std::vector or std::list or ... one of the other STL containers, so you don't have to waste your time on memory management and using static sized arrays.
And std::string is the way to go for strings in C++. It is something similar to the STL containers, but just for char's.