【问题标题】:Read double values from csv file to table从 csv 文件读取双精度值到表
【发布时间】:2016-10-21 08:33:18
【问题描述】:

首先我想提一下,这是我在 Lua 中的第一个程序。我需要开发一个读取 CSV 文件的 Lua 应用程序。该文件由四列和未知数量的行组成。因此我必须阅读到文件行尾。在每一行中,存储点的 xyz 坐标。这些坐标存储为双精度值。现在我必须将值从 csv 文件复制到一个表(Lua 中的数组)。稍后在文件中,我必须为 igm 机器人编辑机器人程序。因此我需要这张桌子。直到现在我有闲置的代码,但我不确定这是否是开始这个​​的正确方法:

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;

所以首先我执行了一个 C++ 程序,它创建了 csv 文件,但后来我想改变这个过程,使 C++ 程序独立于 Lua 脚本。这里这条线只是为了测试。在这一行之后,我想将 csv 文件中的数据读取到表格中并将表格打印到屏幕上。所以对我来说,我只是将文件的内容打印到命令行,这样我就可以检查脚本是否工作正常。

我以前从未使用过 Lua,文档对我来说真的很难理解。因此,如果您能给予我任何帮助,我将不胜感激。

编辑:我现在使用user3204845 的帖子来更新我的代码。要将表格打印到屏幕上,我使用了 print 命令。但这样我就得到了0069b568。所以我的想法是使用for-loop。但这不起作用。有人可以给我一个提示如何访问 Lua 表中的条目吗?这是我的代码:

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;

【问题讨论】:

    标签: io lua


    【解决方案1】:

    您可以使用 string.format 漂亮地打印您的值:

    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 是字符串值的占位符:第一个 %s 将替换为 coordinates[line].coordinate_x 中的值,第二个将替换为 coordinates[line].coordinate_y,依此类推。

    ipairs 用于根据其索引 (1, 2, 3, ...) 对表进行迭代,而 pairs 使用“自然”排序,不遵循特定逻辑;)

    但是,由于我猜您不仅想将这些值用于打印出来,因此您可能需要考虑将它们存储为数字;相应地编辑您的脚本:

    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
    

    现在,您实际上可以对这些值进行数学运算。这也使您可以更好地控制输出:例如,将上述格式表达式中的 %s 替换为 %.2f,以始终显示带有两位小数的数字。

    【讨论】:

    • 感谢您的帮助。我还有一个问题。当我想在 LuaEdit 中调试我的脚本时,我收到错误消息,它期望在print 附近有一个do 命令。所以看来我的 for 循环不正确。
    • 发现错误,我在for循环中忘记了do,但它仍然不起作用。代码for line in coordinates do 似乎是假的,以防迭代表
    • 您可以使用ipairs 来遍历一个表,我已经相应地更新了我的答案。另请注意,我清理了read_file 方法,因为有不必要的代码。
    • 我尝试了for-loop 的代码,但是当我开始调试时,我收到错误消息 bad argument #1 to format。由于忘记了标志,我不得不稍微更改代码,但主要我使用了您的代码。所以这里是:for _, coordinate in ipairs(coordinates) do print(("X: %s, Y: %s, Z: %s"):format(coordinate.coordinate_x, coordinate.coordinate_y, coordinate.coordinate_z)) end
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    相关资源
    最近更新 更多