2

I am working on an SMS application for Android where I am sending a number of Strings of predefined size in a single SMS. At the sending side, I am concatenating a number of Strings of predefined sizes. Once I have received the SMS, I want to split the long String into smaller Strings based on their sizes.

Here is a simple code to explain what I have attempted:

// On the SMS sending side
String str1 = new String(new char[8]);
String str2 = new String(new char[4]);
String str3 = new String(new char[2]);
String str4 = new String(new char[2]);

String sendSMS = str1 + str2 + str3 + str4;

// send SMS

After receiving the data I want to seperate the combined String into data for str1, str2, str3, str4, given that I know the size of each small Strings.

So far I have found a number of answers on SO, all of which use split() function, however I do not have a seperating character token between the concatenated Strings. Instead, I want to use the knowledge of the size of each substring to get them. Something similar to sscanf is what I am looking for.

masad
  • 1,547
  • 1
  • 18
  • 40
  • So, you mean you need `String.substring()` ? – Mike Nakis Aug 11 '17 at 19:18
  • I have looked at `String.substring()`, however I have lots of Strings and it becomes quite cluttered to use substring for extracting each String. Is there a way I can use the sizes of each String into a single function call, that can split String into a String array of smaller Strings? As I said in my question, this would be something quite similar to `sscanf` in C++ (if it exists) – masad Aug 11 '17 at 19:22

5 Answers5

4

Here is some sample code to do what you want... However, it does no error checking which I will leave up to you.

String[] splitter(String input, int[] lengths)
{
    String[] output = new String[lengths.length];
    int pos = 0;
    for(int i=0;i<lengths.length;i++)
    {
        output[i] = input.substring(pos, pos+lengths[i]);
        pos = pos + lengths[i];
    }
    return output;
}
Jamie
  • 1,888
  • 1
  • 18
  • 21
  • Many thanks! I am now using `substring` function in a similar way as in your question. However, I also like the 'Stringbuilder' solution below. – masad Aug 12 '17 at 20:50
4

You can use a solution like this:

int index = 0;
String str1= sms.substring(index, str1Length);
index += str1Length;
String str2 = and.substring(index, str2Length);
Index += str2Length:

....

You can create a Helper class to do this:

Class SmsExtractor{
     Int lastVisitedIndex = 0;
     String msg;

     Public SmsExtractor (String msg){
         This.msg=msg;
     }

    Public String extract(int length){
         String m = msg.substring(lastVisitedIndex, length);
         lastVisitedIndex += length;
         Return m;
    }
 }

And use it :

SmsExtractor e = new SmsExtractor ( receivedMsg);
String str1 = e.extract(str1Length);
String str2 = e.extract(str2Length);

...

Another until method from SmsExtractor :

Public String[] extractAll (int[] lengths){
    String [] msgs = new String[lengths.length];
    For( int I =0; I< lengths.length; I++){
        msgs[I]= extract(lengths[I]);
    }
    Return msgs;
}
Vasile Bors
  • 656
  • 6
  • 14
3

If you know in advance the size of the small String, you can calculate the index of each one from the large String. you can use the substring(startIndex, endIndex) function to do that.

Here is an example

You can use this function inside your own utility function like this

List<String> extractSmallString(String longString, List<Integer> smallStringSize) {
    ArraysList<String> extraction = new ArrayList<>();
    int i = 0;
    for (int size : smallStringSize) {
        extraction.add(longString.substring(i, i + size);
        i += size;
    }
    return extraction
}
jeanr
  • 1,031
  • 8
  • 15
  • I have looked at `String.substring()`, however I have lots of Strings and it becomes quite cluttered to use substring for extracting each String. Is there a way I can use the sizes of each String into a single function call, that can split String into a String array of smaller Strings? As I said in my question, this would be something quite similar to `sscanf` in C++ (if it exists) – masad Aug 11 '17 at 19:27
  • 1
    Why don't you create your own function taking a list of the small string size using internally the `substring` function and returning a `List` ? – jeanr Aug 11 '17 at 19:37
3

My recommendation would be to use a StringBuilder. Assuming you were given sendSMS from your question and you wanted to get str1 through str4, you might do this:

StringBuilder sb = new StringBuilder(sendSMS);
str1 = getStringFromSb(sb, 8);
str2 = getStringFromSb(sb, 4);
str3 = getStringFromSb(sb, 2);
str4 = getStringFromSb(sb, 2);    

And the getStringFromSb method:

String getStringFromSb(StringBuilder sb, int stringLength)
{
  String returnStr = sb.substring(0, stringLength);
  sb.delete(0, stringLength);
  return returnStr;
}
windedmoose
  • 207
  • 3
  • 11
  • Many thanks! This works as well as a number of other answers. I like your solution, although it is quite similar to just using an incremental index in one of the other answers. – masad Aug 12 '17 at 20:52
2

Have a look at this library: It's an implementation for sscanf in java:

https://github.com/driedler/java-sscanf/tree/master/src/util/sscanf

You can refer to this question too.

alexpfx
  • 6,412
  • 12
  • 52
  • 88