Thread: Strange String replacement...

  1. #1
    Registered User
    Join Date
    Jun 2007
    Location
    Rio de Janeiro, Brasil
    Posts
    48

    Unhappy Strange String replacement...

    Hello,

    I'm not a C programmer for a long time (more than 8 years) and I don't know much more about the strings functions that we have today aside the basic ones...

    I want to do some search/calculate/replace in a string but I don't know the functions well aside do in the hard code way, char by char... which I think should exist a better way to solve...

    here's what I need:

    I have a big string, and inside we have N times like this code:

    "origin" "-264 -256 16"

    the numbers aren't the same of course, and I need to replace all these origins in Z axis plus 15... (in this case, I need to add 15 to the 16 value)

    so I need to turn that string into:

    "origin" "-264 -256 31"

    it's not always 2 chars, could be even like:

    "origin" "-264 -256 1234"

    but in all the cases is just add 15 to the Z axis to fix a bug.

    so we need to get the number between the third space and third " after the string origin, convert to number, add 15, and replace in the string.

    this must be done to all origins found on the string.

    any ideas?

    thanks a lot!
    Last edited by hajas; 06-10-2007 at 02:23 PM.

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Sounds like something a regex library would be best able to do. Boost.Regex or Boost.Xpressive for example.

    http://www.boost.org/
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    Jun 2007
    Location
    Rio de Janeiro, Brasil
    Posts
    48
    hmmm... went there... but is so much big to be an answer...

    I really want a function(s) that set 2 positions in a string and bring me that substring, then I need to changed and replace back.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I would use a stringstream to read the data into separate variables and write it back out again with the appropriate changes. Doing string manipulation is hard because you don't know how many digits the numbers are.

  5. #5
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    This is not very good, but heres an example I made that gets the index of the first space, and then the first " that comes after it. It would need some work to do what you want it to do, but its just to give a rough idea of how you can get these two indexes. (sorry its in C)
    Code:
    #include <stdio.h>
    
    void GetSection(char*s)
    {
         int count=0;
         int start_index=-1;
         int end_index;
         while(*s)
         {
                  if(start_index == -1)
                  {
                        if(*s == ' ')
                              start_index=count;
                  }
                  else if(*s == '"')
                          end_index=count;
                  s++;  
                  count++;        
         }
         printf("Start: &#37;i    End: %i", start_index, end_index);
    }
    
    int main()
    {
        char str[]="dejfd siEUGH\"Fedfj";
        puts(str);
        GetSection(&str[0]);
        getchar();
    }
    Then you just need to split the string in three parts, convert the middle part to a number, add 15 to it, convert it back to a string, then concatenate the three strings.
    Last edited by mike_g; 06-10-2007 at 03:33 PM.

  6. #6
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    Perhaps the least efficient way, but I think it oughta work:

    Code:
    void change_em(std::vector<std::string> & coords)
    {
       std::stringstream s;
       int x, y, z;
       std::vector<std::string>::iterator it = coords.begin();
    
       while(++it != coords.end())
       {
         s.str(*it);
         s >> x >> y >> z;
         z += 15;
         s.str(std::string());  //in case z < 0 and + 15 makes for fewer digits
         s << x << y << z;
         *it = s.str();
         x = y = z = 0;
       }
    }
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    If you just want the answer, and don't even care about what language it's written in, then use something like this
    Code:
    #!/bin/perl -w
    use strict;
    while ( <> ) {
        if ( /(.*?)(\d+)\"/ ) {
            print $1 . ($2+15) . "\"\n";
        }
    }
    I copy/pasted a couple of lines and got
    Code:
    $ perl foo.pl
    "origin" "-264 -256 16"
    "origin" "-264 -256 31"
    "origin" "-264 -256 1234"
    "origin" "-264 -256 1249"
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Jun 2007
    Location
    Rio de Janeiro, Brasil
    Posts
    48

    Thumbs up thanks!

    hmmm... it's not question of logic, but language knownlege... which I don't know how to do it in C, but I can do it in Cold Fusion per exemple...

    and another thing, the string don't have ONLY code like I show you, here a real exemple:

    Code:
    {"classname" "worldspawn"}{"origin" "-256 248 16""classname" "info_player_deathmatch"}{"classname" "info_player_deathmatch""origin" "248 256 16"}{"origin" "248 -256 16""classname" "info_player_deathmatch"}{"classname" "info_player_deathmatch""origin" "-264 -256 16"}{"origin" "-176 -200 24""classname" "weapon_rocketlauncher"}{"classname" "weapon_rocketlauncher""origin" "-184 192 24"}{"origin" "168 184 24""classname" "weapon_rocketlauncher"}{"origin" "-184 -264 24""classname" "ammo_rockets"}{"classname" "ammo_rockets""origin" "192 -256 24"}{"origin" "184 128 24""classname" "ammo_rockets"}{"classname" "ammo_rockets""origin" "-184 128 24"}{"origin" "216 -192 24""classname" "weapon_rocketlauncher"}{"light" "400""origin" "-8 0 208""classname" "light"}
    ok, so I need to change Z, adding 15 to them to EVERY origin in this code.

    so I must to find "origin" first, got the substring between the next 3rd space and next ", convert to number (I think is needed), add 15, and replace in the original string... this must be made to each origin ONCE! and ONLY once!

    so I really need this answer in C++ or at least and C....

    thanks for all the help!

  9. #9
    Registered User
    Join Date
    Jun 2007
    Location
    Rio de Janeiro, Brasil
    Posts
    48

    Lightbulb pseudocode....

    take a look in this pseudocode:

    Code:
    while can find "origin" into String do {
       strReplaceFirst (String, origin, fhajas); // replace FIRST origin for fhajas in the string
       posA = find 3rd space after fhajas;
       posB = find next " after posA;
       Str1 = GetSubstring (String[0],posA);
       Str2 = GetSubstring (posB,String[size]);
       num = GetSubstring (posA, posB);
       ToNumber(num) += 15;
       String = Str1 + num + Str2;
    }
    strReplace (String, fhajas, origin) // replace ALL fhajas for origin in the string
    could you write this in C++ to me?

    feel free to suggest a better solution.

    thanks a lot!
    Last edited by hajas; 06-11-2007 at 08:20 AM.

  10. #10
    Registered User
    Join Date
    Jun 2007
    Location
    Rio de Janeiro, Brasil
    Posts
    48

    Exclamation that solution will not work, here a new one!

    well, I realize that I can't change all origins, because I'll cause problems to other classes....
    so I can only change info_player_deathmatch and info_player_start classes

    so here the new pseudocode to solve this:

    Code:
    set working = 1;
    while working == 1 {
    	if "{" not found{
    		set working = 0;
    	else{
    	 	subs = GetSubstring(String, first {, first });
    		Str1 = GetSubstring (String[0], subs[0]);
    		Str2 = GetSubstring (subs[size],String[size]);
    		if found (info_player_deathmatch || info_player_start) in subs {
      			find "origin" location;
    			posA = find 3rd space after origin location;
    			posB = find next " after posA;
    			Subs1 = GetSubstring (subs[0],posA);
    			Subs2 = GetSubstring (posB,subs[size]);
    			num = GetSubstring (posA, posB);
    			ToNumber(num) += 15;
      			subs = Subs1 + num + Subs2;
    			ReplaceAll (subs, {, [);
    			ReplaceAll (subs, }, ]);
    		}
    	}
    }
    ReplaceAll (String, [, {);
    ReplaceAll (String, ], });
    any inputs?
    Last edited by hajas; 06-11-2007 at 11:16 AM.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You've got the pseudo-code, now go ahead and do it.

    Or at least have a go at it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Jun 2007
    Location
    Rio de Janeiro, Brasil
    Posts
    48

    Question

    Quote Originally Posted by Salem View Post
    You've got the pseudo-code, now go ahead and do it.

    Or at least have a go at it.
    can you give me the right functions to use? I know how to code, I only don't want to code anything since I know that must have functions that already can make this.

    if not, I'll need to make this functions too...

    here my "fake" fuctions used:

    ReplaceAll (String, StringRemove, StringReplace)
    - replace all strings found by another inside a string

    GetSubstring (String, pointA, pointB)
    - get a substring between two points

    find (String, StringToFind)
    - return the location of the StringToFind inside the String

    all this functions exists in ColdFusion per exemple, so must exist something at least similar in C++ right? that's all I'm asking... I already have and wrote the solution, I only need to convert to C++ which I don't have experience and don't know much functions.

    thanks again!

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Registered User
    Join Date
    Jun 2007
    Location
    Rio de Janeiro, Brasil
    Posts
    48
    thanks m8! it's a start.

  15. #15
    Registered User
    Join Date
    Jun 2007
    Location
    Rio de Janeiro, Brasil
    Posts
    48
    well, didn't work at all... even the string declaration... so seams is just C? not C++?

    I did like the link you give me

    string s;

    then compile:

    qcommon\cmodel.c(495) : error C2065: 'string' : undeclared identifier
    qcommon\cmodel.c(495) : error C2146: syntax error : missing ';' before identifier 's'

    ???

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. String issues
    By The_professor in forum C++ Programming
    Replies: 7
    Last Post: 06-12-2007, 09:11 AM
  2. Replies: 4
    Last Post: 03-03-2006, 02:11 AM
  3. Another overloading "<<" problem
    By alphaoide in forum C++ Programming
    Replies: 18
    Last Post: 09-30-2003, 10:32 AM
  4. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM