Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: Array working different in Android vs Windows


This question is answered.


Permlink Replies: 2 - Last Post: Feb 6, 2018 3:45 PM Last Post By: Andrew McIsaac Threads: [ Previous | Next ]
Andrew McIsaac

Posts: 93
Registered: 3/12/13
Array working different in Android vs Windows  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 2, 2018 8:15 PM
Good evening c++ Deities,

I am using XE8 C++ Enterprise, on Windows 10.
Created a mobile application : multidevice - TabbedForm.

I have :

TStringList * valuesa = new TStringList(); // valuesa are values in a possible string format, and will be 'conditioned' for data entry errors...

String temp;
char tempi; // to take the place of the i th value...

This works well on Android Device - can deploy ...
for (int i= 0; i< temp.Length(); i++)
{
tempi=temp[i];
if(tempi=='A') // want to add whenever there is an A in the position of the String
total += StrToInt(valuesa->Strings[i]);
}

but I will get error when switching this to windows 64 bit
to do the same thing - the string array doesn't start at 0, but at 1 ?

for (int i= 1; i< temp.Length()+1; i++)
{
tempi=temp[i];
if(tempi=='A')
total += StrToInt(valuesa->Strings[i-1]);
}

Each will produce required dependent on operating system.

I don't know why these would be different - or am I missing something else completely ?

Thanks in advance.
Andrew
Remy Lebeau (Te...


Posts: 9,442
Registered: 12/23/01
Re: Array working different in Android vs Windows
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 5, 2018 11:08 AM   in response to: Andrew McIsaac in response to: Andrew McIsaac
Andrew McIsaac wrote:
TStringList * valuesa = new TStringList(); // valuesa are values in a possible string format, and will be 'conditioned' for data entry errors...

You are using StrToInt() with the strings that are stored in valuesa. So, why aren't you using a more appropriate container that holds integers instead of strings? TList<int> or std::vector<int> or similar.

String temp;
char tempi; // to take the place of the i th value...

System::String is an alias for System::AnsiString in CB2007 and earlier, and is an alias for System::UnicodeString in CB2009+. The RTL defines a System::Char alias for whatever character type System::String contains, as well as a _D() macro to map compile-time char/string literals to the same character type. In your case, System::UnicodeString contains System::WideChar elements, and System::WideChar is 16-bit on every platform ('wchar_t' on Windows, 'char16_t' on other platforms). As such, your 'tempi' variable needs to be declared as System::WideChar instead of 'char', or better as System::Char to match your use of System::String:

String temp;
Char tempi;  // to take the place of the i th value...


This works well on Android Device - can deploy ...

No, it doesn't work, because:

- you are assigning a 'char16_t' to a 'char'. At best, that will truncate character values > 0xFFFF without warning. At worse, it will fail to compile due to different character types being used.

- you are not taking into account that System::UnicodeString is 0-indexed or 1-indexed depending on platform. C++Builder compilers that use a 1-indexed System::UnicodeString define a precompiler conditional named _DELPHI_STRING_ONE_BASED, which you need to handle if you want to write cross-platform code.

Try something more like this instead:

String temp;
Char tempi;  // to take the place of the i th value...
 
for (int i = 0; i < temp.Length(); ++i)
{
    #ifdef _DELPHI_STRING_ONE_BASED
    tempi = temp[i+1];
    #else
    tempi = temp[i];
    #endif
    if (tempi == _D('A'))
        total += StrToInt(valuesa->Strings[i]);
}


Alternatively:

inline int Low(const System::String &)
{
    #ifdef _DELPHI_STRING_ONE_BASED
    return 1;
    #else
    return 0;
    #endif
}
 
inline int High(const System::String &S)
{
    #ifdef _DELPHI_STRING_ONE_BASED
    return S.Length();
    #else
    return S.Length()-1;
    #endif
}
 
String temp;
Char tempi;  // to take the place of the i th value...
 
int low = Low(temp);
int high = High(temp);
for (int i = low; i <= high; ++i)
{
    tempi = temp[i];
    if (tempi == _D('A'))
        total += StrToInt(valuesa->Strings[i-low]);
}


but I will get error when switching this to windows 64 bit

There is nothing in the code you have shown that behaves differently in 64-bit vs 32-bit. Whatever problem you are having is related to something else, most likely your misunderstanding of how System::String indexing works across different platforms.

--
Remy Lebeau (TeamB)
Andrew McIsaac

Posts: 93
Registered: 3/12/13
Re: Array working different in Android vs Windows  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 6, 2018 3:45 PM   in response to: Andrew McIsaac in response to: Andrew McIsaac
Wow, Thank you,

I have much to learn.

Switching to Windows 64 bit - that was meant to be switching from Android to Windows ,...

StrToInt, initially, but the user's data evolved to include decimals, so I used StrToFloat(...

Thank you for all the clarifications.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02