how to find numbers in array and reverse their order?

Hello ,

I have a this byte array for example

26 32 36 20 E0 EC 20 F9 F0 E9 E9 E3 F8 5C 70 5C 70 5C 73 20 E3 E2 EC 20 F8 E0 E5 E1 EF 29 39 31 5C

and as you can see I have the numbers 0x32,0x36 =26 and 0x39,0x31=91
I want to be able reverse the order and them put them in the old array or even create a new FIX array.
so it will be

26 36 32 20 E0 EC 20 F9 F0 E9 E9 E3 F8 5C 70 5C 70 5C 73 20 E3 E2 EC 20 F8 E0 E5 E1 EF 29 31 39 5C

36,32 -> 62 and 31,39-19

there is no rule when the numbers will be or after what
in C# the solution was with with Regex , list , match function .

how can I do this?
I thought that I can find the place of the number in the array them see if the next byte is a number too but them what?

Thanks ,

as you can see I have the numbers 0x32,0x36 =26 and 0x39,0x31=91

Sorry, but I don't see where the =26 and =91 come into it.

Is it only those two pairs of values that you want to reverse ?

  1. you are right - it doesn’t . it just a Hex value to be more easy to understand an explain the question.

  2. no , this is just an example . I don’t know what the number in the array will be .
    but I do know that I am looking for 0x30–>0x39
    and before the number I will have 0x20
    also it could be more then 2 digits in a raw
    for example I could have in the array :
    …0x38 0x33 0x39…

is more clear now ?

Thanks ,

Koren12345:
is more clear now ?

Not at all. You have used at least 3 different notation styles and have not yet explained what any of them mean:

0x32,0x36 =26
36,32 -> 62
31,39-19

when you look at the Hex-Ascii code tale you get this :
HEX Ascii
32 2
36 6
39 9

so when I have 0x36,0x39 --> that mean I have the number 39
if it easy for you ignore the ASCII value - this is just so it will be clear to see in the monitor - ignore it.

let me rewrite the question:

in this sequence of bytes, there are groups of bytes starting with 0x20, followed by a series of digits in ASCII (0x30 to 0x39). In each of these groups, I want to reverse the order of the digits

is it more clear now?

Koren12345:
let me rewrite the question:

in this sequence of bytes, there are groups of bytes starting with 0x20, followed by a series of digits in ASCII (0x30 to 0x39). In each of these groups, I want to reverse the order of the digits

is it more clear now?

Getting there.

I assume that instead of "a series of digits in ASCII" you really mean "a serial of bytes whose value happens to be the ASCII value for the characters '0' through '9'"? Note that this information is totally irrelevant to the task at hand.

Next questions: what terminates this "series of bytes"? A certain number of bytes? The next occurrence of a 0x20 byte? What happens if you hit the end of the array before said termination?

I hope by now you see the importance of writing a clear, concise problem statement. If any of the engineers who work for me consistently wrote like that, they might not be working for me much longer.

  1. yes
  2. I know the final number of the array I'm running the code on if this what you mean .
    the final byte of the array is 0x03.
    and the stat of the array is 0x02

when I wrote the question it's seem very logic and clear what I want to do :slight_smile:
I will try to explain next time more

so when I have 0x36,0x39 --> that mean I have the number 39

That looks like 69 to me, but as has been pointed out the actual meaning of the bytes is irrelevant

As a matter of interest, how is the array being populated in the first place ?

this is what I have so far :
finding the numbers and finding where are they located in the array

 Serial.println("Place  ,  value in HEX");
  for (int i = 0; i < sizeof(FinalMsg); i++)
  {
    int nu = (FinalMsg[i]);
    if (( 48 <= nu) && (nu <= 57))///48 its the DEC value of  0x30 , and 57 it's the DEC value of 0x39
    {
      numbersPlace[numbersPlaceInt] = i;
      numbersPlaceInt++;
      
      Serial.print(i);
      Serial.print("       ");
      Serial.print(nu, HEX );
      Serial.println("");


    }

    else
    {
//do nothing 
    }
  }

and this is the result I’m getting:

Place , value in HEX
78 32
79 36
107 39
108 31

is this good place to start? ow can I continue from here ?

Thanks ,

Is this another "how do you do something you don't really need to do" questions?

why ?
I'm trying to think how to do it while your are trying yo help me

I need to do this , if not I wouldn't ask :slight_smile:

Koren12345:
why ?
I'm trying to think how to do it while your are trying yo help me

I need to do this , if not I wouldn't ask :slight_smile:

Like you "needed" to do this?

I need to do this - still waiting for an answer there......
meanwhile I move to another problem in my project

char data[] = "they're 2fast 96 345 6789 a11 24x 2424";

void setup() {
  Serial.begin(250000);
  Serial.println(data);
  findAndRotateBlankNumbers(data);
  Serial.println(data);
}

enum States {
  needBlank,
  needNumber,
  collectNumbers,
};

void findAndRotateBlankNumbers(char* ptr) {
  char* first;
  char* last;
  for (uint8_t state = needBlank; *ptr; ptr++) {
    switch (state) {
      case needBlank:
        if (*ptr == ' ') {
          state = needNumber;
        }
        break;
      case needNumber:
        if (isDigit(*ptr)) {
          state = collectNumbers;
          first = ptr;
        } else if (*ptr != ' ') {
          state = needBlank;
        }
        break;
      case collectNumbers:
        {
          bool swap = false;
          if (!isDigit(*ptr)) {
            last = ptr - 1;
            state = (*ptr == ' ' ? needNumber : needBlank);
            swap = true;
          } else if (!ptr[1]) {
            last = ptr;
            swap = true;
          }
          if (swap) {
            if (last != first) {
              for (int8_t nums = (last - first + 1) / 2; nums--; ) {
                char swap = *first;
                *first++ = *last;
                *last-- = swap;
              }
            }
          }
          break;
        }
    }
  }
}

void loop() {}
they're 2fast 96 345 6789 a11 24x 2424
they're 2fast 69 543 9876 a11 42x 4242


Created with Finite State Machine Designer.

genius!!!
it's just what i wanted

and it's working just great!

just a small questions (to see I understand it ):

where do I see the values you are looking for ?
meaning , where is the 0-9 "search"?
let say some day I would like to reverse another sets of values
for example :
all the values that are (in HEX - 0x40--0x5A , which is A-Z )
how do I do it ?
so if it has ABCD -->it will change it to DCBA?

again ,

Thanks you very much!

Koren12345:
a simple change *char to *byte will do it ?

Yes, it should not matter, maybe you get a bunch of warnings for the comparisons against char constants.

You could cast your array to a char* in the function call, like you have to use casts on the println statements.

byte data[] = "they're 2fast 96 345 6789 a11 24x 2424";

void setup() {
  Serial.begin(250000);
  Serial.println((char*)data);
  findAndRotateBlankNumbers((char*)data);
  Serial.println((char*)data);
}

OK , no problem there :slight_smile:

I guess the trick in this function was "isDigit" .... - didn't know about this :slight_smile:
so thanks you again ,

another question :

after running the code for some time I see I need to add another "rule" that if I have the colon char :

' : '

because sometime I need to reverse the order of the time :

I will explain :

what I have now is this :
Original message " time is 54:31"
after using your function I get
"time is 45:13"

so you can see why this is not good :slight_smile: ,

where do I need to add the other "if" in which case ,
so when the function see ":" , it will treat it like number ?

I have try this:

case needNumber:
        if ((isDigit(*ptr)|(*ptr == ":") {
          state = collectNumbers;
          first = ptr;
        } else if (*ptr != ' ') {
          state = needBlank;
        }

am I understand the function logic correctly?

Thanks ,

Koren12345:

case needNumber:

if ((isDigit(*ptr)|(*ptr == ":") {

You are messing with the wrong state, logical or is represented by || not |.

You could change the state needBlank to needBlankOrColon,
you could make the leading character a parameter and call the function for ' ' and ':'.

it's a misspell - I have fix this in the code and forgot to change it here .... of course its "||"

but when you say
You could change the state needBlank to needBlankOrColon,

this is what I have added ;
(* All other code is the same as you told me )

case needBlank:
			if (*ptr == ' ' || *ptr ==':') {
				state = needNumber;
			}
			break;

this is what you mean ?
it's not working
when I enter

char data[] = { "with colon 45:31  " };

I get the same result :

with colon 45:31


with colon 54:31

I want it to show

 with colon 13:54

what am I missing ?

Thanks ,

[/code]

You will have to change the transition in collectNumbers also.

            state = (*ptr == ' ' ? needNumber : needBlank);

to

            state = (*ptr == ' ' || *ptr == ':' ? needNumber : needBlank);