Jump to content
Sign in to follow this  
ColonelSandersLite

Converting Strings

Recommended Posts

Anyone know of any method to convert strings to something else?

In particular I'm looking to convert a string to an array of single character strings. I'm needing something where the end result is something like the php explode command or the java .charAt() method of the string class or something similiar.

I could probably make do with any method of string operation that will let you remove stuff from a string (maybe).

-------------------------------

Although the path followed to get to the solution is interesting, if you wish to jump straight to the end result of this thread (a package of scripts to solve the problem, mostly), you can just go here.

Share this post


Link to post
Share on other sites

What about the other way around? Beginning with an array and creating any string you wish out of it? I don't see where you would get much unique string input from the player in your mission.

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

array1 = ["I am","a","string"]

array2 = ["something else"]

titletext format ["%1 %2 %3",(array1 select 0),(array1 select 1),(array1 select 2)]

titletext format ["%1 really %2 %3",(array1 select 0),(array1 select 1),(array1 select 2)]

titletext format ["%1 %2",(array1 select 0),(array2 select 0)]

I'm a bit rusty, and this is OFP knowledge, no guarantee for syntax errors.

EDIT:

You could even go with

arrayletters = ["a","b","c" and so on

arraycaps = ["A","B","C" and so on

arrayspecial = [" ","!",".","$" and so on

arraynumbers = ["1","2","3" and so on

Share this post


Link to post
Share on other sites

Actually, I'm working on my Particle Parameter Utility. Specifically, trying to get a nice import function going via a dialog interface.

So yes, I will be getting unique string input from the player.

Also, I do already do this from the other end in the above tool (that's exactly how it exports the code required to make the effect).

Share this post


Link to post
Share on other sites

While we're waiting for some better ideas... smile_o.gif

What about a onscreen-click-keyboard dialog which would store the input in an array while printing the letters on screen?

Share this post


Link to post
Share on other sites

With a (ugly) trick you can get the first X characters from a string like this:

Quote[/b] ]

_str = "hello world"; // Input string

_num = 5; // Number of letters

_foo = "";

_out = "";

for "_x" from 0 to (2038 - _num) do {_foo = _foo + " "};

call compile (format["%1_out = ""%2", _foo, _str] + """");

hint _out; // Displays "hello"

Propably wont help you much though, the best way currently seems to be to capture input character at a time and store it in an array.

Share this post


Link to post
Share on other sites

@ Trapper

I don't think so, that would take more of the users time than the current method of setting the parameters by hand. What I'm trying to do is come up with something that will parse code the user can just paste into a box into something my application can actually use.

@ Kegetys

While cool, I think you're right about it not helping. Not unless it's possible to get the string's length and and remove the last X letters of a string. Either that or be able to remove the first X letters from a string. I'm playing around with it, but I'm not sure that can be done at all. I'm pretty sure the way that snippet above works is by giving the format command a longer string than it can accept, therefore it automatically crops it at the desired length. I doubt it works the other way around.

Share this post


Link to post
Share on other sites
Quote[/b] ]With a (ugly) trick you can get the first X characters from a string like this:...

Pretty neat trick... wink_o.gif

What you could probably do is expand that script a little, so that you extract the individual string characters one by one, and then put them into an array.

Once you have'em there you can do pretty much anything you want with it.

Share this post


Link to post
Share on other sites

Thing is that you can't get them one by one. you can get the first letter on it's own sure. But you can't get the second without also getting the first.

Well, as I said before (a little incorrectly), not without removing the first X letters from a string.

And while I've been trying to manage that for a few hours now, I haven't figured a way. Not saying there isn't a method of doing that. I'd be happy to hear it. I just haven't found a way myself.

Share this post


Link to post
Share on other sites

this is all a bit out of my league, but could you try a "brute force" approach, assuming you can extract the first X letters from a string?

(this is not meant to be game script code)

_i1 = first letter

_2 = first two letters

_3 = first three letters

if (_i1 + "a") == _2, then _i2 = "a"

etc, etc

if (_i1 + _i2 + "a") == _3, then _i3 = "a"

etc, etc

Could get real slow, but it may work given most strings made up of letters and numbers (36 chars) only. Just tested, "ü" != "Ü" so case sensitivity is used for some characters FWIW.

Share this post


Link to post
Share on other sites
How in the world did you get a length?

I'm just taking bigger and bigger chunks off the left until it matches the original string...

But I can't really think of any practical application for it. Can you???

Well anyway - here's the function:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">KRON_StrLen = {private["_in","_chk","_buff","_len"]; _in=_this select 0; _chk=""; _len=0; if (_in!="") then {while {_in!=_chk} do {_len=_len+1; _buff=""; for "_i" from 0 to (2038 - _len) do {_buff = _buff + " "}; call compile (format["%1_chk = ""%2", _buff, _in] + """");};}; _len;};

_len=["abcde"] call KRON_StrLen;

Share this post


Link to post
Share on other sites

That gives me an idea fasad.

Especially with Kronzky's method of getting a string length.

You can use some nested looping to combine those two things...

Basically, use several loops to start generating every possible string combo until you have a match.

The code for that will get tedious, but I may know a trick or two to get her done...

BTW, I added a vote and a note to that issue. Either some dude took my user name, or I signed up for a user name a while back and forgot my password... So, I'm CSL there.

Share this post


Link to post
Share on other sites

Well, I have some good news and some bad news about the method I was talking about above.

Good news first:

It is fully possible to disect a string to figure out what it is using a brute force type loop that chews through every possible combination of characters.

The bad news:

It'll only take the game 5 mins to chew through a 5 char combination...

I think it's safe to say that that idea is a bust.

I've potentially got another method though also inspired by fasad above. It's another brute forcer, but more refined. In all honesty though, I doubt it will pay out. Still, we'll see right?

It will however have to wait until tomorrow. I'm about fried for the night.

Share this post


Link to post
Share on other sites

edit: "the quick brown fox jumps over the sleepy dog" -> each character as an element of an array in under half a second. Brute force yeehaa! Do you feel the power? smile_o.gif

I'm sure one of the script gurus will be able to make huge improvements on this. The forEach executes in one cycle, which is sure to create slowdown, it's a SQS, it uses a loop, gotos and even keeps on searching for character matches after it has found one! biggrin_o.gif

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

_str = "the quick brown fox jumps over the sleepy dog"

_charArray = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"," ",""]

_desArray = []

_desComp = ""

_i = 1

#loop

_num = _i

_foo = ""

_out = ""

for "_x" from 0 to (2038 - _num) do {_foo = _foo + " "}

call compile (format["%1_out = ""%2", _foo, _str] + """")

_letter = ""

{if ((_desComp + _x) == _out) then {_letter = _x}} forEach _charArray

if (_letter == "") then {goto "exit"}

_desComp = _desComp + _letter

_desArray = _desArray + [_letter]

_i = _i + 1

player sideChat format ["looping, i = %1",_i]

goto "loop"

#exit

player sideChat format ["desArray is %1",_desArray]

hint format["runtime = %1",_time]

exit

Share this post


Link to post
Share on other sites

Here the SQF Version:

fGetCharArray.sqf

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_string = _this;

_chars = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"," ",""];

_convertedStr = [];

_oldStr = "";

_letter = "";

_i = 1;

while{true}do

{

_tmpStr = [_string,_i] call fGetLeftStr;

{

scopeName "CharCheck";

if(_tmpStr == (_oldStr + _x))then

{

_convertedStr = _convertedStr + [_x];

_oldStr = _oldStr + _x;

_letter = _x;

breakOut "CharCheck";

};

}foreach _chars;

if(_letter == "")exitWith

{

_convertedStr

};

_i = _i + 1;

};

need fGetLeftStr.sqf

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">private["_str","_num","_foo","_out"];

_str = _this select 0;

_num = _this select 1;

_foo = "";

_out = "";

for "_x" from 0 to (2038 - _num) do

{

_foo = _foo + " "

};

call compile (format["%1_out = ""%2", _foo, _str] + """");

_out

Share this post


Link to post
Share on other sites

Guess you guys were a lot more optimistic than me, regarding the "brute force" method...

I never even tried it. I thought it would be way too slow.

Well, with this capability in hand, I've now created a class of string macros to handle all the basic functions:

Len: returns the length of the string

Left: returns x characters from the left

Mid: returns x characters, starting at point y

Right: returns x characters from the right

InStr: returns true if the tested string is contained in the main string

Upper: converts string to upper case

Lower: converts string to lower case

ToArray: returns the string as an array

I will later release a fully documented version (with full credit to all of you guys of course), so that it's accessible to any beginner.

They are, of course, still pretty slow. So it's nothing that should be used in fast loops. But still, better than nothing...

The first version is available here.

<span style='font-size:10pt;line-height:100%'>Thanks to all of you for this great example of community teamwork!!!</span>

Share this post


Link to post
Share on other sites

One purely initial thought, having just run it:

KRON_StrMid uses cardinal values

Personally, I feel ordinal is in order here.

Other opinions?

Share this post


Link to post
Share on other sites
Quote[/b] ]KRON_StrMid uses cardinal values

Personally, I feel ordinal is in order here.

Perhaps I should add a "SubString" function, that then works with ordinals.

I've based the syntax of the functions on Basic (since that will be a language probably *everyone* is familiar with). And there Mid works with cardinals.

Having two different "MId" functions would also eliminate the question whether to have the first position be 0 or 1. Normally, in Basic, it's 1, but right now I'm using 0, since in ArmA all arrays are 0-based.

So we would have Mid using 1 as a first position, and the second parameter gives the length, and SubString, which would start at 0, and the second parameter defines the end position.

Would that be ok?

Share this post


Link to post
Share on other sites

Honestly, I would go with either or. Adding another function that does basically the same thing isn't such a hot idea IMO. While *we* would understand exactly what the difference is, I think it may end up just confusing some end users.

If the final decision is cardinal, I can live with it. If the decision is ordinal, that's great too.

I would wait to see if anybody else would like to give us some input on that subject though.

This is just all IMO.

My argument specifically though is that as far as I know, every non-3rd party scripting command in arma is ordinal and this should be the same.

Aside:

You know, if I have one major gripe about basic, it's that it's cardinal....

What makes it worse is VB.net's funky combination of ordinal and cardinal.

Declaring an array of 10 elements results in an array with elements 0-10. Talk about giving devs nightmares...

so that means that:

for int i = 0 to i < 10 step 1

is just as valid a method of looping through a 10 element array as:

for int i = 1 to i == 10 step 1

but if you mix them (suppose differenent developers are collaborating or something), you'll end up with bad output.

--------------------------------

Actually:

My bad, it is ordinal.

I made a mistake the first time I looked at it. Sorry, I haven't been up very long... icon_rolleyes.gif

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

cardinal:

String: a s d f g h i j k l

Position: 1 2 3 4 5 6 7 8 9

ordinal:

String: a s d f g h i j k l m

Position: 0 1 2 3 4 5 6 7 8 9

Share this post


Link to post
Share on other sites

Yeah, it'd be great to also have some string functions as in SQL. The "like" command would be great in some instances, substring, etc. especially for contatenating unique strings. But I think we're kind of expecting BIS to create an entirely new programming language, which they practically already have, lol.

Share this post


Link to post
Share on other sites

Well, with an array output, we can build functions to process them however we want easilly.

In all honesty though, I'm not sure we need a BIS function anymore. The only real advantage a BIS function would have over what we just put together is speed. Since this entire concept would mostly be usefull for user dialogs and such, I'm not sure how imperitive speed really is here.

-------------------

I take that immediatly above back. There are still limitations to what we can do, at least so far. I don't think that's going to change though, as it's an inherint liability with the method we're using.

The whole concept of

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

call compile (format["%1_out = ""%2", _foo, _str] + """");

breaks when you pass it a string with quotes in it.

You can partially work around it by using some double-single quote replacement:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

call compile (format["%1_out = '%2", _buff, _in] + "'");

Doing that breaks when you pass it a string with single quotes in it however.

There are probably other undiscovered issues still too. Some of which may be solvable, some may not be.

The may be a way around that issue, but I'm not seeing it. Perhaps I will tomorrow, or perhaps someone else will...

Share this post


Link to post
Share on other sites
Quote[/b] ]In all honesty though, I'm not sure we need a BIS function anymore. The only real advantage a BIS function would have over what we just put together is speed. Since this entire concept would mostly be usefull for user dialogs and such, I'm not sure how imperitive speed really is here.

I have two cases where I need speed to be sure that there is no lag. To add these functions in game should be small job from BIS and benefits are huge. At least TableToString and StringToTable commands are wellcome. With them there is possibility to make different String management functions more easily.

Share this post


Link to post
Share on other sites

My version of string to array function, based on cex's str2arr.cpp

vf_strtoarray.sqf

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">vf_sta_chars=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"," ","0","1","2","3","4","5","6","7","8","9",".",",",":","-","_"];

vf_sta_probel1000="";

for "_i" from 1 to 1000 do

{

vf_sta_probel1000=vf_sta_probel1000+" ";

};

vf_sta_probel100="";

for "_i" from 1 to 100 do

{

vf_sta_probel100=vf_sta_probel100+" ";

};

vf_sta_probel1_9=[""," "," "," "," "," "," "," "," "," "];

{

private["_p","_str","_array","_char","_old"];

_array=[];

_old="";

_str="";

for "_i" from 2038 to 1 step -1 do

{

_p="";

for "_b" from 1 to (_i-_i mod 1000)/1000 do {_p=_p+vf_sta_probel1000};

for "_b" from 1 to (_i mod 1000 - _i mod 100)/100 do {_p=_p+vf_sta_probel100};

for "_b" from 1 to (_i mod 100 - _i mod 10)/10 do {_p=_p+" "};

_p=_p + (vf_sta_probel1_9 select (_i mod 10));

call compile(format["%1_str = ""%2",_p,_this] + """");

if (_old == _str) exitwith {_array};

_char={ if (_str==_old+_x) exitWith {_x}; ""} forEach vf_sta_chars;

if (_char!="") then {_array=_array+[_char]};

_old=_str;

};

_array

}

using:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_func=call (compile (preprocessfile "vf_strtoarray.sqf"));

_array="string" call _func;

about function

first: this function use global variables

vf_sta_chars

vf_sta_probel1000

vf_sta_probel100

in vf_sta_chars array all chars that function will be added to array if they are in the given string. If char doesn't exist in vf_sta_chars the searching isn't stop when find that in array...english banghead.gif ..

simple example:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

_text="//string" call _func;

result will be

_text=["s","t","r","i","n","g"];

then "/" isn't exist in vf_sta_chars but converting don't stop and return ["s","t","r","i","n","g"], all chars that exist in vf_sta_chars

and second

this function convert 2000 chars by ~ 0.064 seconds, i think it fast smile_o.gif

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×