I have a string = "abcdefg". I will copy it to another string inside a loop. Then I want to erase only one character every time. First I will remove the character a from the first and it will be "bcdefg". Second time I will remove b and the string will be "acdefg". And so on. I tried to do it using erase() but it didn't work. You may take a look at how I tried:
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main() {
string abc = "abcdefg"; // the main string
int len = abc.length();
for(int i=0;i<len;i++)
{
string cba = abc; // I copy it to another string
cba.erase(i,i+1); // I try to erase only one element
cout<<cba<<endl;
}
return 0;
}
The output should be:
bcdefg
acdefg
abdefg
abcefg
abcdfg
abcdeg
abcdef
But my code prints:
bcdefg
adefg
abfg
abc
abcd
abcde
abcdef
Can anybody please suggest me a way to do it correctly?? I'm really in danger.
The std::basic_string::erase function you are calling takes an index and a count. The second parameter is the number of characters to remove and you should be using 1.
For some example code:
//M a r k
//0 1 2 3
string name = "Mark";
//erase the single character 'r' at position 2
name.erase(2, 1); //M a k
Related
I want the first character in string example1 to print out. Using example1[0] seems to work, but for some reason having an int variable have that same value will output 49. Why does this happen, and how can I make the LOG(print) print 1 instead of 49?
#include <iostream>
#include <string>
#define LOG(x) std::cout<<x<<std::endl;
int main() {
std::string example1 = {"1 2 3 4 5"};
int print = 0;
LOG(example1[0]);
//this prints 1
print = example1[0];
LOG(print)
//this, somehow, prints 49. Why?
}
When you write example1[0], that's a char; if you convert it to an int, it's the ASCII value of it (or, in older/different systems, the value in the specific character table).
This question already has answers here:
Difference between erase and remove
(7 answers)
Closed 2 years ago.
I recently tried a code mentioned somewhere on this site to remove blank spaces in a string. The answer suggested the function remove from the algorithm library (amazingly explained here: https://www.geeksforgeeks.org/stdremove-stdremove_if-c/) but it gives an unexpected output. It replaces all the blank spaces with some random numbers. Here is the code.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string a;
int b;
getline(cin, a);
remove(a.begin(), a.end(), ' ');
b = stoi(a);
cout << b << endl;
return 0;
}
If I input 14 546 32 for example it outputs 145463232. Oddly enough if I input 1 2 3 4 5 it outputs the correct thing: 12345.
Expected output, input:
I input any number with blank spaces in between some numbers.
It outputs the number without spaces.
I tried compiling it online with this compiler: https://www.onlinegdb.com/. It has the exact same output. Can anybody figure out what is wrong with the code. And also i need to turn the string into an integer to do some mathematical operations with the integer afterwards (that is why I use the stoi function). Thanks.
Interesting thing about std::remove is that it does not actually remove anything. =)
You will need to erase the character by yourself like this:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string a;
int b;
getline(cin, a);
a.erase(remove(a.begin(), a.end(), ' '), a.end());
b = stoi(a);
cout << b << endl;
return 0;
}
You can read more about Erase–remove here:
https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom
std::remove removes the elements that compare equal to its argument by shifting the remaining elements using move-assignment. It doesn't resize the container after shifting those elements. In your case, since the objects are of type char, they are simply copied to the beginning of the array. So the end of your string stays the same.
When you remove spaces from the first number, and shift everything to left, you get this:
old string: 14 546 32
new string: 145463232
When you do the same in the second case:
old string: 1 2 3 4 5
new string: 12345 4 5
The only reason you get the correct result in the second one is the space in-between. First number in the string (12345) is converted to int and returned.
Note that std::remove also returns an iterator to the new end of the list. You could use that to resize the string.
auto end = remove(a.begin(), a.end(), ' ');
a.resize(end - a.begin());
I'm just trying to use the alphabet to try and make words/names. When I do this the cout end up outputting nothing.
#include <iostream>
#include <ctime>
#include <string>
#include <stdlib.h>
using namespace std;
int main() {
char Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
string n;
n[0] = Alphabet[10];
n[1] = alphabet[4];
n[2] = alphabet[21];
n[3] = alphabet[8];
n[4] = alphabet[13];
cout << n << endl;
}
Your issue here is that n is an empty string, meaning you're trying to access indexes that don't exist.
To add characters to the string, you could use the string member function, push_back
n.push_back(Alphabet[10]);
n.push_back(alphabet[4]);
...
Alternatively, the += operator would also work:
n += Alphabet[10];
n += alphabet[4];
...
Furthermore, I'd suggest using .at() over the subscript operator ([]) with your strings, as .at() will do bounds checking for you (which would have made this issue a little more obvious).
When you create a string with string n;, an empty string is created. It has length zero, therefore trying to access character positions within the string with n[0] etc. does not work. These simply do not exist at that point.
As said in another answer, you can use the member function push_back to add a character to a string, increasing its length by one.
When you define n as string n;, then n will be an empty string (zero size and unspecified capacity), and accessing a string with an index beyond its size is undefined behaviour.
There are two principal ways to overcome this:
(1) Use operator += like in n += Alphabet[10];, such that the string object will adapt its size accordingly. Note that this may lead to realloc-operations internally from time to time.
(2) if you know the size in advance, with string n(5, ' ') you may reserve enough space in advance (and fill the string up with blanks in this case), such that realloc-operations will not have to occur.
I am a newbie in programing and stuck at a point where I have to compare the two strings using C++: string 1 and string 2 for the same characters and then delete those characters from string 1 and print the string 2. Looking forward for your help. My code goes like this:
#include<string>
#include<iostream>
#include<conio.h>
using namespace std;
int main()
{
string first_string;
string second_string;
string::size_type start_position=0;
cout<<"Please enter the first string: "<<endl;
getline(cin,first_string);
cout<<"Please enter the Second string: "<<endl;
getline(cin, second_string);
while ( (start_position = second_string.find(first_string, start_position)) != string::npos )
{
while ( (start_position = second_string.find(first_string, start_position)) != string::npos )
{
second_string.replace( start_position, first_string.size(), "" );
start_position++;
}
}
cout<<"The Result is as follws: "<<second_string<<endl;
getch();
return 0;
}
Looking forward for your help.
Regards,
Sam
Compare each char in string2 with all chars of string1. If that char from string2 doesn't match any in string1 then append this char to a new string else continue without appending. Continue this for all chars in string2. Now assign the new string as string1. This uses extra o(n) space but is simpler.
I would recommend using c_str to represent your string as an array of characters (or even better begin with an array of characters rather than the string datatype). After you do this write a function to go through each array and compare characters (removing where required), its a bit inefficient but it'll do the job and its simple.
Initially I have user input decimal numbers (0 - 15), and I will turn that into binary numbers.
Say these numbers are written into a text file, as shown in the picture. These numbers are arranged by the numbers of 1's. The dash - is used to separate different groups of 1.
I have to read this file, and compare strings of one group with the all the strings in the group below, i.e., Group 1 with all the strings in group 2, and group 2 - group 3.
The deal is that, only one column of 0 / 1 difference is allowed, and that column is replaced by letter t. If more than one column of difference is encountered, write none.
So say group 2, 0001 with group 3, 0011, only the second column is different. however, 0010 and 0101 are two columns of difference.
The result will be written into another file.....
At the moment, when I am reading these strings, I am using vector string. I came across bitset. What is important is that I have to access the character one at a time, meaning I have break the vector string into vector char. But it seems like there could be easier way to do it.
I even thought about a hash table - linked-list. Having group 1 assigned to H[0]. Each comparison is done as H[current-group] with H[current_group+1]. But beyond the first comparison (comparing 1's and 0's), the comparison beyond that will not work under this hash-linked way. So I gave up on that.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
int main() {
ifstream inFile("a.txt");
vector<string> svec;
copy(istream_iterator<string>(inFile), istream_iterator<string>(), back_inserter(svec));
copy(svec.begin(), svec.end(), ostream_iterator<string>(cout,"\n"));
for(int i = 0; i < svec.size(); i++)
{
cout << svec[i] << " ";
}
inFile.close();
return 0;
}
This is the sample code of writing it into a file....but like I said, the whole deal of vector seems impractical in my case....
Any help is appreciated. thanks
I don't understand your code snippet -- it looks like all it does is read in the input file into a vector of strings, which will then contain each whitespace-delimited word in a separate string, then write it back out in 2 different ways (once with words separated by \n, once with them separated by spaces).
It seems the main problem you're having is with reading and interpreting the file itself, as opposed to doing the necessary calculations -- right? That's what I hope this answer will help you with.
I think the line structure of the file is important -- right? In that case you would be better off using the global getline() function in the <string> header, which reads an entire line (rather than a whitespace-delimited word) into a string. (Admittedly that function is pretty well-hidden!) Also you don't actually need to read all the lines into a vector, and then process them -- it's more efficient and actually easier to distill them down to numbers or bitsets as you go:
vector<unsigned> last, curr; // An unsigned can comfortably hold 0-15
ifstream inf("a.txt");
while (true) {
string line;
getline(inf, line); // This is the group header: ignore it
while (getline(inf, line)) {
if (line == "-") {
break;
}
// This line contains a binary string: turn it into a number
// We ignore all characters that are not binary digits
unsigned val = 0;
for (int i = 0; i < line.size(); ++i) {
if (line[i] == '0' || line[i] == '1') {
val = (val << 1) + line[i] - '0';
}
}
curr.push_back(val);
}
// Either we reached EOF, or we saw a "-". Either way, compare
// the last 2 groups.
compare_them_somehow(curr, last); // Not doing everything for you ;)
last = curr; // Using swap() would be more efficient, but who cares
curr.clear();
if (inf) {
break; // Either the disk exploded, or we reached EOF, so we're done.
}
}
Perhaps I've misunderstood your goal, but strings are amenable to array member comparison:
string first = "001111";
string next = "110111";
int sizeFromTesting = 5;
int columnsOfDifference = 0;
for ( int UU = sizeFromTesting; UU >=0; UU-- )
{
if ( first[ UU ] != next[ UU ] )
columnsOfDifference++;
}
cout << columnsOfDifference;
cin.ignore( 99, '\n' );
return 0;
Substitute file streams and bound protection where appropriate.
Not applicable, but to literally bitwise compare variables, & both using a mask for each digit (000010 for second digit).
If or = 0, they match: both are 0. If they or = 1 and & = 1, that digit is 1 for both. Otherwise they differ. Repeat for all the bits and all the numbers in the group.
in vb.net
'group_0 with group_1
If (group_0_count > 0 AndAlso group_1_count > 0) Then
Dim result = ""
Dim index As Integer = 0
Dim g As Integer = 0
Dim h As Integer = 0
Dim i As Integer = 0
For g = 0 To group_0_count - 1
For h = 0 To group_1_count - 1
result = ""
index = 0
For i = 0 To 3
If group_1_0.Items(g).ToString.Chars(i) <> group_1_1.Items(h).ToString.Chars(i) Then
result &= "-"
index = index + 1
Else
result &= group_1_0.Items(g).ToString.Chars(i)
End If
Next
Next
Next
End If
Read it in as an integer, then all you should need is comparisons with bitshifts and bit masks.