[NXC] StrCat not working with string returned from Flatten

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
Post Reply
ricardocrl
Posts: 117
Joined: 27 Dec 2010, 19:27

[NXC] StrCat not working with string returned from Flatten

Post by ricardocrl »

Hey,

This is the code:

Code: Select all

task main(void){
     int length;
     string lengthString;
     string buffer = "Ola";

     length = 1000;
     lengthString = Flatten(length);
     buffer = StrCat(lengthString, buffer);
     
     NumOut(0, LCD_LINE8, StrIndex(buffer, 0));
     NumOut(25, LCD_LINE8, StrIndex(buffer, 1));
     NumOut(50, LCD_LINE8, StrIndex(buffer, 2));
     NumOut(75, LCD_LINE8, StrIndex(buffer, 3));
     
     while(true);
}
The output is: 232 3 0 0

So, the result includes the first string, returned from Flatten(), but not the second one concatenated.
Do you find anything wrong? Can it be a bug?

Cheers,
Ricardo
ricardocrl
Posts: 117
Joined: 27 Dec 2010, 19:27

Re: [NXC] StrCat not working with string returned from Flatten

Post by ricardocrl »

I found out that it works with FlattenVar(). That's strange anyway, because the flattening works fine with both functions, but not the concatenation.
spillerrec
Posts: 358
Joined: 01 Oct 2010, 06:37
Location: Denmark
Contact:

Re: [NXC] StrCat not working with string returned from Flatten

Post by spillerrec »

Flatten(), before calling the flatten opcode, copies the value into __D0main which type is long, while FlattenVar() uses the variable directly. So with FlattenVar(), you pass it a two byte value, while with Flatten() you pass it a 4 byte value, because there is a temporary variable involved which you aren't aware of. The length of the string is therefore different in the two cases.
So StrCat does work, however the text you are looking for is a few characters later in the string than you expect and therefore not showing on the screen.

Why the compiler does this, I have no clue...
My blog: http://spillerrec.dk/category/lego/
RICcreator, an alternative to nxtRICeditV2: http://riccreator.sourceforge.net/
ricardocrl
Posts: 117
Joined: 27 Dec 2010, 19:27

Re: [NXC] StrCat not working with string returned from Flatten

Post by ricardocrl »

Oh, nice explanation. It makes some sense, as Flatten() is a general function, it's normal that it returns a 4-byte string, regardless of the kind of the variable.

I would suggest that this note could be on the description in the API html help.

Thank you!
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: [NXC] StrCat not working with string returned from Flatten

Post by afanofosc »

Flatten is implemented in the compiler as a function that can take a boolean expression as its input. It needs to use temporaries as a result of this capability. The temporaries used for all NXC expressions are either signed longs, unsigned longs, or floats.

FlattenVar is defined as a macro in NXCDefs.h so it cannot accept any kind of NXC expression (since it emits an NBC asm block directly into the resulting code). FlattenVar can work with any type, not just simple numbers. It will flatten to a string whose length is determined by the size of the input variable.

There is a new SizeOf API function in NXC which will be included in the next test/official release that uses FlattenVar to calculate at runtime the size of any type. For simple types it does the calculation at compile time. The Read/ReadLn functions have been modified to use this new function so that it can calculate the right number of bytes to read from a file based on the size of the container provided to store the data in.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
ricardocrl
Posts: 117
Joined: 27 Dec 2010, 19:27

Re: [NXC] StrCat not working with string returned from Flatten

Post by ricardocrl »

Well, there's one thing I'm not getting...

If the null terminator is the value 0, why doesn't strcat() ignore the 0-value bytes of the Flatten() result of the variables with less then 4 bytes? And from what I just tried, if I call strlen(Flatten(1)) it gives me 4.

Is that because of the structure behind the "string" type, that contains length information?

Cheers,
Ricardo
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: [NXC] StrCat not working with string returned from Flatten

Post by afanofosc »

A string is just an array of bytes and strlen = array length - 1. The firmware keeps track of the number of elements in each array so it would think that the string was 4 bytes long even though 2 of those bytes were additional nulls (with the actual array length being 5).

All that strcat does is the same thing as arraybuild except that it drops off the last element in each of the source arrays both when counting how many elements the destination array needs to have room for and when using memmove to copy the data from each source array into the memory allocated for the destination array.

So your concatenation worked fine but you have two nulls embedded in the middle of your string - and the first two characters in it are not representable on the NXC LCD screen using the font defined in the firmware.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
ricardocrl
Posts: 117
Joined: 27 Dec 2010, 19:27

Re: [NXC] StrCat not working with string returned from Flatten

Post by ricardocrl »

Ah, OK, I see. I thought that when operating with a string, it would look for the first null-terminator, like the normal C does.

Thank you John!
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests