Differences in behaviour between simulator and Adnroid device (FILE I/O ++)

I’m writing a simple racing game and I’m struggling with reading the level data from text files. Each text file is supposed to contain the level data for one level and has the format:

-T-


C–

Where each line represents 3 lanes and each character represents an object. “-” means no object etc.

What I want to do is to read these data and place them into an level array for further in-game processing. The (simplified) code for this is shown below:

-- Open and read level data file local path = system.pathForFile( "levels/1.txt", system.ResourceDirectory ) local file = io.open( path, "r" ) local fileData = file:read( "\*a" ) -- Arrange level data into array (currLevelData) local currLevelData = {} -- Control number of lines in level data file local numLevelLines = select(2, fileData:gsub('\n', '\n')) + 1 print("\nFile data has " .. numLevelLines .. " lines:\n" .. fileData) local moreLines = true local lineNum = 1 -- Current line number while traversing data local bufferPtr = 1 -- Offset into file data string while moreLines do currLevelData[lineNum] = {} -- Create new entry to currLevelData array/table -- Each level line contains data for three (highway) lanes. Create sub for laneNum=1, 3 do -- Add table sub item with object ID and speed currLevelData[lineNum][laneNum] = {} currLevelData[lineNum][laneNum].objId = fileData:sub(bufferPtr, bufferPtr) currLevelData[lineNum][laneNum].speed = laneNum bufferPtr = bufferPtr + 1 -- Move to next char end -- Move pointer to next line (skip newline character(s)) bufferPtr = bufferPtr + 2 lineNum = lineNum + 1 if (lineNum \> numLevelLines) then moreLines = false end end -- Do a printout to verify level data array print("\nLevel data array (" .. #currLevelData .. " lines):") for i=1, #currLevelData do local lane1 = currLevelData[i][1].objId .. ", " .. currLevelData[i][1].speed local lane2 = currLevelData[i][2].objId .. ", " .. currLevelData[i][2].speed local lane3 = currLevelData[i][3].objId .. ", " .. currLevelData[i][3].speed print(lane1 .. ", " .. lane2 .. ", " .. lane3) end io.close( file ) file = nil 

This works just great - in the simulator. But as soon as I try to run it on an actual device (running Android 4.4.2) the data looks garbled.

The exact output from the simulator looks like this:

Copyright © 2009-2014  C o r o n a   L a b s   I n c .

        Version: 3.0.0

        Build: 2014.2511

Platform: GT-I9300 / x64 / 6.2 / GeForce GTX 765M/PCIe/SSE2 / 4.4.0 / 2014.2511

File data has 4 lines:

1AB

2CD

3EF

4GH

Level data array (4 lines):

1, 1,   A, 2,   B, 3

2, 1,   C, 2,   D, 3

3, 1,   E, 2,   F, 3

4, 1,   G, 2,   H, 3

While the exact adb logging (adb logcat Corona:v *:s) looks like this:

V/Corona  ( 8551): Loading via reflection: CoronaProvider.licensing.google.LuaLoader

I/Corona  ( 8551):

I/Corona  ( 8551): File data has 4 lines:

I/Corona  ( 8551): 1AB

2CDorona  ( 8551):

3EForona  ( 8551):

4GHorona  ( 8551):

I/Corona  ( 8551):

I/Corona  ( 8551): Level data array (4 lines):

I/Corona  ( 8551): 1, 1,   A, 2,   B, 3

, 1,   2, 2,   C, 3

I/Corona  ( 8551):

, 2,   3, 3 8551): , 1,

, 1,   a  ( 8551):

, 3orona  ( 8551): , 2,

Can anybody explain what’s happening and why the simulator and device behaves so differently?

In the section with:

 -- Move pointer to next line (skip newline character(s)) bufferPtr = bufferPtr + 2

I started out using +1, but switched to +2 since Notepad inserts both a newline and a carriage return (two bytes) for each newline. Makes no difference, however. With both +1 and +2 the simulator code works and the device do not.

But it surely seems like there is something fishy going on with the newline interpretation. I just can’t see what.

As a side note: I have also tried Notepad++ and loading the txt file written with Notepad it showed like this:

1AB 2CD 3EF 4GH

If I removed the extra lines, saved the file and ran the app in the simulator it didn’t register more than one line (in other words: no newlines).

1.txt is the file saved from Notepad

1b.txt is the file saved from Notepad++ with the extra line breaks (shown above) removed

Android is based on Unix/Linux.  It only uses a single character newline (\n or ASCII 10).  Windows uses a two character newline \r\n (ASCII 13, ASCII 10).  This is why you are seeing a difference.   file.read() has an option that will read one line at a time instead of reading the whole file that you are doing with *a as the parameter.

Rob

Thanks, Rob, that really helped. 

As a side note: I have also tried Notepad++ and loading the txt file written with Notepad it showed like this:

1AB 2CD 3EF 4GH

If I removed the extra lines, saved the file and ran the app in the simulator it didn’t register more than one line (in other words: no newlines).

1.txt is the file saved from Notepad

1b.txt is the file saved from Notepad++ with the extra line breaks (shown above) removed

Android is based on Unix/Linux.  It only uses a single character newline (\n or ASCII 10).  Windows uses a two character newline \r\n (ASCII 13, ASCII 10).  This is why you are seeing a difference.   file.read() has an option that will read one line at a time instead of reading the whole file that you are doing with *a as the parameter.

Rob

Thanks, Rob, that really helped.