11 Jan, 2013, Hades_Kane wrote in the 1st comment:
Votes: 0
I'm kinda beating my head against the wall on this…

I'm trying to figure out how to take a number… hypothetically: "2370392"

and be able to compare the 3rd digit in that number to something else. 3rd digit is the example I'm using, but any position within a string I'd like to be able to isolate and compare (and manipulate with a different function).

More specifically, in our mprogs, we have a system of "variables" that stores a variable name and value onto a player. I'm wanting to be able to basically use this like array.

Under normal circumstances, it would work basically by defining and later being able to check, for example, "testvariable" to a specific number.

I'd like to be able to set testvariable to "2370392" (no problem with that, of course) but then have a check to be able to detect what the third digit or space or whatever in the number is, and do my if checks to see what it equals.

Likewise, being able to modify a specific digit would be necessary too.

Basically, what I want to be able to do is:

if varpos $n testvariable == 3 7

and in the number "2370392" it would check the third digit, see that it equals 7, and pass as a result.

The main thing that I'm running into is that the value for the variables is a long int, and any examples I've been able to find in the code of pulling a specific location in a string is, well, a string and not an int.

My initial thought was to be attempting something along the lines of taking the string that is processed

"testvariable" "operator" "arg1" "arg2"

and do something like:

pos = arg1
val = arg2

if(variable[arg1] == arg2)
blah

At least, that's more or less how I jotted down my thinking this through process, I know that's hardly representative of actual or working code, but still might be useful for illustrative purposes.

Things I've been able to detect is that in order to nab a specific part of a string, it has to be an array or a pointer, and that there hasn't been much of a way that I've been able to figure out how to convert that long int value into an array or pointer that I can nab a specific position out of to compare.

I feel like I'm ranting, it's late and I'm tired, and have been staring at this code for several hours and haven't been able to figure it out. Google hasn't been much help either.
11 Jan, 2013, Runter wrote in the 2nd comment:
Votes: 0
I can't say about your specific usecase because I don't know anyhting about mprogs, but let's say you have a string in C.

char *s = "012345";


and you want to compare the third digit (2) to see if it is a certain value.


I believe it's like this:

s[3] == ' ' // to compare it to a space
printf("%c", s[3]); // prints 3
11 Jan, 2013, Hades_Kane wrote in the 3rd comment:
Votes: 0
I've made a little progress (read: it's compiling and not crashing)…

Excuse how sloppy this is, I'm worried more about trying to get it to work at this juncture rather than it looking clean.

if (lval_char != NULL)
{
char pos[MAX_INPUT_LENGTH];
char val[MAX_INPUT_LENGTH];
long posval = -1, valval = -1;
char lval1 [MAX_INPUT_LENGTH];
long lval2 = 0;
char buf2[MAX_INPUT_LENGTH];

//Try to grab an lvalue variable.
lval_var = get_variable (lval_char, buf);

line = one_argument (line, buf);
line = one_argument (line, pos);
line = one_argument (line, val);

sprintf (buf2, "DEBUG0: lval1: %s lval2: %ld line: %s pos: %s val: %s posval: %ld valval: %ld buf: %s",lval1, lval2, line, pos,val,posval,valval,buf);
bug (buf2, 0);

if (lval_var == NULL)
return FALSE;
else
sprintf(lval1, "%ld", lval_var->value);

sprintf (buf2, "DEBUG1: lval1: %s lval2: %ld line: %s pos: %s val: %s posval: %ld valval: %ld buf: %s",lval1, lval2, line, pos,val,posval,valval,buf);
bug (buf2, 0);

sprintf (buf2, "DEBUG2: lval1: %s lval2: %ld line: %s pos: %s val: %s posval: %ld valval: %ld buf: %s",lval1, lval2, line, pos,val,posval,valval,buf);
bug (buf2, 0);
//Now process the operator.
if ((oper = keyword_lookup (fn_evals, buf)) < 0)
{
sprintf (buf,
"Cmd_eval: prog %d syntax error(4.5): '%s'",
vnum, original);
bug (buf, 0);
return FALSE;
}


sprintf (buf2, "DEBUG3: lval1: %s lval2: %ld line: %s pos: %s val: %s posval: %ld valval: %ld buf: %s",lval1, lval2, line, pos,val,posval,valval,buf);
bug (buf2, 0);

if (!is_number (pos))
{
sprintf (buf,
"Cmd_eval: prog %d syntax error(4.5): '%s'",
vnum, original);
bug (buf, 0);
return FALSE;
}
else
posval = atoi (pos);

sprintf (buf2, "DEBUG4: lval1: %s lval2: %ld line: %s pos: %s val: %s posval: %ld valval: %ld buf: %s",lval1, lval2, line, pos,val,posval,valval,buf);
bug (buf2, 0);



sprintf (buf2, "DEBUG5: lval1: %s lval2: %ld line: %s pos: %s val: %s posval: %ld valval: %ld buf: %s",lval1, lval2, line, pos,val,posval,valval,buf);
bug (buf2, 0);

if (!is_number (val))
{
sprintf (buf,
"Cmd_eval: prog %d syntax error(4.5): '%s'",
vnum, original);
bug (buf, 0);
return FALSE;
}
else
valval = atoi (val);

sprintf (buf2, "DEBUG6: lval1: %s lval2: %ld line: %s pos: %s val: %s posval: %ld valval: %ld buf: %s",lval1, lval2, line, pos,val,posval,valval,buf);
bug (buf2, 0);

if(lval1[posval] == 0 || !is_number(lval1))
{
sprintf (buf,
"Cmd_eval: prog %d syntax error(4.5): '%s'",
vnum, original);
bug (buf, 0);
return FALSE;
}

sprintf (buf2, "DEBUG7: lval1: %s lval2: %ld line: %s pos: %s val: %s posval: %ld valval: %ld buf: %s",lval1, lval2, line, pos,val,posval,valval,buf);
bug (buf2, 0);

lval2 = lval1[posval];

sprintf (buf2, "DEBUG8: lval1: %s lval2: %ld line: %s pos: %s val: %s posval: %ld valval: %ld buf: %s",lval1, lval2, line, pos,val,posval,valval,buf);
bug (buf2, 0);

return (num_eval (lval2, oper, valval));
}


The problem now is… debug8 is having "lval2" return the incorrect string.

I have the variable (lval1" set to myself as "237495" and right now currently, I am trying to compare the 5 character in that string to see if it equals 7. Obviously it doesn't, and what that code is intended to do is have lval2 return the 5th character of "9" but it isn't.

This is the debug output:

[*****] BUG: DEBUG1: lval1:   lval2: 0  line:   pos: 5  val: 7  posval: -1  valval: -1  buf: ==
[*****] BUG: DEBUG1: lval1: 237495 lval2: 0 line: pos: 5 val: 7 posval: -1 valval: -1 buf: ==
[*****] BUG: DEBUG2: lval1: 237495 lval2: 0 line: pos: 5 val: 7 posval: -1 valval: -1 buf: ==
[*****] BUG: DEBUG3: lval1: 237495 lval2: 0 line: pos: 5 val: 7 posval: -1 valval: -1 buf: ==
[*****] BUG: DEBUG4: lval1: 237495 lval2: 0 line: pos: 5 val: 7 posval: 5 valval: -1 buf: ==
[*****] BUG: DEBUG5: lval1: 237495 lval2: 0 line: pos: 5 val: 7 posval: 5 valval: -1 buf: ==
[*****] BUG: DEBUG6: lval1: 237495 lval2: 0 line: pos: 5 val: 7 posval: 5 valval: 7 buf: ==
[*****] BUG: DEBUG7: lval1: 237495 lval2: 0 line: pos: 5 val: 7 posval: 5 valval: 7 buf: ==
[*****] BUG: DEBUG8: lval1: 237495 lval2: 53 line: pos: 5 val: 7 posval: 5 valval: 7 buf: ==
11 Jan, 2013, Hades_Kane wrote in the 4th comment:
Votes: 0
I don't know WHERE it is getting 53 from…
11 Jan, 2013, mangan wrote in the 5th comment:
Votes: 0
There isn't a quick-and-easy solution that I am aware of in terms of just a couple lines (in C/C++), without some overhead.
Grabbing out an indexed digit from a binary number (even though it displays in decimal as 2370392 for us) could be done if you converted the number into base ten and then just grabbed whichever index you want. Question is then, how do you store the decimal number? Likely answer is an array (list, vector, whatever), at which point you may consider storing the number in an array/vector/etc. from the beginning.

Easier method, although it uses more memory (not sure how frequent you'll use this, or if the number is only for mprogs), would be to store the number as a string. You could then use what Runter suggested to treat it as an indexed decimal digit. Further, you could translate the entire thing from binary to ASCII chars via atoi() calls and the like. For individual digits that have to be translated back and forth, simply add or subtract it from the character '0'.

Hth.
11 Jan, 2013, Hades_Kane wrote in the 6th comment:
Votes: 0
The variable value itself, specifically the numerical sequence that I'm trying to translate into a string so I can nab a particular number (or position within that string) is in use in a lot of programs currently and nearly every pfile has numbers saved as variables, so altering how that works is pretty much out of the question.

As a result of that, I need to try to figure out what I can do within the confines of this particular function… to take what already exists, and convert it into what I need.

It appears as though what I have above is printing it as a string like I need, and it seems that the code is correctly identifying what position in the string I'm asking it to identify along with what number I'm trying to compare it to, at this juncture it just doesn't appear to be plucking the number out correctly. I'm unsure if there is something wrong with what I have, or if because of the differences in strings and ints, if it is mangling what it is plucking into something else.
11 Jan, 2013, plamzi wrote in the 7th comment:
Votes: 0
Hades_Kane said:
The variable value itself, specifically the numerical sequence that I'm trying to translate into a string so I can nab a particular number (or position within that string)…


It's late and maybe I'm missing something (or everything) but what about itoa()?
11 Jan, 2013, Hades_Kane wrote in the 8th comment:
Votes: 0
plamzi said:
Hades_Kane said:
The variable value itself, specifically the numerical sequence that I'm trying to translate into a string so I can nab a particular number (or position within that string)…


It's late and maybe I'm missing something (or everything) but what about itoa()?


I looked into that, but it's not including in my distro.

Or something.

I have the proper thing included, but it isn't recognizing it.
11 Jan, 2013, Rarva.Riendf wrote in the 9th comment:
Votes: 0
For a string use Runter solution for whatever other value do like this:
1234567890 let say you want to access the 4, just divide by 10^6 (cause you want the number in the 6th position from the RIGHT) it will give you 1234 then 1234 mod 10 = 4


PS:I am pretty sure that some bit manipulation can give you that result right away but I am too lazy to look into it.

a itoa I found in my code (I did not write it, no guarantee whatsoever of validity)

void reverse(char s[]) {
int i, j;
char c;

for (i = 0, j = strlen(s) - 1;i < j;i ++, j –) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}

void itoa(int n, char s[]) {
int i, sign;

if ((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do { /* generate digits in reverse order */
s[i ++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i ++] = '-';
s[i] = '\0';
reverse(s);
}
11 Jan, 2013, plamzi wrote in the 10th comment:
Votes: 0
Well, the wiki link also has all the code you need for itoa :) Same as what Rarva just posted.

If your number is always the same length and if you only need to run one check at one position, you can just do it manually:

2370392

if ( !((n /1000) % 3) ) {
//char at 3rd to last position is 3
}
11 Jan, 2013, Hades_Kane wrote in the 11th comment:
Votes: 0
Thanks for the itoa.

It appears that these two things are accomplishing the same thing, though:

itoa(lval_var->value,lval1);
sprintf(lval1, "%ld", lval_var->value);


Still trying to make sense of the other stuff posted :p
11 Jan, 2013, Hades_Kane wrote in the 12th comment:
Votes: 0
plamzi said:
Well, the wiki link also has all the code you need for itoa :) Same as what Rarva just posted.

If your number is always the same length and if you only need to run one check at one position, you can just do it manually:

2370392

if ( !((n /1000) % 3) ) {
//char at 3rd to last position is 3
}


I was hoping not to have to force the same length every use here, but it's beginning to feel like beggars can't be choosers :p

I do my best to make our progs as versatile as possible, and I was hoping to be able to use this system as a means to create new arrays on the characters using the existing variable system without having to add new values to the pfiles everytime I wanted to do this.

It seemed so simple in my head, just assign a multi digit number and pluck out a specified digit (going from the left), but it's proving to be anything but :\
11 Jan, 2013, plamzi wrote in the 13th comment:
Votes: 0
Honestly, I'm too tipsy to process the code you posted but what's wrong with adding itoa and doing:

if (itoa(2370392)[2] == '4') {
//is the 3rd character 4? no, it isn't
}
else
if (itoa(2370392)[6] == '9') {
//is the 7th character 9? yes, it is
}


If you're worried about the length of the numbers being too variable, just do a sanity check for length.

Maybe there's something else logistically (as in legacy support) that is making this seem like a big challenge?
11 Jan, 2013, Rarva.Riendf wrote in the 14th comment:
Votes: 0
Quote
I was hoping not to have to force the same length every use here, but it's beginning to feel like beggars can't be choosers :p


Err my numeric code works for this but only if position is get from the right :)

short int getvalue(long number, short int position) {  //no check if number is actually big enough to have that many position
long temp = number / (math.pow(10, position);
return temp mod 10;
}
11 Jan, 2013, Hades_Kane wrote in the 15th comment:
Votes: 0
plamzi said:
Honestly, I'm too tipsy to process the code you posted but what's wrong with adding itoa and doing:

if (itoa(2370392)[2] == '4') {
//is the 3rd character 4? no, it isn't
}
else
if (itoa(2370392)[6] == '9') {
//is the 7th character 9? yes, it is
}


If you're worried about the length of the numbers being too variable, just do a sanity check for length.

Maybe there's something else logistically (as in legacy support) that is making this seem like a big challenge?


It's possibly just me being a newb at this particular kinda thing making this seem like a big challenge.

It boils down to this, trying to make it work with the program system and such…


The number I'm trying to pull from (2370392 for example) can be any number… the value I'm checking for can be any value, and the position I'm looking for it in can be any position… likewise, the method of comparing can be any of the value ones (>,<,==,>=,<=).

Basically the check would look like this:

if var $* X Y A B

X = variablename (no problem pulling this)
Y = the operator values
A = position
B = value

So in the case of: if var $n testvar == 5 2

I'm asking if the variable of testvar on the person who triggered the program has a 5th value and if so, does it equal 2.

I don't know if I'm clearing anything up or not…
11 Jan, 2013, Rarva.Riendf wrote in the 16th comment:
Votes: 0
To know if number is big enough divide it by 10^position 1234 / 10000 = 0 hence beep wrong so no 5th position
once you know your number is big enough use either my method or itoa and extract the number you want from yours.

We gave you the solution to get everything you need, maybe you are just too tired :) Sleep on it and it will be pretty obvious when you wake up
11 Jan, 2013, Runter wrote in the 17th comment:
Votes: 0
I would do it this way:

i = 12345

class Integer
def get_digit(d)
(self / 10 ** (d-1)) % 10;
end
end

(1..5).each do |n|
puts i.get_digit(n)
end



http://codepad.org/O8eJ058q


And in C

int digit(int n, int d) {
return (n / (int)Math.Pow(10, d - 1)) % 10;
}

// digit(12345, 3); // Get 3rd digit
11 Jan, 2013, Rarva.Riendf wrote in the 18th comment:
Votes: 0
Looks like the solution I gave him (minus a -1) but I admit that at 7 am and still not sleeping I begin to have a hard time thinking straight. So is not it only for a position starting from the right and not the left like he wanted ? (would need to know wich size the number is so you can do size - position thing with this code
11 Jan, 2013, Runter wrote in the 19th comment:
Votes: 0
Rarva.Riendf said:
Looks like the solution I gave him (minus a -1) but I admit that at 7 am and still not sleeping I begin to have a hard time thinking straight. So is not it only for a position starting from the right and not the left like he wanted ? (would need to know wich size the number is so you can do size - position thing with this code


Yeah, I didn't see yours before I posted. Basically the same thing.
11 Jan, 2013, Hades_Kane wrote in the 20th comment:
Votes: 0
Finally got it working, thanks guys!

Basically what I did was grab the number that I'm trying to pull from and did a strlen on it and made it int length. posval below is the position in the number I'm trying to grab.

Then, with the code you guys provided, I did:

int var1 = 0;

var1 = lval_var->value / pow(10,length - posval);
lval2 = var1 % 10;


lval2 returns the proper number.

Thanks a bunch. Got one more thing I'll be needing to try to do in a similar vein to have this working the way I need… but I'm too tired and worn out now to even attempt touching it even a little bit tonight :p
0.0/35