Inserting a character in a string - c++

I have a string name2. I want to remove the capital characters in it and put lowercase instead.
Input:Car Output:car
Here is my loop code:-
if(isupper(name2.at(i))) {
string tem=to_string(tolower(name2.at(i)));
name2.erase(i,1);
name2.insert(i,tem);
}
i is just the loop variable.
However , here is my input vs output
Input:Sushant Output:115ushant
It is giving some sort of ASCII equivalent ouput , I suppose.
How do I fix this?

Here, to_string interprets the result of tolower as an integer. So what you see inserted in your string is the ASCII value of 's' (115). To fix this, there is no need to convert to string, just use characters directly:
char c = tolower(name.at(i));
name2.erase(i, 1);
name2.insert(i, c);
Easier and more efficient would be to just directly tolower() the character at the ith position:
name[i] = std::tolower(name[i]);
That being said, simpler would be to lowercase the whole string in one go, and take for granted that some characters will be lowercased unnecessarily:
std::transform(name.begin(), name.end(), name.begin(),
[](unsigned char c){ return std::tolower(c); }
);
See also: std::tolower.

It can be done simply using the range-based for loop.
Here is a demonstrative program.
#include <iostream>
#include <string>
#include <cstring>
int main()
{
std::string s;
std::cout << "Enter a word: ";
std::cin >> s;
for ( char &c : s )
{
if ( std::isupper( ( unsigned char )c ) )
{
c = tolower( c );
}
}
std::cout << s << '\n';
}
Its output might look like
Enter a word: Sushant
sushant
As for your if statement then at least this sub-statement
string tem=to_string(tolower(name2.at(i)));
does not make sense. For example
std::cout << std::to_string( 'A' ) << '\n';
can output
65
that corresponds to the ASCII value of the character 'A'.
That is the function std::to_string converts the promoted code of the character 'A' as an integer to a string.

Related

Save names or strings

Using CPP on visual studios 2019. If needing more info just comment.
The compiler would ask for a name/string, you would enter it then
it would ask again.
If you were to type the same thing twice, the compiler would say "you typed it twice".
The problem is that I don't know how I should go about saving uppercase and lowercase
words because if you were to just type in the same word with a capital the compiler
would think its a brand new word.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string word[100];
int x = 0;
while (1)
{
cout << "Enter word.";
cin >> word[x];
x++;
// I don't know how to check if words typed in are the same.
// Thats the question.
}
}
If you are considering two strings entered in different case as the same string, then you could store the inputted string by transforming it into lower/upper case and then check with the previous value and currently inputted value every time.
Considering you read into string s, you could store the string into lower/upper case by using std::transform() function.
std::transform(s.begin(), s.end(), s.begin(), ::toupper);
Remember to convert the read input into lower/upper case as well before checking both the strings. I gave you the basic idea of how your program would work. Now, write the code yourself.
You have to use std::transform with std::toupper.
Steps:
input word, save in std::string
input next word
check words: call
std::transform(s.begin(), s.end(), other.begin(), ::toupper);
for both words and if they are the same print first word
You can convert all of the entered word characters into a single case (lower case/upper case), then check if the result is present in the entered words set.
A complete example:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> words{};
while (true) {
std::string word{};
std::cout << "Enter a word: " << std::flush;
std::cin >> word;
// Convert word to lower case by adding 32 to each upper case
// character
for (auto &c : word) {
c |= 0x20;
}
if (words.count(word)) {
std::cerr << "You typed `" << word << "' twice!" << std::endl;
continue;
}
words.emplace(std::move(word));
}
return 0;
}

Extract all numbers from stringstream

I want to read string and extract all numbers.
Input: 5a3 1f a0aaaa f1fg3
Output: 53 1 0 13
I tried this code:
string s;
getline(cin, s);
stringstream str_strm(s);
int found;
string temp;
while (!str_strm.eof()) {
str_strm >> temp;
if (stringstream(temp) >> found)
{
cout << found << endl;
}
}
but when found 5 (from example)after that automatically start to check the other string. How can I extract all numbers?
Here's a possible solution - while loop is used to separate strings with whitespaces, after that digits are extracted from the sub-strings.
int main()
{
stringstream ss("5a3 1f a0aaaa f1fg3");
string str;
while (getline(ss, str, ' ') ){
str.erase(std::remove_if(str.begin(), str.end(), [](unsigned char c) { return !std::isdigit(c); }), str.end());
cout << str << " ";
}
}
You could read each space separated word, and then remove the non-digits, like this
std::string word;
while (std::cin >> word)
{
word.erase(std::remove_if(word.begin(), word.end(),
[](unsigned char c) { return not std::isdigit(c); }),
word.end());
std::cout << word << " ";
}
For the input of 5a3 1f a0aaaa f1fg3, it prints 53 1 0 13.
The admittedly odd way of removing elements of a range, is a common idiom.
You could even avoid the loop entirely, if you have the input on a single line
std::string word;
std::getline(std::cin, word);
word.erase(std::remove_if(word.begin(), word.end(),
[](unsigned char c) { return not std::isdigit(c)
and not std::isspace(c); }),
word.end());
std::cout << word;
Please see here the ultra simple example. (There is an even simpler solution at the bottom of this post)
It is using modern C++ elements and algorithms. And has only a few lines of code.
#include <iostream>
#include <string>
#include <regex>
#include <iterator>
#include <algorithm>
#include <sstream>
int main() {
// Read a string from the console
if (std::string line{}; std::getline(std::cin, line)) {
// Put the complete line into a std::istringstream
std::istringstream iss{line};
// Print result
std::transform(std::istream_iterator<std::string>(iss), {}, std::ostream_iterator<std::string>(std::cout, " "),
[](const std::string& s) { return std::regex_replace(s, std::regex{ R"([^\d])" }, ""); });
}
return 0;
}
So, what's going on here. Let us look at it statement by statement. So, first:
if (std::string line{}; std::getline(std::cin, line)) {
This is a if-statement with initializer. If you look up if in the C++ reference, here, then you can see, that we can now have an additional initialization statement as the first part in the if. And why are we using that? Because it is an additional measure for scoping. The variable "line" is only used within the scope of the if statement. It is not needed outside the if. From the functionality point of view, it is the same as writing:
std::string line{};
if (std::getline(std::cin, line)) {
But then, "line" would be also visible outside of the if statement. And, because we want to prevent the pollution of outer namespace, we select this method.
Next is std::getline. This will read a complete line from the input stream, so, from the console (std::cin)and put it into the string. The std::getline returns a reference to the stream. The stream has an overloaded bool operator, that returns, if there was a failure (or end of file) or not. So, the if statement checks, if the input operation works. By the way. All IO-opereations should be checked, if they work or fail.
Good, now we have the complete line of the user input in our variable "line".
With
std::istringstream iss{line};
we put the string into an std::istringstream. We do this, because we want to make use of the C++ "iostream" library. The std::istringstream behaves as any other stream, for example std::cin and you can extract values from it that are separated by a white space. Like in std::cin >> v1 >> v2. The disadvantage for such an approach is, that you need to know the number of values in advance or use a dynamic growing container and a loop.
And this brings ud to our next construct that I want to explain. You may have heard about "iterators". Iterators are like pointers and can point to a range of elements. If you have a std::vector or any other container, then you can iterate with the begin() and end() iterator over all elements in the std::vector without knowing, how many elements are in the std::vector, without knowing how many elements it contains.
And for input streams, we have something similar: The std::istream_iterator. This iterator will iterate over the elements in the std::sitringstream and returns the type of variable given in its template parameter, by repeatedly calling the extractor operator >>. Here, in our case, a std::string. You may know ask: Until when? Where is the end. If you look in the description of the constructor number 1 of the std::istream_operator then you will see, that the default constructor Constructs the end-of-stream iterator. and the default construct can be generated by using the empty braced {} initializer. So {} is the end iterator.
If we want to read all std::strings from the std::istringstream, then we read between
std::istream_iterator<std::string>(iss) and {}. So every string that is in the std::istringstream.
Good, next, there is a similar thing for output, the std::ostream_iterator. This will call the inserter operator "<<" for all elements in a given range. And, we can can specify, to which stream it should send the data, here std::cout and additionally a separator-string, which will be appended to the outputted value.
OK, next: std::transform. As it names says, it will transform the elements in a range of elements, between a begin() and end() iterator, to a other range. So, it will transform the elements as shown above from the std::istringstream and send them to the std::ostream iterator. So, we read the source value, transform it, then write it.
But, how to transform. For the transformation, we give a simple lambda function, which calls the std::regex_replace function. This is a standard function, to replace parts of a string with other string data. And, the what that will be replaced is specified by a std::regex. This is a special pattern that is defined in some kind of meta language and matches specified parts of a string. in our case we use [^\d] which means, not a digit. You can test regexes here. You can also lean about them here.
And now, all together, explains the above solution.
All this can be further optimized to 2 statements:
#include <iostream>
#include <string>
#include <regex>
int main() {
// Read a string from the console
if (std::string line{}; std::getline(std::cin, line)) {
// Remove unnecessary characters
std::cout << std::regex_replace(line, std::regex{ R"([^\d ])" }, "") << "\n";
}
return 0;
}
I cannot think of a more simpler solution.
In case of questions, please ask.
You can use get from istream to get each character, including whitespace, and then isdigit to check for a digit character...
#include <iostream>
#include <cctype>
int main()
{
char ch;
std::cin.get(ch);
while (!std::cin.eof())
{
if (isdigit(ch) || ch == ' ' || ch == '\n')
{
std::cout << ch;
}
std::cin.get(ch);
}
return 0;
}
However, you can avoid using std::cin.eof() for your expression for your While loop as follows...
#include <iostream>
#include <cctype>
int main()
{
char ch;
while (std::cin.get(ch))
{
if (isdigit(ch) || ch == ' ' || ch == '\n')
{
std::cout << ch;
}
}
return 0;
}
Regular expression pattern matching can be used to find all the digits in the input string.
Here is an example program to find the digits:
// C++ program to find all digits in a string
#include <bits/stdc++.h>
using namespace std;
int main() {
string inputString;
cout << "Enter the input string: ";
getline(cin, inputString);
cout << "Digits found: ";
// Define the regular expression matcher and pattern
smatch matcher;
regex pattern("[[:digit:]]");
while (regex_search(inputString, matcher, pattern)) {
// Show the match
cout << matcher.str(0);
// Continue searching the rest of the string
inputString = matcher.suffix().str();
}
return 0;
}
Output:
Enter the input string: sdfh354 eutyt;ljkn756897490uiotureu 587689jkgf 90
Digits found: 35475689749058768990
Here is another approach of finding the numbers in the string, without using the regular expression pattern matching:
#include <iostream>
#include <cctype>
#include <bits/stdc++.h>
using namespace std;
int main() {
string rawInput;
cout <<"Enter input string: ";
getline(cin, rawInput);
// Get all words from the input string
stringstream allWords(rawInput);
// Find and print digits in each word
string word;
while(allWords >> word) {
for(int i = 0; word[i]; i++) {
// Print only the numbers in the word
if(isdigit(word[i])) {
cout<<word[i];
}
}
cout<<" ";
}
cout<<"\n";
return 0;
}
Output:
Enter input string: ghjg45 jsdfj 897897 343yut45 90
45 897897 34345 90
How can I extract all numbers?
When you KNOW that the input numbers are all hex values ... (and how many)
stringstream ss ("5a3 1f a0aaaa f1fg3");
for (int i=0; i<4; ++i)
{
int k;
ss >> hex >> k;
cout << k << endl;
}
with output
1443
31
10529450
3871

C++ Cin input to array

I am a beginner in c++ and I want to enter a string as character by character into an array , so that I can implement a reverse function .. However unlike C when the enter is hit a '\n' is not insterted in the stream.. how can I stop data from being entered ?
my code is :
#include<iostream>
#include<array>
#define SIZE 100
using namespace std;
char *reverse(char *s)
{
array<char, SIZE>b;
int c=0;
for(int i =(SIZE-1);i>=0;i--){
b[i] = s[c];
c++;
}
return s;
}
int main()
{
cout<<"Please insert a string"<<endl;
char a[SIZE];
int i=0;
do{
cin>>a[i];
i++;
}while(a[i-1]!= '\0');
reverse(a);
return 0;
}
When you read character by character, it really reads characters, and newline is considered a white-space character.
Also the array will never be terminated as a C-style string, that's not how reading characters work. That means your loop condition is wrong.
To begin with I suggest you start using std::string for your strings. You can still read character by character. To continue you need to actually check what characters you read, and end reading once you read a newline.
Lastly, your reverse function does not work. First of all the loop itself is wrong, secondly you return the pointer to the original string, not the "reversed" array.
To help you with the reading it could be done something like
std::string str;
while (true)
{
char ch;
std::cin >> ch;
if (ch == '\n')
{
break; // End loop
}
str += ch; // Append character to string
}
Do note that not much of this is really needed as shown in the answer by Stack Danny. Even my code above could be simplified while still reading one character at a time.
Since you tagged your question as C++ (and not C) why not actually solve it with the modern C++ headers (that do exactly what you want, are tested, save and work really fast (rather than own functions))?
#include <string>
#include <algorithm>
#include <iostream>
int main(){
std::string str;
std::cout << "Enter a string: ";
std::getline(std::cin, str);
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
return 0;
}
output:
Enter a string: Hello Test 4321
1234 tseT olleH

use of Range Based for loops in C++

I am trying to write a program that eliminates blank spaces using a range based for loop in C++. For eg, if the input is, "what is your name?" , the output should be "Whatisyourname?" however when i run the code below, the output it gives is "Whatisyourname?me?", why is that?
int main()
{
string s = "What is your name?";
int write_index = 0;
for (const char &c : s)
{
if (c != ' ')
{
s[write_index++] = c;
}
}
cout << s << endl;
system("pause");
}
Add after the loop the following statement
s.erase( write_index );
or
s.resize( write_index );
to remove redundant characters from the string.
The general approach to such tasks is the following
#include <algorithm>
#include <string>
//...
s.erase( std::remove( s.begin(), s.end(), ' ' ), s.end() );
The reason for this is because string s is still as long as the original string, "What is your name?". You wrote over top of every character in the string except for the last three. What you could do is erase the last three characters from the string after you're done removing the spaces. This is untested but something like this should work:
s.erase(write_index, s.length() - write_index)
Your range based for loop usage is correct. Just keep in mind that you're looping over all the input characters (as though you were looping with for (int i = 0; i < s.length(); i++), but you're not outputting as many characters as you're reading.
So the equivalent for loop would be like this:
for (int i = 0; i < s.length(); i++) {
const char& c = s[i];
if (c != ' ') {
s[write_index++] = c;
}
}
Here are two useful little functions:
template<class C, class F>
bool remove_erase_if( C& c, F&& f ) {
using std::begin; using std::end;
auto it = std::remove_if( begin(c), end(c), std::forward<F>(f) );
if ( it == c.end())
return false;
c.erase( it, c.end() );
return true;
}
template<class C, class T>
bool remove_erase( C& c, T&& t ) {
using std::begin; using std::end;
auto it = std::remove( begin(c), end(c), std::forward<T>(t) );
if ( it == c.end())
return false;
c.erase( it, c.end() );
return true;
}
these both take a container, and either a test or an element.
They then remove and erase any elements that pass the test, or equal the element.
Your code emulated the remove part of the above code, and did not do the erase part. So the characters remaining at the end ... remained.
remove (or your code) simply moves all the "kept" data to the front of the container. The stuff left over at the end ... stays there. The erase step then tells the container that the stuff after the stuff you kept should be discarded. If you don't discard it, it ... remains ... and you get your bug.
With the above two functions, you can do this:
int main() {
std::string s = "What is your name?";
remove_erase( s, ' ' );
std::cout << s << '\n';
}
and you are done.
As an aside, using namespace std; is often a bad idea. And std::endl forces a buffer-flush, so I prefer '\n'. Finally, system("pause") can be emulated by running your IDE in a mode that leaves you your command window open, instead of adding it to your code Ctrl-F5.
You can keep track of the number of spaces you have and resize the string at the end.
int main()
{
string s = "What is your name?";
int length = s.length();
int write_index = 0;
for (const char &c : s)
{
if (c != ' ')
{
s[write_index++] = c;
}
else
{
length -= 1;
}
}
s.resize(length);
cout << s << endl;
}
Try this:
#include <string.h>
#include <iostream>
using namespace std;
int main()
{
string s = "What is your name?";
std::string aux(s.size(),' ');
int write_index = 0;
for (const char &c : s)
{
if (c != ' ')
{
aux[write_index++] = c;
}
}
cout << s << endl;
cout << aux << endl;
system("pause");
}
Now, I don't personally code C++, but this looks eerily similar to a for-each loop in C#, Java, and JavaScript; so I'll give it a go.
Let's first break down your code to see what's going on
int main() {
// creates a string object which is essentially a glorified array of chars
string s = "What is your name?";
int write_index = 0;
// for evry char "c" in the char-array "s"
for (const char &c : s) {
// if c isn't a space
if (c != ' ') {
// write c to s at index "write_index" then increment "write_index"
s[write_index++] = c;
}
}
std::cout << s << std::endl;
system("pause");
}
The logic seems good, so why does "what is your name?" turn into "whatisyourname?me?"? Simple. Because you're overwriting the existing array.
"what is your name?" is 18 characters long, and since you're only writing a non-space character to the array if it's not a space you're essentially copying characters one space left for every space in your text.
For example here's what happens after you run this code over the first 7 characters: "whatiss your name?", and after the first 12: "whatisyourur name?", and finally after all 18: "whatisyourname?me?". The length of the string never really changes.
So you got a number of options to solve this issue:
Build a new string from the old one with a string-builder (if such a thing exists in C++) and return the freshly created string.
Count the number of spaces you encounter and return a substring that is that many characters shorter (original is 18 chars - 3 spaces = new is 15 chars).
Reduce the length of the string by the required amount of characters (Thanks Yakk for this one)
This is a basic application of the copy_if algorithm from the standard library.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <iterator>
#include <string>
int main()
{
std::string s = "What is your name?";
std::copy_if(s.begin(), s.end(), std::ostream_iterator<char>(std::cout),
[](char c){ return !std::isspace(c); });
return 0;
}
outputs:
Whatisyourname?
If you actually need to remove them from the original string, then use the algorithm remove_if followed by erase.

converting individual string elements to their decimal equivalents in c++

I have a string str ( "1 + 2 = 3" ). I want to obtain the individual numbers of the string in their decimal values( not ASCII ). I have tried atoi and c_str(). But both them require the entire string to consist of only numbers. I am writing my code in C++.
Any help would be great.
My challenge is to evaluate a prefix expression. I am reading from a file where each line contains a prefix expression. My code snippet to tokenize and and store the variables is as shown below. Each line of the file contains numbers and operators(+,-,*) which are separated by a space.
Ex - line = ( * + 2 3 4);
ifstream file;
string line;
file.open(argv[1]);
while(!file.eof())
{
getline(file,line);
if(line.length()==0)
continue;
else
{
vector<int> vec;
string delimiters = " ";
size_t current;
size_t next = -1;
do
{
current = next + 1;
next = line.find_first_of( delimiters, current );
if((line[next] <=57)&&(line[next] >=48))
vec.push_back(atoi((line.substr( current, next - current )).c_str()));
}while (next != string::npos);
cout << vec[0] << endl;
}
}
file.close();
In this case vec[0] prints 50 not 2.
You need to learn to delimit a string. Your delimiting characters would be mathematical operators (ie:
C: creating array of strings from delimited source string
http://www.gnu.org/software/libc/manual/html_node/Finding-Tokens-in-a-String.html
In the case of the second link, you would do something like:
const char delimiters[] = "+-=";
With this knowledge, you can create an array of strings, and call atoi() on each string to get the numeric equivalent. Then you can use the address (array index) of each delimiter to determine which operator is there.
For just things like addition and subtraction, this will be dead simple. If you want order of operations and multiplication, parentheses, etc, your process flow logic will be more complicated.
For a more in-depth example, please see this final link. A simple command-line calculator in C. That should make it crystal clear.
http://stevehanov.ca/blog/index.php?id=26
You will not fall into your if, since your next position will be at a delimiter.
string delimiters = " ";
...
next = line.find_first_of( delimiters, current );
if((line[next] <=57)&&(line[next] >=48))
...
Since your delimiters consist of " ", then line[next] will be a space character.
From the description of your problem, you are missing code that will save away your operators. There is no code to attempt to find the operators.
You don't have to assume ASCII for testing for a digit. You can use is_digit() for example, or you can compare against '9' and '0'.
When you print your vector element, you may be accessing the vector inappropriately, because no item may have ever been inserted into the array.
Don't use fin.eof() to control a loop. That function is only useful after a read has failed.
There are a number of ways to get ints from a std::string, I'm choosing std::stoi() from the C++11 standard in this case.
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
typedef std::vector<int> ints;
bool is_known_operator(std::string const& token)
{
static char const* tokens[] = {"*", "/", "+", "-"};
return std::find(std::begin(tokens), std::end(tokens), token) != std::end(tokens);
}
ints tokenise(std::string const& line)
{
ints vec;
std::string token;
std::istringstream iss(line);
while (iss >> token)
{
if (is_known_operator(token))
{
std::cout << "Handle operator [" << token << "]" << std::endl;
}
else
{
try
{
auto number = std::stoi(token);
vec.push_back(number);
}
catch (const std::invalid_argument&)
{
std::cerr << "Unexpected item in the bagging area ["
<< token << "]" << std::endl;
}
}
}
return vec;
}
int main(int, const char *argv[])
{
std::ifstream file(argv[1]);
std::string line;
ints vec;
while (std::getline(file, line))
{
vec = tokenise(line);
}
std::cout << "The following " << vec.size() << " numbers were read:\n";
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, "\n"));
}