Creating a word shifter - c++

For an assignment, I am working on creating a word shifter in C++. I have little to no experience with C++ so it has been very difficult. I think I am really close but just missing some syntax that is part of C++. Any help would be appreciated greatly.
string s = phrase;
int length = s.length();
//find length of input to create a new string
string new_phrase[length];
//create a new string that will be filled by my for loop
for (int i=0; i<length; i++)
//for loop to go through and change the letter from the original to the new and then put into a string
{
int letter = int(s[i]);
int new_phrase[i] = letter + shift;
//this is where I am coming up with an error saying that new_phrase is not initialized
if (new_phrase[i] > 122)
//make sure that it goes back to a if shifting past z
{
new_phrase[i] = new_phrase[i] - 26;
}
}
cout << new_phrase<< endl;

Considering your syntax,I wrote an example for you.Besides,it is conventional
to write comment before it's relevant code.
#include <iostream>
#include <string>
using namespace std;
int main()
{
//test value;
int shift = 3;
string s = "hello string";
//find length of input to create a new string
int length = s.length();
//create a new string.it's length is same as 's' and initialized with ' ';
string new_phrase(length, ' ');
for (int i=0; i<length; i++)
{
//no need to cast explicitly.It will be done implicitly.
int letter = s[i];
//It's assignment, not declaration
new_phrase[i] = letter + shift;
//'z' is equal to 126.but it's more readable
if (new_phrase[i] > 'z')
{
new_phrase[i] = new_phrase[i] - ('z' - 'a' + 1);
}
}
cout << new_phrase<< endl;
}

This should work.
// must be unsigned char for overflow checking to work.
char Shifter(unsigned char letter)
{
letter = letter + shift;
if (letter > 'z')
letter = letter - 26;
return letter;
}
// :
// :
string new_phrase = phrase; // mainly just allocating a string the same size.
// Step throught each char in phrase, preform Shifter on the char, then
// store the result in new_phrase.
std::transform(phrase.begin(), phrase.end(), new_phrase.begin(), Shifter);
cout << new_phrase<< endl;
UPDATE: made letter unsigned, so the overflow check works.

Try and investigate this code
#include <iostream>
#include <string>
#include <cctype>
void ShiftRight( std::string &s, std::string::size_type n )
{
if ( n >= 'Z' - 'A' + 1 ) return;
for ( char &c : s )
{
bool lower_case = std::islower( c );
c = std::toupper( c );
c = ( c + n -'A' ) % ('Z' -'A' + 1 ) + 'A';
if ( lower_case ) c = std::tolower( c );
}
}
int main()
{
std::string s( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
std::cout << s << std::endl << std::endl;
for ( std::string::size_type i = 1; i <= 'Z' -'A' + 1; i++ )
{
std::str std::string s( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
ShiftRight( s, i );
std::cout << s << std::endl;
}
return 0;
}
The output is
ABCDEFGHIJKLMNOPQRSTUVWXYZ
BCDEFGHIJKLMNOPQRSTUVWXYZA
CDEFGHIJKLMNOPQRSTUVWXYZAB
DEFGHIJKLMNOPQRSTUVWXYZABC
EFGHIJKLMNOPQRSTUVWXYZABCD
FGHIJKLMNOPQRSTUVWXYZABCDE
GHIJKLMNOPQRSTUVWXYZABCDEF
HIJKLMNOPQRSTUVWXYZABCDEFG
IJKLMNOPQRSTUVWXYZABCDEFGH
JKLMNOPQRSTUVWXYZABCDEFGHI
KLMNOPQRSTUVWXYZABCDEFGHIJ
LMNOPQRSTUVWXYZABCDEFGHIJK
MNOPQRSTUVWXYZABCDEFGHIJKL
NOPQRSTUVWXYZABCDEFGHIJKLM
OPQRSTUVWXYZABCDEFGHIJKLMN
PQRSTUVWXYZABCDEFGHIJKLMNO
QRSTUVWXYZABCDEFGHIJKLMNOP
RSTUVWXYZABCDEFGHIJKLMNOPQ
STUVWXYZABCDEFGHIJKLMNOPQR
TUVWXYZABCDEFGHIJKLMNOPQRS
UVWXYZABCDEFGHIJKLMNOPQRST
VWXYZABCDEFGHIJKLMNOPQRSTU
WXYZABCDEFGHIJKLMNOPQRSTUV
XYZABCDEFGHIJKLMNOPQRSTUVW
YZABCDEFGHIJKLMNOPQRSTUVWX
ZABCDEFGHIJKLMNOPQRSTUVWXY
ABCDEFGHIJKLMNOPQRSTUVWXYZ
As for your code then it of course is wrong. You have not to define an array of strings. And do not use magic numbers as for example 122.
Also you may include in my code a check that a next symbol is an alpha symbol.

Related

How can I replace every letter in a string with opposite letter? C++

How can I replace every letter in a string with opposite letter? For example, replace "a" with "z", replace "B" with "Y". How can I make it for every string?
Please consider this solution:
From the ASCII table http://www.asciitable.com/
CHAR DECIMAL
"A" 65
"B" 66
...
"Y" 89
"Z" 90
If we want to swap 'B' (which is the second char past 'A') for 'Y' (which is the second to last char from 'Z'), we might want to" take the distance from 'A' and subtract that from 'Z', as in 'Z' - (x - 'A')
#include <string>
#include <iostream>
char invert_char(char x)
{
if (x >= 'a' && x <= 'z')
return char('a' -x + 'z');
if (x >= 'A' && x <= 'Z')
return char('A' -x + 'Z');
return x;
}
std::string invert_string(std::string str)
{
for (auto& c: str)
c = invert_char(c);
return str;
}
int main()
{
std::string test = "ABCDEF UVWXYZ";
std::cout << test << std::endl;
std::cout << invert_string(test) << std::endl;
return 0;
}
Use a translation/lookup array.
Define an array (vector) of source letters, and a translation string. You can use a pair of maps to to encode and decode, or you could use brute force string search for every character (both ways shown below.
class translate {
std::string original;
std::string coded;
std::map<char,char> encode_map;
std::map<char,char> decode_map;
translation function (brute force),
public:
// you could pass original and coded string pair, or use defaults
translate() {
original="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
coded="ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba";
for( size_t ndx = 0; ndx < order; ++ndx ) {
encode[original.at(ndx)] = coded.at(ndx);
decode[coded.at(ndx)] = original.at(ndx);
}
}
//brute force scans original to find coded position, n*O(m)
std::string
brute(std::string src)
{
std::string dest;
for( auto& ch : src ) {
dest.push_back(coded.at(find(original,ch)));
}
return dest;
}
//use map for encode, decode, n*O(log(m))
std::string
encode(std::string src)
{
std::string dest;
for( auto& ch : src ) {
dest.push_back(encode_map[ch]);
}
return dest;
}
std::string
decode(std::string src)
{
std::string dest;
for( auto& ch : src ) {
dest.push_back(decode_map[ch]);
}
return dest;
}
}
std::transform provides a very convenient way to apply a transformation to every member of a container. With std::string you can easily apply your wanted transformation of grabbing the character from the opposite end of the alphabet by testing if the current character isupper() and if so, grab the character offset from 'Z' the same number of characters as the current character is from 'A'. (same would apply for islower() in case of a lowercase character)
If the character is not an alpha-character, then it remains unchanged. Using std::transform, your function can be reduced to:
void oppositechar (std::string& s)
{
std::transform (s.begin(), s.end(), s.begin(),
[](unsigned char c) {
if (std::isupper(c)) /* if upper */
c = 'Z' - c + 'A'; /* replace w/dist from Z */
else if (std::islower(c)) /* if lower */
c = 'z' - c + 'a'; /* replace w/dist from z */
return c;
});
}
Adding a short program that lets you enter any string as the first argument on the command line (or using "Hello World" if no argument is provided), you could do:
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
void oppositechar (std::string& s)
{
std::transform (s.begin(), s.end(), s.begin(),
[](unsigned char c) {
if (std::isupper(c)) /* if upper */
c = 'Z' - c + 'A'; /* replace w/dist from Z */
else if (std::islower(c)) /* if lower */
c = 'z' - c + 'a'; /* replace w/dist from z */
return c;
});
}
int main (int argc, char **argv) {
std::string s = argc > 1 ? argv[1] : "Hello World";
std::cout << s << '\n';
oppositechar (s); /* transform s with encoding */
std::cout << s << '\n';
}
Example Use/Output
$ ./bin/transformoppositechar
Hello World
Svool Dliow
$ ./bin/transformoppositechar "ABC-XYZ abc-xyz"
ABC-XYZ abc-xyz
ZYX-CBA zyx-cba
Look things over and let me know if I did not understand what you were attempting to do correctly, or if you have further questions.
You can check for each letter in the input string and replace it with the opposite letter manually by writing if statements. But there's a more programmatic way.
In English alphabet there are only 26 letters. To get the inverse string, you will replace any a with z, any b with y. That means you replace 1st letter with 26th letter, 2nd letter with 25th letter. As programmers, we count from 0. So you replace 0th letter with 26th and so on. If the input letter is a, i.e 0th letter, you'll replace it with (26 - 0)th letter. If it is b, i.e 1st letter you'll replace it with (26 - 1)th letter and so on. If it is nth letter, replace it with (26 - n)th letter.
But in ascii table, a is 97th and A is 65th. So we have to substract 97 from ascii value of relevant letter before do the above explained math. Substract 65 if letter is upper case.
#include <iostream>
using namespace std;
string inverse(string data){
string inverse_string = "";
for(char c : data){
int limit = 97;
if (((int)c) < 97) limit = 65; //assumes the letter is uppercase
int chr_code = (int)c - limit;
int inverse_chr_code = 26 - chr_code;
int result = inverse_chr_code + (limit - 1);
inverse_string += (char)result;
}
return inverse_string;
}
int main(){
cout << inverse("apPle");
return 0;
}
Above code gives output "zkKov" i.e the inverse string to "apPle"
Try the following code:
char newChar = 'z' - (oldChar - 'a'); // If oldChar is in between 'a' and 'z'
char newChar = 'Z' - (oldChar - 'A'); // If oldChar is in between 'A' and 'Z'
See this for ASCII table.
You need to handle the situation like oldChar is a valid alphabet ((a <= oldChar and oldChar <= 'z') or (A <= oldChar and oldChar <= 'Z'))
See this code:
#include <iostream>
#include <string>
#include <exception>
char char_invert(char x)
{
if ((x >= 'a') and (x <= 'z'))
return 'z' - (x - 'a');
if ((x >= 'A') and (x <= 'Z'))
return 'Z' - (x - 'A');
throw std::runtime_error("Invalid Character");
}
std::string string_invert(std::string str)
{
std::string result;
for (auto& c: str)
result.push_back(char_invert(c));
return result;
}
int main()
{
std::string example = "aBCDEFUVWXYZ";
std::cout << example << std::endl;
std::cout << string_invert(example) << std::endl;
return 0;
}
try this. explanation of code is in the comments.
//---generic: this supports any string buffer such as const char*.
void invertStrBuf(char* p_szArr, size_t p_size){
for(size_t a = 0; a < p_size; a++){
char item = p_szArr[a];
char sc = item & ~0x20; //force convert to upper case.
if('A' <= sc && sc <= 'Z'){
sc = 'Z' - (sc - 'A'); //invert letter
p_szArr[a] = sc | (item & 0x20); //change back to original case and then save.
}
}
}
//---std::string.
void invertStr(std::string& p_str){
invertStrBuf(&p_str[0], p_str.size());
}
void main(){
//---convert std::string
std::string sVal = "abcZYX123&*(";
invertStr(sVal);
cout << "string: " << sVal << endl;
// //---convert char buffer.
// const char sampVal = "another 123 EXAMPLE +_\[]";
// size_t sizeSampVal = strlen(sampVal);
// char* charBuf = malloc(sizeSampVal+1);
// memmove(charBuf, sampVal, sizeSampVal+1);
// invertStrBuf(&charBuf[0], strlen(charBuf));
// cout << "charBuf[]: " << charBuf << endl;
}

Writing program in C++ using Microsoft VS, but I get a debug assertion message here. It runs on cpp.sh and repl.it fine, but not on VS. What can I do?

This function is meant to remove all special characters, numbers, and whitespace from the char array.
// Michael E. Torres II
// Vigenere Cipher
// February 4, 2018
// C++ code to implement Vigenere Cipher
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <cctype>
#include <iterator>
#include <sstream>
#include <functional>
using namespace std;
// This function generates the key in
// a cyclic manner until it's length isi'nt
// equal to the length of original text
string generateKey(string str, string key)
{
int x = str.size();
for (int i = 0; ; i++)
{
if (x == i)
i = 0;
if (key.size() == str.size())
break;
key.push_back(key[i]);
}
return key;
}
// This function returns the encrypted text
// generated with the help of the key
string cipherText(string str, string key)
{
string cipher_text;
for (int i = 0; i < str.size(); i++)
{
// converting in range 0-25
int x = (str[i] + key[i]) % 26;
// convert into alphabets(ASCII)
x += 'A';
cipher_text.push_back(x);
}
return cipher_text;
}
// This function decrypts the encrypted text
// and returns the original text
string originalText(string cipher_text, string key)
{
string orig_text;
for (int i = 0; i < cipher_text.size(); i++)
{
// converting in range 0-25
int x = (cipher_text[i] - key[i] + 26) % 26;
// convert into alphabets(ASCII)
x += 'A';
orig_text.push_back(x);
transform(orig_text.begin(), orig_text.end(), orig_text.begin(), ::tolower);
}
return orig_text;
}
string removeNonAlpha(char *str)
{
unsigned long i = 0;
unsigned long j = 0;
char c;
while ((c = str[i++]) != '\0')
{
if (isalpha(c)) // this is where the breakpoint is automatically placed
{
str[j++] = c;
}
}
str[j] = '\0';
return str;
}
// Driver program to test the above function
int main(int argc, char *argv[])
{
string keyword = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
stringstream ss;
char a[] = "“I think and think for months and years. Ninety-nine times, the conclusion is false. The hundredth time I am right.” – Albert Einstein “Imagination is more important than knowledge. For knowledge is limited, whereas imagination embraces the entire world, stimulating progress, giving birth to evolution.” – Albert Einstein";
int i = 0;
string str = removeNonAlpha(a);
str.append(512 - str.length(), 'X');
transform(str.begin(), str.end(), str.begin(), ::toupper);
transform(keyword.begin(), keyword.end(), keyword.begin(), ::toupper);
string key = generateKey(str, keyword);
string cipher_text = cipherText(str, key);
transform(cipher_text.begin(), cipher_text.end(), cipher_text.begin(), ::tolower);
transform(key.begin(), key.end(), key.begin(), ::tolower);
string orig = originalText(cipher_text, key);
cout << "Original/Decrypted Text : " << "\n";
for (int i = 0; i < orig.size(); i += 81)
orig.insert(i, "\n");
cout << orig;
cout << "\n\n" << "Ciphertext : " << "\n";
for (int i = 0; i < cipher_text.size(); i += 81)
cipher_text.insert(i, "\n");
cout << cipher_text;
cout << "\n\nPress ENTER key to Continue\n";
getchar();
return 0;
}
The char array works fine with this while loop, so long as there are no special characters [.,%$#!^]. As soon as there are any special characters in the char array, it gives me the debug assertion:
"Program: ...\Projects\ConsoleApplication17\Debug\ConsoleApplication17.exe
File: minkernel\crts\ucrt\src\appcrt\convert\isctype.cpp
Line: 42
Expression: c >= -1 && c <= 255
...
The program '[11048] ConsoleApplication17.exe' has exited with code 3 (0x3)."
If I run this on repl.it or cpp.sh, I get no issues though. I appreciate any help. Thank you.
It isn't done at all. It needs to be cleaned up a lot, but I'm just trying to test it as is.
see https://msdn.microsoft.com/en-us/library/xt82b8z8.aspx
isalpha expects a number between 0 and 0xFF:
The behavior of isalpha and _isalpha_l is undefined if c is not EOF or
in the range 0 through 0xFF, inclusive. When a debug CRT library is
used and c is not one of these values, the functions raise an
assertion.
You need to cast you char to an unsigned char before passing to isalpha.

my code doesn't run some thing wrong about strings, c++

I was training on solving algorithms, I wrote a code but it won't compile
in (if) I can not check s[i]=='S' .
I'm trying to if s[i] is S character or not but I don't know where my problem is.
If I can't use this syntax, what could be a solution?
#include<iostream>
#include<string>
using namespace std;
int main()
{
double v_w=25,v_s=25,d_w=25,d_s=25;
int n;
cin>>n;
string s[]={"WSSS"};
int i ;
for (i=0; i<n; i++)
{
if( s[i] == "W" )
{
v_s += 50;
d_w = d_w + (v_w/2);
d_s = d_s + (v_s/2);
cout<<"1 \n";
}
if(s[i]=='W')
{
v_w +=50;
d_w = d_w + (v_w/2);
d_s = d_s + (v_s/2);
cout<<"2 \n";
}
return 0;
}
cout<< d_w<<endl<<d_s;
}
string s[]={"WSSS"}; means an array of strings which the first one is "WSSS".
What you need is:
std::string s="WSSS";
string s[] = {"Hello"} is an array of strings (well, of one string).
If you iterate over it, or index into it s[0] is "Hello".
Whereas
string s{"Hello"} is one string, which is made up of characters.
If you iterate over it, or index into it s[0], you will get 'H'.
To pre-empt all the other things that are going to go wrong when the string versus character problem is sorted, lets move the return 0; from the middle of the for loop.
Then let's think about what happens if the number n entered is larger than the length of the string:
int n;
cin>>n; //<- no reason to assume this will be s.length (0 or less) or even positive
string s{"WSSS"}; //one string is probably enough
int i ;
for(i=0;i<n;i++)
{
if( s[i] == 'W' ) //ARGGGGGGG may have gone beyond the end of s
{
In fact, let's just drop that for now and come back to it later. And let's use a range based for loop...
#include<iostream>
#include<string>
using namespace std;
int main()
{
double v_w = 25, v_s = 25, d_w = 25, d_s = 25;
string s{ "WSSS" };
for (auto && c : s)
{
if (c == 'W')
{
v_w += 50;
d_w = d_w + (v_w / 2);
d_s = d_s + (v_s / 2);
cout << "2 \n";
}
}
cout << d_w << '\n' << d_s << '\n'; //<- removed endl just because...
return 0;
}
s is an array of strings in this case it has only element:
string s[] = {"WSSS"};
so writing s[2]; // is Undefined behavior
your code will produce a UB if the user enters n greater than the number of elements in s:
n = 4;
for(i = 0; i < n; i++) // s[3] will be used which causes UB
{
if( s[i] == 'W' ) // s[i] is a string not just a single char
{
}
}
also as long as s is an array of strings then to check its elements check them as strings not just single chars:
if( s[i] == "W" ) // not if( s[i] == 'W' )
I think you wanted a single string:
string s = {"WSSS"};
because maybe you are accustomed to add the subscript operator to character strings:
char s[] = {"WSSS"};
if so then the condition above is correct:
if( s[i] == 'W' )

producing all anagrams in a string c++

I saw this problem online, and I was trying to solve it in C++. I have the following algorithm:
char permutations( const char* word ){
int size = strlen( word );
if( size <= 1 ){
return word;
}
else{
string output = word[ 0 ];
for( int i = 0; i < size; i++ ){
output += permutations( word );
cout << output << endl;
output = word[ i ];
}
}
return "";
}
For example, if I have abc as my input, I want to display abc, acb, bac, bca, cab, cba.
So, what I'm trying to do is
'abc' => 'a' + 'bc' => 'a' + 'b' + 'c'
=> 'a' + 'c' + 'b'
so I need o pass a word less char every function call.
Could someone please help how to do it?
I suggest doing it using the algorithm header library in C++, much easier; and as a function can be written like this:
void anagram(string input){
sort(input.begin(), input.end());
do
cout << input << endl;
while(next_permutation(input.begin(), input.end()));
}
However since you want it without the STL, you can do it like so:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap (char *x, char *y)
{
char ch = *x;
*x = *y;
*y = ch;
};
void permutate_(char* str, size_t index )
{
size_t i = 0;
size_t slen = strlen(str);
char lastChar = 0;
if (index == slen )
{
puts(str);
return;
}
for (i = index; i < slen; i++ )
{
if (lastChar == str[i])
continue;
else
lastChar = str[i];
swap(str+index, str+i);
permutate_(str, index + 1);
swap(str+index, str+i);
}
}
// pretty lame, but effective, comparitor for determining winner
static int cmpch(const void * a, const void * b)
{
return ( *(char*)a - *(char*)b );
}
// loader for real permutor
void permutate(char* str)
{
qsort(str, strlen(str), sizeof(str[0]), cmpch);
permutate_(str, 0);
}
Which you can call by sending it a sorted array of characters,
permutate("Hello World");
The non-STL approach was gotten from here.
The STL is wonderful:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void permutations(const char *word) {
string s = word;
sort(s.begin(), s.end());
cout << s << endl;
while(next_permutation(s.begin(), s.end()))
cout << s << endl;
}
int main() {
permutations("abc");
return 0;
}
Now, next_permutation can be implemented quite simply. From the end of the string, iterate backwards until you find an element x which is less than the next element. Swap x with the next value larger than x in the remainder of the string, and reverse the elements coming afterwards. So, abcd becomes abdc since c < d; cdba becomes dabc since c < d and we flip the last three letters of dcba; bdca becomes cabd because b < d and we swap b for c.

remove commas from string

I created a program in C++ that remove commas (,) from a given integer. i.e. 2,00,00 would return 20000. I am not using any new space. Here is the program I created:
void removeCommas(string& str1, int len)
{
int j = 0;
for (int i = 0; i < len; i++)
{
if (str1[i] == ',')
{
continue;
}
else
{
str1[j] = str1[i];
j++;
}
}
str1[j] = '\0';
}
void main()
{
string str1;
getline(cin, str1);
int i = str1.length();
removeCommas(str1, i);
cout << "the new string " << str1 << endl;
}
Here is the result I get:
Input : 2,000,00
String length =8
Output = 200000 0
Length = 8
My question is that why does it show the length has 8 in output and shows the rest of string when I did put a null character. It should show output as 200000 and length has 6.
Let the standard library do the work for you:
#include <algorithm>
str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
If you don't want to modify the original string, that's easy too:
std::string str2(str1.size(), '0');
str2.erase(std::remove_copy(str1.begin(), str1.end(), str2.begin(), ','), str2.end());
You need to do a resize instead at the end.
Contrary to popular belief an std::string CAN contain binary data including 0s. An std::string 's .size() is not related to the string containing a NULL termination.
std::string s("\0\0", 2);
assert(s.size() == 2);
The answer is probably that std::strings aren't NUL-terminated. Instead of setting the end+1'th character to '\0', you should use str.resize(new_length);.
Edit: Also consider that, if your source string has no commas in it, then your '\0' will be written one past the end of the string (which will probably just happen to work, but is incorrect).
The std::srting does not terminate with \0, you are mixing this with char* in C. So you should use resize.
The solution has already been posted by Fred L.
In a "procedural fashion" (without "algorithm")
your program would look like:
void removeStuff(string& str, char character)
{
size_t pos;
while( (pos=str.find(character)) != string::npos )
str.erase(pos, 1);
}
void main()
{
string str1;
getline(cin, str1);
removeStuff(str1, ',');
cout<<"the new string "<<str1<<endl;
}
then.
Regards
rbo
EDIT / Addendum:
In order to adress some efficiency concerns of readers,
I tried to come up with the fastest solution possible.
Of course, this should kick in on string sizes over
about 10^5 characters with some characters to-be-removed
included:
void fastRemoveStuff(string& str, char character)
{
size_t len = str.length();
char *t, *buffer = new char[len];
const char *p, *q;
t = buffer, p = q = str.data();
while( p=(const char*)memchr(q, character, len-(p-q)) ) {
memcpy(t, q, p-q);
t += p-q, q = p+1;
}
if( q-str.data() != len ) {
size_t tail = len - (q-str.data());
memcpy(t, q, tail);
t += tail;
}
str.assign(buffer, t-buffer);
delete [] buffer;
}
void main()
{
string str1 = "56,4,44,55,5,55"; // should be large, 10^6 is good
// getline(cin, str1);
cout<<"the old string " << str1 << endl;
fastRemoveStuff(str1, ',');
cout<<"the new string " << str1 << endl;
}
My own procedural version:
#include <string>
#include <cassert>
using namespace std;
string Remove( const string & s, char c ) {
string r;
r.reserve( s.size() );
for ( unsigned int i = 0; i < s.size(); i++ ) {
if ( s[i] != c ) {
r += s[i];
}
}
return r;
}
int main() {
assert( Remove( "Foo,Bar,Zod", ',' ) == "FooBarZod" );
}
Here is the program:
void main()
{
int i ;
char n[20] ;
clrscr() ;
printf("Enter a number. ") ;
gets(n) ;
printf("Number without comma is:") ;
for(i=0 ; n[i]!='\0' ; i++)
if(n[i] != ',')
putchar(n[i]) ;
getch();
}
For detailed description you can refer this blog: http://tutorialsschool.com/c-programming/c-programs/remove-comma-from-string.php
The same has been discussed in this post: How to remove commas from a string in C
Well, if youre planing to read from a file using c++. I found a method, while I dont think thats the best method though, but after I came to these forums to search for help before, I think its time to contribute with my effort aswell.
Look, here is the catch, what I'm going to present you is part of the source code of the map editor Im building on right now, that map editor obviously has the purpose to create maps for a 2D RPG game, the same style as the classic Pokemon games for example. But this code was more towards the development of the world map editor.
`int strStartPos = 0;
int strSize = 0;
int arrayPointInfoDepth = 0;
for (int x = 0; x < (m_wMapWidth / (TileSize / 2)); x++) {
for (int y = 0; y < (m_wMapHeight / (TileSize / 2)); y++) {
if (ss >> str) {
for (int strIterator = 0; strIterator < str.length(); strIterator++) {
if (str[strIterator] == ',') {`
Here we need to define the size of the string we want to extract after the previous comma and before the next comma
`strSize = strIterator - strStartPos;`
And here, we do the actual transformation, we give to the vector that is a 3D vector btw the string we want to extract at that moment
`m_wMapPointInfo[x][y][arrayPointInfoDepth] = str.substr(strStartPos, strSize);`
And here, we just define that starting position for the next small piece of the string we want to extract, so the +1 means that after the comma we just passed
strStartPos = strIterator + 1;
Here, well since my vector has only 6 postions that is defined by WorldMapPointInfos we need to increment the third dimension of the array and finally do a check point where if the info has arrived the number 6 then break the loop
arrayPointInfoDepth++;
if (arrayPointInfoDepth == WorldMapPointInfos) {
strStartPos = 0;
arrayPointInfoDepth = 0;
break;
}
}
}
}
}
}
Either way on my code, think abt that the vector is just a string, thats all you need to know, hope this helps though :/
Full view:
int strStartPos = 0;
int strSize = 0;
int arrayPointInfoDepth = 0;
for (int x = 0; x < (m_wMapWidth / (TileSize / 2)); x++) {
for (int y = 0; y < (m_wMapHeight / (TileSize / 2)); y++) {
if (ss >> str) {
for (int strIterator = 0; strIterator < str.length(); strIterator++) {
if (str[strIterator] == ',') {
strSize = strIterator - strStartPos;
m_wMapPointInfo[x][y][arrayPointInfoDepth] = str.substr(strStartPos, strSize);
strStartPos = strIterator + 1;
arrayPointInfoDepth++;
if (arrayPointInfoDepth == WorldMapPointInfos) {
strStartPos = 0;
arrayPointInfoDepth = 0;
break;
}
}
}
}
}
}