Ray
Ray

Reputation: 787

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.

Upvotes: 0

Views: 31835

Answers (8)

toshito
toshito

Reputation: 1

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;
                    }
                }
            }
        }



    }
}

Upvotes: 0

Dilip Kumar Yadav
Dilip Kumar Yadav

Reputation: 615

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

Upvotes: 0

rubber boots
rubber boots

Reputation: 15194

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;
}

Upvotes: 1

Fred Larson
Fred Larson

Reputation: 62073

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());

Upvotes: 18

anon
anon

Reputation:

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" );
}

Upvotes: 1

Draco Ater
Draco Ater

Reputation: 21226

The std::srting does not terminate with \0, you are mixing this with char* in C. So you should use resize.

Upvotes: 1

Kaz Dragon
Kaz Dragon

Reputation: 6809

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).

Upvotes: 4

Brian R. Bondy
Brian R. Bondy

Reputation: 347226

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);

Upvotes: 8

Related Questions