【问题标题】:Lua Script CSV file to tableLua 脚本 CSV 文件到表
【发布时间】:2016-12-30 19:59:43
【问题描述】:

我对 Lua 还很陌生,所以我在将数据从 csv 文件读取到表格时遇到了一些麻烦。 csv 文件由四列组成。第一列是一个字符串,其他三列是双精度值。 我要做的是:打开文件,读入数据并处理数据。 为了测试,我想将数据打印到屏幕上。稍后我必须打开另一个文件,一个机器人程序,并将数据传递给这个程序。

我使用 consol 命令lua Script.lua 执行脚本。但我得到的只是错误消息lua: Script.lua:22: bad argument #1 to ´format´ (number expected, got nil) stack traceback: [C]: in function ´string.format´ script.lua:22: in main chunk [C]: in?

谁能告诉我我做错了什么?

编辑:所以我稍微改变了我的脚本。所以这是我的新代码

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_name, coordinate_x, coordinate_y, coordinate_z = line:match("%s*(.-),%s*(.-),%s*(.-),%s*(.-)")
    coordinates[#coordinates+1] = { coordinate_name=coordinate_name, coordinate_x = tonumber(coordinate_x), coordinate_y = tonumber(coordinate_y), coordinate_z = tonumber(coordinate_z) }
    end

    --file:close()
    return coordinates
end

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

return 0;

现在我可以执行脚本了,但打印到屏幕上的所有内容都是:X: nil, Y: nil, Z: nil。据我了解 LUA,nil 表示没有值被读取到表中。

编辑:我要读取的文件如下所示:

After;-5;-5;0;
After;-2;-5;0;
After;5;-5;0;
After;5;-2;0;
After;5;5;0;
After;2;5;0;
After;-5;5;0;
After;-5;2;0;
After;-5;-5;0;
Intersects;5;-4;0
Intersects;-5;-4;0
Intersects;-5;-3;0
Intersects;5;-3;0
Intersects;5;-2;0
Intersects;-5;-2;0

编辑:现在更新的代码:

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_name,
           coordinate_x,
           coordinate_y,
           coordinate_z = line:match("%s* (.*);%s*(.*);%s*(.*);%s*(.*);%s*(.*)")
     coordinates[#coordinates+1] = { coordinate_name = coordinate_name, coordinate_x = tonumber(coordinate_x), coordinate_y = tonumber(coordinate_y), coordinate_z = tonumber(coordinate_z) }
    print(("X: %s Y: %4f Z: %s"):format(coordinates.coordinate_x,
                                     coordinates.coordinate_y,
                                     coordinates.coordinate_z))
    end

    for _, coordinate in ipairs(coordinates) do
        print(coordinates.coordinate_x, coordinates.coordinate_z, coordinates.coordinate_z)
    end

    file:close()

    return coordinates
end

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

 return 0;

我在 Windows 上使用 Lua 5.3.3,脚本是在 LuaEdit 中编写的,并由 lua Script.lua 行调用。

【问题讨论】:

    标签: csv file-io lua


    【解决方案1】:

    在您的模式中使用(.*) 而不是(.-)。根据docs- 将匹配最短模式,这在我的测试中似乎与 z 坐标无关:

    已更新以匹配发布的文件格式

        local coordinate_name,
              coordinate_x,
              coordinate_y,
              coordinate_z = line:match("([^;]*);([^;]*);([^;]*);([^;]*)")
    

    tonumber 将为您处理空间修剪,您似乎没有在任何地方使用坐标名称。有很多string trim implementations 可供您选择,如果您以后需要修剪坐标名称变量。

    完整的脚本供参考。

    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_name,
            coordinate_x,
            coordinate_y,
            coordinate_z = line:match("([^;]*);([^;]*);([^;]*);([^;]*)")
            coordinates[#coordinates+1] = { coordinate_name = coordinate_name, coordinate_x = tonumber(coordinate_x), coordinate_y = tonumber(coordinate_y), coordinate_z = tonumber(coordinate_z) }
        end
    
        file:close()
    
        return coordinates
    end
    
    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
    
    return 0;
    

    【讨论】:

    • 我刚刚尝试了您的模式来读取 csv 文件。但仍然所有打印到控制台窗口的是:X: nil, Y. nil, Z: nil。有没有办法测试读取功能是否有效并单独测试打印。也许读取功能有效,但我的打印功能错误。
    • 您的打印功能对我来说很好用。也许您的文件有问题,或者它根本没有读取它,因为它不在同一个文件夹中。尝试在 read_file 循环中打印出 line 变量,看看是否有任何输出显示,并仔细检查内容的格式是否正确。
    • 我将打印行复制到循环 for line in io.lines(path) do 中,但仍然得到 nil 作为答案。我还检查了该文件是否与 lua 脚本位于同一文件夹中,并且命令行是否在同一文件夹中打开。我还编辑了我的问题,以便您查看文件的外观。
    • 啊,你的问题。您的字段由分号分隔,而不是逗号。试试line:match("%s*(.*);%s*(.*);%s*(.*);%s*(.*)")
    • 我更改了您建议的行,但仍然没有打印到屏幕上。但我还有一个问题。如果我将坐标作为字符串读取,然后通过命令tonumber 将这些坐标转换为数字,那么使用%s 打印它是否正确? %d 会不会更好,就像在 C 中一样?
    猜你喜欢
    • 2015-06-27
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 2014-11-05
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多