1

First I want to mention that this is my first program in Lua. I need to develop a Lua application, which reads a CSV file. The file consists of four columns and an unknown number of rows. Therefore I have to read till end of lines of file. In each row, the xyz coordinate for points stored. These coordinates are stored as double values. Now I have to copy the values form the csv file to a table (array in Lua). Later in the file I have to edit a Robot Program for an igm Robot. Therefore I need the table. Till now I have the fallowing code, but I'm not sure if this is the rigth way to start this:

local open = io.open

local function read_file(path)
    local file = open(path, "r") -- r read mode and b binary mode
    if not file then return nil end
    local content = file:read "*a" -- *a or *all reads the whole file
    file:close()
    return content
end


os.execute("OpenGLM_3.exe -slicesize 3 -model cube_2.stl -ascii - eulerangles 0 0 0")
local fileContent = read_file("data.csv");

return 0;

So first I execute an C++ program, which creates the csv file, but later I want to change the process, so that the c++ program is independent from the Lua script. Here this line is just for testing. After this line I want to read the data from the csv file to a table and print the table to the screen. So for me, I would just print the content of the file to the command line, so I could check if the script is working correct.

I never worked with Lua before, and the documentation is really hard to understand for me. So I would be grateful for any help you can give me.

Edit: I now worked with the post by user3204845 to update my code. To print the table to screen I used the print command. But in that way I just got 0069b568. So my idea was to use a for-loop. But that does not work. Can someone give me a hint how to access a entry in a table in Lua. Heres my code:

local open = io.open

local function read_file(path)
   local file = open(path, "r") -- r read mode and b binary mode
   if not file then return nil end
   local coordinates = {}

   for line in io.lines(path) do
   local coordinate_x, coordinate_y, coordinate_z = line:match("%s*(.-),%s*(.-),%s*(.-)")
   coordinates[#coordinates+1] = { coordinate_x = coordinate_x, coordinate_y = coordinate_y, coordinate_z = coordinate_z }
    end

    file:close()
    return coordinates
end


os.execute("OpenGLM_3.exe -slicesize 3 -model cube_2.stl -ascii - eulerangles 0 0 0")
local coordinates = read_file("data.csv")
for line in coordinates
   print(coordinates[line])
end
return 0;
Community
  • 1
  • 1
user3794592
  • 183
  • 2
  • 16

1 Answers1

2

You can use string.format to pretty-print your values:

local coordinates = read_file("data.csv")
for _, coordinate in ipairs(coordinates) do  -- use pairs or ipairs to iterate over tables
    print(("X: %s, Y: %s, Z: %s"):format(coordinate.coordinate_x,
                                         coordinate.coordinate_y
                                         coordinate.coordinate_z)
end

%s is a placeholder for string values: The first %s will be replaced by the value in coordinates[line].coordinate_x, the second one with coordinates[line].coordinate_y and so forth.

ipairs is used to iterate over a table according to its indices (1, 2, 3, ...), while pairs uses the 'natural' ordering, which follows no specified logic ;)

However, since I guess you'll want to use these values for more than just printing them out, you might want to consider storing them as numbers; edit your script accordingly:

local function read_file(path)
    local coordinates = {}

    for line in io.lines(path) do
        local coordinate_x, coordinate_y, coordinate_z = line:match("%s*(.-),%s*(.-),%s*(.-)")
        coordinates[#coordinates+1] = { coordinate_x = tonumber(coordinate_x), coordinate_y = tonumber(coordinate_y), coordinate_z = tonumber(coordinate_z) }
    end

    return coordinates
end

Now, you can actually perform math on the values. This also allows you to have more control over your output: For example, replace %s in the above format expression with %.2f, to always display the numbers with two decimal digits.

Henrik Ilgen
  • 1,879
  • 1
  • 17
  • 35
  • Thanks for the help. I still have a question. When I want to debugg my script in LuaEdit I get the error message the it expected a `do` command near `print`. So it seems my for loop isn't correct. – user3794592 Jun 21 '16 at 10:40
  • Found the error, i fogot the do in the for loop, but it still doe not work. The code `for line in coordinates do` seems to be false, in case to iterate over a table – user3794592 Jun 21 '16 at 10:52
  • You can use `ipairs` to iterate over a table, I have updated my answer accordingly. Also note that I cleaned up the `read_file` method, because there was unnecessary code. – Henrik Ilgen Jun 21 '16 at 11:50
  • I tried your code for the `for`-loop but when I start the debugging I get the error message bad arguement #1 to format. I had to change the code a litte bit, because of forgotten signs, but in the main I used your code. So here it is: `for _, coordinate in ipairs(coordinates) do print(("X: %s, Y: %s, Z: %s"):format(coordinate.coordinate_x, coordinate.coordinate_y, coordinate.coordinate_z)) end` – user3794592 Jun 21 '16 at 13:16