I was writing a code that would substitute some random 17 character strings into a single alphabet, and I can't find a way. Basically, what I'm trying to do is this:
char strings[] = {
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
"zF8,1KV#¥]$k?|9R#",
"0B4>=nioEjp>4rhgi",
}
char alphabet[]{
"a","b","c","d","e","f","g","h","i",
}
replace(std::string str){
/**get str and then see the index of the corresponding string in strings[], and replace the string with alphabet[index number], while deleting the original string part that was replaced**/
int main(){
cin >> std::string replace;
replace(replace);
example input: L-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|r9bC5f0q#qA(RKZ>|r
expected output: abc
EDIT:
New Code
Changes from the original code
It also has a bigger array than the simplified version(previous code). It displays the structure of the full program.(where the strings are routed to and why)
Basically What it's doing
getting input from user, put it in the input variable, input goes through algorithm() function untouched, and then goes to the replace function and is replaced. It then the replaced string gets returned back through the original route to the main function, where it is displayed.
I've kept the arrays a string type because the const char* gave me a segmentation error.
std::string Subs[53]=
{
"LQlMv]G5^^1kcm?fk",
"7W^S;/vB(6%I|w[fl",
"<w7>4f//Z55ZxK'z.",
"_W5g(lu<pTu3^_A7n",
"OfLm%8:EF}0V1?BSS",
"|+E6t,AZ~XewXP17T",
"L-nIbhm5<z:92~+,x",
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
"zF8,1KV#¥]$k?|9R#",
"0B4>=nioEjp>4rhgi",
"EG#0[W9.N4i~E<f3x",
"(0Pwkk&IPchJHs.7A",
"7XgmQ6fW<|J+NY[m0",
".g4CwX/DU!!~!zbtZ",
"+_U'qn_/9Fo|gT/!n",
"=0s(mYh&F%y=MBS5(",
"cg71(}bo+Q5P8F[T6",
"lc|a\%5.9pOpooU+QR",
"E_(3A:o+.]qL3MYA6",
"H#O'X_RiVS#8l0bKD",
"Y1gbGD`~8d>HSWN35",
"LQlMv]G5^^1kcm?fk",
"T4}gI;`BFVfhw=-sf",
"6BHMA0IRix]/=(jht",
"yS$=#Jdpp?P2k6SMQ",
"t1~|kkh+>4d>}OQ`a",
"2Y-\\CU\"944yBluWD5",
"'M\\ZbIX5{`Xd;qi!o",
"?N+RtVqj_r(C5##0\"",
"2;*Livh?V$X/8z#Md",
")IN|7FOs2l-mAM[d#",
"(~f268J},xXrK'Rp'",
"&r/qf9fFHnzV!RzH/",
"}naDRH4p$NI2a).t,",
"{8DM+7!.Mge|~fnO|",
")r[#nI0YDH>6cE38p",
"(0Pwkk&IPchJHs.7A",
")r[#nI0YDH>6cE38p",
"8M-=cQFQ,pPo7eu=p",
"0PHw=/|(tZ1}FHm/'",
"[su`'0Oybc.\"-/W5)",
"1uHl[IC7Sr#NUJV;I",
"8z8%,jK0CDOkJz8I?",
"3Ao2yXDN%YzpE&Suy",
"zNs`7E'e/$i8VqaUL",
"bzHmA^K2>7`UZ?!AO",
};
std::string Alphabet[53] =
{
" ","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","r","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
};
std::string replace(std::string rep) {
int len = sizeof(Subs)/sizeof(Subs[0]);
std::stringstream ss1;
for(int i = 0; i < len; i++) {
if (rep.find(Subs[i]) != std::string::npos) {
ss1 << Subs[i];
}
}
std::string input = ss1.str();
return input;
}
std::string algorithm(std::string input)
{
//some other algorithms come here(not relative to this question)
input = replace(input);
return input;
}
int main(void){
int ed;
std::cin >> ed;
if(ed == 1){
//different function(not relative to the question)
}
else if(ed == 0){
std::string input;
std::cin >> input;
input = algorithm(input);
std::cout << input << std::endl;
}
else{
std::cout << "1 or 0" << std::endl;
main();
}
return 0;
}
example input: L-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|r9bC5f0q#qA(RKZ>|r
expected output: abc
actual output: L-nIbhm5<z:92~+,xL-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|r9bC5f0q#qA(RKZ>|r
Sorry it's become long.
There are few mistakes in above code :
char array initialization is not correct.
method body for main and replace method is not closed.
Currently by default return type of replace method is int.
There is string#find method which can be helpful here.
I have tried to make those fixes and here is updated code in C++17 :
#include <iostream>
#include <sstream>
using namespace std;
const char *strings[9] = {
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
"zF8,1KV#¥]$k?|9R#",
"0B4>=nioEjp>4rhgi"
};
const char *alphabet[9] = {
"a","b","c","d","e","f","g","h","i"
};
void replace(std::string rep) {
int len = sizeof(strings)/sizeof(strings[0]);
std::stringstream ss1;
for(int i = 0; i < len; i++) {
if (rep.find(strings[i]) != std::string::npos) {
ss1 << alphabet[i];
}
}
std::cout << ss1.str();
}
int main(){
std::string rep;
cin >> rep;
replace(rep);
}
For reference : https://onlinegdb.com/Bd9DXSPAa
Note - Above code is just for reference, please make sure to add all test cases handling.
I made a c++17 version for your code.
Replacing 'c' style arrays and pointers with C++ style containers, iterators.
And using std::string::replace function. Use the standardlibrary if you can,
its tested and well documented.
#include <algorithm>
#include <iostream>
#include <regex>
#include <string>
#include <vector>
// std::vector/std::array instead of 'c' style arrays.
// allows us to us range based for loops later.
std::vector<std::string> strings =
{
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
//"zF8,1KV#¥]$k?|9R#", // <<== I commented out this line, ¥ is not a valid charcter in my environment
"0B4>=nioEjp>4rhgi"
};
// a string is already an array of characters.
std::string alphabet{ "abcdefghijkl" };
std::string replace_with_alphabet(const std::string& input)
{
std::string retval{ input };
std::size_t index{ 0 };
// range based for, it will keep the order of the vector.
for (const auto& str : strings)
{
// look if you can find any of the predefined strings
// in the input strings.
const size_t pos = retval.find(str, 0);
// if found
if (pos != std::string::npos)
{
// get the next character from the alphabet
std::string replacement{ alphabet[index++] };
// use std::string::replace for replacing the substring
const size_t len = str.length();
retval.replace(pos, len, replacement, 0);
}
}
return retval;
};
/**get str and then see the index of the corresponding string in strings[], and replace the string with alphabet[index number], while deleting the original string part that was replaced**/
int main()
{
auto output = replace_with_alphabet("L-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|rk=5,ln(08IAl(gGAK");
std::cout << output << std::endl;
}
I need some help on making a function to split sentence into words and this function should work on sentence with different lengths.
Here is the sample code:
void spilt_sentence(string sentence)
{}
int main()
{
std::string sentence1= "Hello everyone";
std::string sentence2= "Hello I am doing stuff";
split_sentence(sentence1);
split_sentence(sentence2);
return 0;
}
I saw someone use std::istringstream to get every words before each space but I don't really know how it works. It gives me error when I put std::istringstream ss(sentence); in the code. Also, I am using c++98 and I compile my program with cygwin. Any leads? Thank you.
Edit: The function will create a number of variables depending on how many words are there in the sentence.
Edit: I am actually working on a LinkedList program and what I am trying to do here is split sentence into words and then generate new nodes containing each word.
Here is the actual code (note: I modified it a little bit so it's not exactly the same as my actual one. Also I am not using struct for Node) and let's say sentence 1 is "Hello everyone" and sentence 2 is "Hello I am doing stuff".
The expected output will be:
linkedlist1:
"hello"<->"everyone"
linkedlist2:
"hello"<->"I"<->"am"<->"doing"<->"stuff"
inside LinkedList.cpp:
void LinkedList::add(std::string sentence)
{
//breaks down the sentence into words
std::istringstream ss(sentence);
do
{
std::string word;
ss >> word;
//store them in nodes in a linkedlist
Node* new_tail = new Node(word);
if (size == 0)
{
head = new_tail;
tail = new_tail;
}
else
{
new_tail->set_previous(tail);
tail->set_next(new_tail);
tail = new_tail;
}
new_tail = NULL;
size++;
}
while(ss);
}
[FIXED]An error message pop up when I compile it, saying std::istringstream ss has default settings but the type is incomplete. What should I do?
error
Here is the function using streams, this function will work only for vectors, you can't use this function for arrays, but if you want to, you can modify it for you.
Here is the code and usage example
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;
void split_sentence(const string& str, vector<string>& cont)
{
istringstream iss(str);
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(cont));
//checking for punctuation marks and if found, we remove them from the word
for(int i = 0, sz = cont.size(); i < sz; i++){
string word = cont.at(i);
for(int j = 0, len = word.length(); j < len; j++){
if(ispunct(word[j])){
cont.at(i) = word.substr(0, word.length() - 1);
}
}
}
}
int main(){
string sentence = "this is a test sentence for stackoverflow!";
vector<string> words;
split_sentence(sentence, words);
for(int i = 0, sz = words.size(); i < sz; i++){
cout<<words.at(i) << endl;
}
return 0;
}
And this is the output
this
is
a
test
sentence
for
stackoverflow
if you also want to print punctuation marks then remove double for loop in fucntion.
I need a program to take a string and replace spaces with increasing numbers.
#include <cstring>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
// Get the String
string str = "this essay needs each word to be numbered";
int num = 1;
string x = num;
int i = 0;
// read string character by character.
for (i < str.length(); ++i) {
// Changing the loaded character
// to a number if it's a space.
if (str[i] == ' ') {
str[i] = x;
++num
}
}
// testing outputs
cout << str << endl;
cout << num << endl;
ofstream file;
file.open ("numbered.txt");
file << str;
file.close();
return 0;
}
I had it at the point where it could replace spaces with a letter or symbol and save to a new file but when I tried to make it a number it stopped working. I would need it to say "this1essay2needs3each4word5to6be7numbered
For ease and clarity, change your approach.
Put the string into an istringstream
Extract each space-separated substring and place into an std::vector<string>
Feed the contents of the vector into a stringstream and
use std::to_string(num) to add the numbers between the substrings
e.g.:
std::string str = "this essay needs each word to be numbered";
int num = 1;
std::istringstream istr(str);
std::string temp;
std::vector<std::string> substrs;
while (istr >> temp)
{
substrs.push_back(temp);
}
std::stringstream ostr;
for (auto&& substr : substrs)
{
ostr << substr << std::to_string(num++);
}
Let's break the problem down into parts. We can make a SpaceReplacer object that does the replacement. It has an Output, which it can use as a function to output characters:
template<class Output>
struct SpaceReplacer {
Output output;
int num_spaces;
void input(char c) {
if(c == ' ') {
auto num_as_string = std::to_string(num_spaces);
num_spaces += 1;
for(char digit : num_as_string) {
output(digit);
}
}
else {
output(c);
}
}
};
Every time you input a character, it either outputs the character you input, or it outputs the digits of the number (if the character was a space).
We should write a helper function to make SpaceReplacers:
template<class Output>
SpaceReplacer<Output> makeReplacer(Output output_func) {
return SpaceReplacer<Output>{output_func, 0};
}
Reading one string, returning new string
It's now easy to write a function that replaces spaces in a string.
std::string replaceSpaces(std::string const& input) {
std::string output_string;
// We output chars by appending them to the output string
auto output_func = [&](char c) { output_string += c; };
auto replacer = makeReplacer(output_func);
for(char c : input) {
replacer.input(c);
}
return output_string;
}
Reading input from file, replacing spaces and returning a string
Because we wrote a really generic SpaceReplacer class, we can modify the function so that it'll read input directly from a FILE*
std::string replaceSpaces(FILE* file) {
std::string output_string;
auto output_func = [&](char c) { output_string += c; };
auto replacer = makeReplacer(output_func);
while(true) {
int input_char = fgetc(file);
if(input_char == EOF) {
break;
}
replacer.input(input_char);
}
return output_string;
}
Reading input from one file, immediately appending it to different file with spaces replaced
We can also read directly from one file, and output directly to another file, with no delay. This might be useful if you were processing a very large amount of data.
void replaceSpaces(FILE* input_file, FILE* output_file) {
auto output_func = [=](char c) { fputc(c, output_file); };
auto replacer = makeReplacer(output_func);
while(true) {
int input_char = fgetc(input_file);
if(input_char == EOF) {
break;
}
replacer.input(input_char);
}
}
In this case, you need to use another string for the result.
#include <cstring>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
// Get the String
string result, str = "this essay needs each word to be numbered qwe qwe wqe qwe qwe qwe q";
int num = 0;
int i;
// read string character by character.
for (i=0; i < str.length(); i++) {
// Changing the loaded character
// to a number if it's a space.
if (str[i] == ' ')
result+=std::to_string(++num);
else
result+=str[i];
}
// testing outputs
cout<<result<<endl;
cout<<num;
ofstream file;
file.open ("numbered.txt");
file << result;
file.close();
return 0;
}
You have to replace it with a character, not by a number.
str[i] = num+'0';
I'm currently writting a program where I try to filter extra spaces so if there are more than 1 spaces in a row, I discard the rest leaving only one
But this is only the first step because the aim of the program is to parse a txt file with mips assembly instructions.
So far I've opened the file, stored the content in a vector and then stored the vector content in an array. Then I check, if you find a char 2 times in a row shift the array to the left.
The problem is that the code works well for any other letter, except for the space character. (On the code below I test it with the 'D' character and it works)
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
class myFile {
vector<string> myVector;
public:
void FileOpening();
void file_filter();
};
void myFile::FileOpening() {
string getcontent;
ifstream openfile; //creating an object so we can open files
char filename[50];
int i = 0;
cout << "Enter the name of the file you wish to open: ";
cin.getline(filename, 50); //whatever name file the user enters, it's going to be stored in filename
openfile.open(filename); //opening the file with the object I created
if (!openfile.is_open()) //if the file is not opened, exit the program
{
cout << "File is not opened! Exiting the program.";
exit(EXIT_FAILURE);
};
while (!openfile.eof()) //as long as it's not the end of the file do..
{
getline(openfile, getcontent); //get the whole text line and store it in the getcontent variable
myVector.push_back(getcontent);
i++;
}
}
void myFile::file_filter() {
unsigned int i = 0, j = 0, flag = 0, NewLineSize, k, r;
string Arr[myVector.size()];
for (i = 0; i < myVector.size(); i++) {
Arr[i] = myVector[i];
}
//removing extra spaces,extra line change
for (i = 0; i < myVector.size(); i++) {
cout << "LINE SIZE" << myVector[i].size() << endl;
for (j = 0; j < myVector[i].size(); j++) {
//If I try with this character for example,
//it works (Meaning that it successfully discards extra 'Ds' leaving only one.
// But if I replace it with ' ', it won't work. It gets out of the loop as soon
//as it detects 2 consecutive spaces.
if ((Arr[i][j] == 'D') && (Arr[i][j + 1] == 'D')) {
for (k = j; k < myVector[i].size(); k++) {
Arr[i][k] = Arr[i][k + 1];
flag = 0;
j--;
}
}
}
}
for (i = 0; i < myVector.size(); i++) {
for (j = 0; j < myVector[i].size(); j++) //edw diapernw tin kathe entoli
{
cout << Arr[i][j];
}
}
}
int main() {
myFile myfile;
myfile.FileOpening();
myfile.file_filter();
}
My question is, why does it work with all the characters except the space one, and how do I fix this?
Thanks in advace.
Wow. Many lines of code. I can only recomend to learn more about the STL and algorithms.
You can read the complete file into a vector using the vectors "range"-constructor and std::istream_iterator. Then you can replace one or more spaces in a string by using a std::regex. This is really not complicated.
In the below example, I do all the work, with 2 lines of code in function main. Please have a look:
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <string>
#include <fstream>
#include <regex>
using LineBasedTextFile = std::vector<std::string>;
class CompleteLine { // Proxy for the input Iterator
public:
// Overload extractor. Read a complete line
friend std::istream& operator>>(std::istream& is, CompleteLine& cl) { std::getline(is, cl.completeLine); return is; }
// Cast the type 'CompleteLine' to std::string
operator std::string() const { return completeLine; }
protected:
// Temporary to hold the read string
std::string completeLine{};
};
int main()
{
// Open the input file
std::ifstream inputFile("r:\\input.txt");
if (inputFile)
{
// This vector will hold all lines of the file. Read the complete file into the vector through its range constructor
LineBasedTextFile text{ std::istream_iterator<CompleteLine>(inputFile), std::istream_iterator<CompleteLine>() };
// Replace all "more-than-one" spaces by one space
std::for_each(text.begin(), text.end(), [](std::string& s) { s = std::regex_replace(s, std::regex("[\\ ]+"), " "); });
// For Debug purposes. Print Result to std::out
std::copy(text.begin(), text.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}
return 0;
}
I hope, I could give you some idea on how to proceed.
I'm trying to build a function that goes through a while or for-loop and finds where the space is, outputs everything before the space, and then erases everything before the space including the space, and then repeats this again.
Any help is much appreciated.
int sentence()
{
string enteredSentence="";
getline(cin,enteredSentence);
string sentenceString(enteredSentence);
int sentenceLength=enteredSentence.size();
cout<<"size of sentence"<<sentenceLength<<endl;
int stringSize=sentenceString.size();
while(stringSize>0)
{
int spaceLoc = enteredSentence.find(" ");
cout<<spaceLoc;
cout<<sentenceString.substr(0,spaceLoc)<<endl;
sentenceString.substr(0,spaceLoc);
cout<<"string before string eraced"<<sentenceString<<endl;
sentenceString.erase (0,spaceLoc);
cout<<"string after string eraced"<<sentenceString<<endl;
stringSize=sentenceString.size();
cout<<"string size is"<<stringSize<<endl;
}
This is how I fixed your code:
#include <iostream>
using namespace std;
int main()
{
string enteredSentence="";
getline(cin,enteredSentence);
string sentenceString(enteredSentence);
int sentenceLength = enteredSentence.size();
cout<<"size of sentence:"<<sentenceLength<<endl;
string::size_type stringSize = sentenceString.size();
while(stringSize > 0)
{
int spaceLoc = sentenceString.find(" "); //there was incorrect var
cout<<spaceLoc<<endl;
if(spaceLoc == string::npos){
cout<<"last part:"<<sentenceString<<endl;
break;
}//check if there are no spaces left
cout<<sentenceString.substr(0,spaceLoc)<<endl;
//the substr line here was redundant
cout<<"string before string erased:"<<sentenceString<<endl;
sentenceString.erase(0, spaceLoc + 1);//also delete the space
cout<<"string after string erased:"<<sentenceString<<endl;
stringSize=sentenceString.size();
cout<<"string size:"<<stringSize<<endl<<endl;
}
return 0;
}
You could use a stringstream.
#include <sstream>
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
string enteredSentence; // It's initialized to "" by default, by the way
getline(cin,enteredSentence);
cout<<"size of sentence: "<<enteredSentence.length()<<endl;
istringstream str_in(enteredSentence);
string word;
while(str_in >> word) {
// Do stuff with word
// I believe str_in.str() will also give you the portion that hasn't yet been processed.
}
return 0;
}
I'm not 100% sure that I understand what you want to achieve. But I can help you with find:
It has a second parameter that specifies from where on in the string the search will start:
size_t pos = 0;
while ((pos = str.find(' ', pos)) != std::string::npos) {
std::cout << "Found a space at " << pos << std::endl;
++pos;
}
Reference
With more information on what you actually want your code to do (show example input plus wanted output) I can help you clear the rest of your code.
Currently your description suggests that you want to output the entire string, but in pieces (separated by spaces).
Your code makes a (needless?) copy of your input, generates substrings only to throw them away and doesn't return an int as said in the function declaration.
If you want to tokenize your input then this question has some answers for you.