I am trying to write a program to reverse a string. I used the following code but unfortunately it didn't work. I am a little confused why that happened.
Here is my code:
#include <string>
#include <iostream>
using namespace std;
int main()
{
string InputString = "Hello";
string OutputString;
int length;
length = InputString.length();
for (int i=length-1, j=0; i >=0, j<length; i--, j++)
OutputString[j] = InputString[i];
cout << "The reverse string of " << InputString << " is "
<< OutputString << ".\n";
return 0;
}
My output is:
The reverse string of Hello is .
The problem isn't quite what you think it is. It is that OutputString is empty and any indexing into it will be out of bounds and lead to undefined behavior.
You might instead do something like
OutputString += InputString[i];
to append characters to the string.
Also, the loop condition i >=0, j<length will not work like you think either. You are using the comma expression so while both i >= 0 and j<length will be evaluated, only the result of j<length will be used. You probably want to use the logical and operator there: i >=0 && j<length.
I prefer to reverse strings like this:
#include <string>
#include <iostream>
int main(int argc,char** argv){
std::string hello = "hello";
for(std::size_t i=0;i < hello.length()/2; ++i)
{
std::swap(hello[i],hello[hello.length()-i-1]);
}
std::cout<<hello<<std::endl;
return 0;
}
Live Demo
Or you simply do:
string OutputString(InputString.rbegin(), InputString.rend());
cout << "The reverse string of " << InputString << " is "
<< OutputString << ".\n";
Related
string a = MwZwXxZwDwJrBxHrHxMrGrJrGwHxMrFrZrZrDrKwZxLrZrFwZxErMrXxArZw;
Assume i have this data in my string . I want to record how many M , Z , X , D , J (including those capital letters i didn't mentions ) in in string how can do it ? My friends say use vector can do it but i does not really know how to use vector is there any alternative way to do it .
I tried using for loops to do and find the M , and reset the pointer to 0 to continue find the next capital value , but not sure is there any easier way to do it .
first I'll show you a 'easier' way to me.
#include <iostream>
#include <map>
using namespace std;
int main(int argc, const char * argv[]) {
string str = "MwZwXxZwDwJrBxHrHxMrGrJrGwHxMrFrZrZrDrKwZxLrZrFwZxErMrXxArZw";
map<char,int> map;
for (int i=0; i<str.length(); i++) {
char ch = str[i];
if (isupper(ch)) {
map[ch] ++;
}
}
for (auto item : map) {
cout<<item.first<<':'<<item.second<<endl;
}
return 0;
}
you'll only need to use 1 loop to solve your problem.
the 'isupper(int _c)' is a function from the standard library, it can tell you wether a character is a capital letter.
the 'map' is a data structure from the standard library too, it can do key-value storage for you.
this program outputs this:
A:1
B:1
D:2
E:1
F:2
G:2
H:3
J:2
K:1
L:1
M:4
X:2
Z:8
is this what you want?
Use regex.
using namespace std;
// regex_search example
#include <iostream>
#include <string>
#include <regex>
int main ()
{
std::string s ("MwZwXxZwDwJrBxHrHxMrGrJrGwHxMrFrZrZrDrKwZxLrZrFwZxErMrXxArZw;");
std::smatch m;
std::regex e ("[A-Z\s]+");
map<string,int> map;
std::cout << "Target sequence: " << s << std::endl;
std::cout << "Regular expression: [A-Z\s]+" << std::endl;
std::cout << "The following matches and submatches were found:" << std::endl;
while (std::regex_search (s,m,e)) {
for (auto x:m)
{
//cout << x << " ";
map[x.str()] ++;
}
//cout << std::endl;
s = m.suffix().str();
}
for (auto item : map) {
cout<<item.first<<':'<<item.second<<endl;
}
return 0;
}
The most direct translation of "loop through the string and count the uppercase letters" into C++ I can think of:
#include <iostream>
#include <map>
#include <cctype>
int main()
{
string a = "MwZwXxZwDwJrBxHrHxMrGrJrGwHxMrFrZrZrDrKwZxLrZrFwZxErMrXxArZw";
std::map<char, int> count;
// Loop through the string...
for (auto c: a)
{
// ... and count the uppercase letters.
if (std::isupper(c))
{
count[c] += 1;
}
}
// Show the result.
for (auto it: count)
{
std::cout << it.first << ": " << it.second << std::endl;
}
}
My program worked like it was supposed to until I added the toupper part into my program. I've tried looking at my error code but it's not really helping. The errors are:
no matching function to call
2 arguments expected, one provided
So I know the error is in those two statements in my while loop. What did I do wrong?
I want to make a name like
john brown
go to
John Brown
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int main(){
string firstname[5];
string lastname[5];
ifstream fin( "data_names.txt" );
if (!fin) {
cout << "There is no file" << endl;
}
int i = 0;
while( i < 5 && (fin >> firstname[i]) && (fin >> lastname[i]) ) {
firstname[0] = toupper(firstname[0]);
lastname[0] = toupper(lastname[0]);
i++;
}
cout << firstname[0] << " " << lastname [0] << endl;
cout << firstname[1] << " " << lastname [1] << endl;
cout << firstname[2] << " " << lastname [2] << endl;
cout << firstname[3] << " " << lastname [3] << endl;
cout << firstname[4] << " " << lastname [4] << endl;
return 0;
}
std::toupper works on individual characters, but you are trying to apply it to strings. Besides adding #include <cctype>, you need to modify your while loop's body:
firstname[i][0] = toupper(firstname[i][0]);
lastname[i][0] = toupper(lastname[i][0]);
i++;
Then it should work as expected. Live demo here
As M.M helpfully pointed out in the comments, you should also check that your strings aren't empty before accessing their first characters, i.e. something like
if (!firstname[i].empty()) firstname[i][0] = toupper(...);
is strongly recommended.
Mind you, you will probably need more sophisticated logic if you get names like McDonald :)
You need ctype.h to get the proper definition for toupper(). It is usually implemented not as a function, but an array mapping.
#include <ctype.h>
The program has several flaws: using a string array instead of a string, not iterating through the string correctly, not declaring but using the C definition of toupper(), not exiting when the file does not exist.
Use this instead:
#include <ctype.h>
#include <iostream>
#include <string>
using namespace std;
int main ()
{
ifstream fin ("data_names.txt");
if (!fin)
{
cerr << "File missing" << endl;
return 1;
}
// not sure if you were trying to process 5 lines or five words per line
// but this will process the entire file
while (!fin.eof())
{
string s;
fin >> s;
for (i = 0; i < s.length(); ++i)
s [i] = toupper (s [i]);
cout << s << endl;
}
return 0;
}
I've got trouble getting the regex in C++ working.
Eventually, I'd like to build a boolean vector from the matched groups ("ITOISBFAMPM" -> "11011000000").
To build the vector, I need to get the start and length of each group.
The pattern works well on regexr.com and I get all the goups. But my code returns an empty result set.
#include <iostream>
#include <vector>
#include <regex>
using namespace std;
string board = "ITOISBFAMPM"
"ACQUARTERDC"
"TWENTYFIVEX"
"HALFBTENFTO"
"PASTERUNINE"
"ONESIXTHREE"
"FOURFIVETWO"
"EIGHTELEVEN"
"SEVENTWELVE"
"TENSEOCLOCK"
"1234";
string pattern = ".*(IT).*(IS).*(HALF).*(PAST).*(TWELVE).*(123).*";
// string pattern = "(PAST)";
int main()
{
regex rgx(pattern);
smatch result;
regex_search(board, result, rgx);
cout << board << endl;
cout << pattern << endl;
cout << result.size();
for(size_t i=0; i<result.size(); ++i)
{
cout << result[i] << endl;
}
}
As indicated by Igor Tandetnik, the code works as is. The problem lies in the interpreter.
I am brand new to programming so none of this may be right. I was just messing around trying to get the effect that I (finally) achieved. More for practice than anything else, but I wondered if there was another way to do it.
#include "stdafx.h"
#include <conio.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1="Don't even think about it!";
string str2;
string str3;
string str4 = "";
for (int i = 0; i < str1.length(); i++){
str2 = str1.substr (0, str1.length()-i);
cout << str2 << str4;
for (int x = str2.length() - 1; x >= 0; x--){
str3 = str1[x];
cout << str3;
}
str4 = str4 + " ";
cout << "\n";
}
getch();
main();
return 0;
}
The question I have is this: Is there a way to make the str3, after it is backwards, its own string that I could then justify right instead of adding spaces with str4?
In order to get a reversed string, just pass the reverse-iterators to the constructor of a new string:
#include <iostream>
#include <string>
int main() {
std::string s = "this is a test";
std::string s_reversed(s.rbegin(), s.rend());
std::cout << s << "\n" << s_reversed << "\n";
}
The output is:
$ g++ test.cc && ./a.out
this is a test
tset a si siht
Applied to your problem:
#include <iostream>
#include <string>
int main() {
std::string s = "this is a test";
for (auto i = s.length(); i > 0; i--) {
std::cout << s;
std::cout << std::string(s.rbegin(), s.rend());
std::cout << '\n';
s[i-1] = ' ';
}
}
Note that there also is an algorithm in the standard library to reverse a container, e.g., a string: std::reverse().
For reference:
http://en.cppreference.com/w/cpp/string/basic_string/basic_string
http://en.cppreference.com/w/cpp/string/basic_string/rbegin
http://en.cppreference.com/w/cpp/string/basic_string/rend
http://en.cppreference.com/w/cpp/algorithm/reverse
You could try this:
replacing letters for whitespace and then reversing the string.
Concat the modified string with the reverse of it and print it.
std::string reverse(std::string str)
{
std::reverse(str.begin(), str.end());
return str;
}
int main()
{
std::string str = "Don't even think about it!";
size_t N = str.length();
for (size_t i = 1; i < N; i++)
{
std::cout << str << reverse(str) << std::endl;
str.replace(N-i,1, " ");
}
return 0;
}
First I would rename the variables so it is more clear what you are trying to achieve. Believe me, in two months you will not have a clue what this code actually does. Suggestion:
str1 -> baseString
str2 -> forwardsClippedString
str3 -> backwardsClippedString
str4 -> gapString
Maybe these names are not even good but I think they are better than str1, ..., str4.
Then I would make a separate method of the inner loop. After that make a separate method of the outer for loop - yes, main() shouldn't be complicated at all.
Finally instead of recursively calling main I suggest to do a while-loop. An infinite one if you please (but it would be nice if one key quits the loop then).
I have the following snippet:
string base= tag1[j];
That gives the invalid conversion error.
What's wrong with my code below? How can I overcome it.
Full code is here:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <time.h>
using namespace std;
int main ( int arg_count, char *arg_vec[] ) {
if (arg_count < 3 ) {
cerr << "expected one argument" << endl;
return EXIT_FAILURE;
}
// Initialize Random Seed
srand (time(NULL));
string line;
string tag1 = arg_vec[1];
string tag2 = arg_vec[2];
double SubsRate = 0.003;
double nofTag = static_cast<double>(atoi(arg_vec[3]));
vector <string> DNA;
DNA.push_back("A");
DNA.push_back("C");
DNA.push_back("G");
DNA.push_back("T");
for (unsigned i=0; i < nofTag ; i++) {
int toSub = rand() % 1000 + 1;
if (toSub <= (SubsRate * 1000)) {
// Mutate
cout << toSub << " Sub" << endl;
int mutateNo = 0;
for (int j=0; j < tag1.size(); j++) {
mutateNo++;
string base = tag1[j]; // This fail
int dnaNo = rand() % 4;
if (mutateNo <= 3) {
// Mutation happen at most at 3 position
base = DNA[dnaNo];
}
cout << tag1[j] << " " << dnaNo << " " << base << endl;
//cout << base;
}
cout << endl;
}
else {
// Don't mutate
//cout << tag1 << endl;
}
}
return 0;
}
Why do I get an Invalid conversion from char to const char* when looping over a string?
The std::string operator [] returns a single char. string cannot be instantiated with a single char.
Use:
string base = string( 1, tag1[j] ) instead
Change it to
char base = tag1[j];
string tag1 = arg_vec[1];
tag1 is a string literal.
string base = tag1[j]; is initialized with a char instead of char *.
Try, char base = tag1[j];
There is no constructor for string that takes just a char (which is what tag1[j] is). You have a couple options:
string base; // construct a default string
base = tag1[j]; // set it to a char (there is an
// assignment from char to string,
// even if there's no constructor
or
string base( 1, tag1[j]); // create a string with a single char
Or as Josh mentioned, you can define base as a char since you're not performing any string operations on it anyway. If you decide to do this you'll need to change DNA to be a vector<char> (and change the initialization of DNA to using chars instead of strings).
One problem is that the error message says the program expects one argument when it actually requires two. You should probably follow the Unix conventions and show the required usage too (or instead):
if (arg_count != 3) {
cerr << "Usage: " << arg_vec[0] << " tag1 tag2";
return EXIT_FAILURE;
}
The names 'argc' and 'argv' are very conventional (and the only major alternative I've seen is 'ac' and 'av'). It might be worth sticking with that.