Print a list that is stored in a variable in LUA - lua

My script uses lfs to read files in a directory.
It then stores the value in a variable called file.
The problem is the value is actually a list.
Here is a sample value.
.
..
a.txt
b.txt
c.txt
d.txt
I can print this variable as is, but I need to integrate this variable inside a dialog box.
When I integrate this variable inside a dialog box, it prints each line in a new dialog.
Here is my code:
require 'lfs'
function main()
for file in lfs.dir[[C:\Users\QXJtaW5pdXM\Desktop\Test\test_3.4.5.6]] do
print(file)
--This works perfectly fine.
Dialog("Title", "Files:\n" .. file)
--This prints each line in a new dialog box.
end
end
return main
I need to print all the files in one dialog box.
If at all possible, I'd love to avoid printing . & ..
As a picture reference, here is what I get:
https://imgur.com/tmfQlan
Here is what I need:
https://imgur.com/mxYBO9t
Could someone please point me in the right direction?
Thank you very very very much!

Your loop's body is executed once for every file so what do you expect if you create a dialog inside the loop? Create it outside after you've created a list of files.
require 'lfs'
function main()
local files = ""
for file in lfs.dir[[C:\Users\QXJtaW5pdXM\Desktop\Test\test_3.4.5.6]] do
files = files .. file .. "\n"
end
Dialog("Title", "Files:\n" .. files)
end
Maybe there is also another function that gives you a list of file names right away.

I had to use table.insert in a for loop to add values inside a table file_list.
Then use table.remove to remove the first two inputs . & ..
In the end, the code would look something like this:
require 'lfs'
file_list = {}
function main()
for grab_files in lfs.dir[[C:\Users\QXJtaW5pdXM\Desktop\Test\test_3.4.5.6]] do
table.insert(file_list, grab_files)
-- table.insert will assign each input of grab_files into each reference of file_list table
end
table.remove(file_list,1)
-- This removes the '.'
table.remove(file_list,1)
-- This removes the '..'
file_names = table.concat(file_list, "\n")
Dialog("Title", "Files:\n" .. file_names)
end
return main

Related

Unable to use io.read() to grab the user's input after already using it to grab a file's contents

I've got this program that starts off with the program grabbing a file's contents.
local oldprint = print
local print = io.write
-- this was done mainly because the newline from print() wasn't needed
io.input("script.txt")
local script = io.read("*all")
io.close()
Then there is a function containing another io.read(), which should allow for the user's input.
local functions = {
[","] = function()
local input
repeat
print("\nAwaiting input... (must be a number)\n")
input = io.read("*n")
until input ~= nil
array[pointer] = input
print(stringy)
end
}
functions[","]()
I expect it for it to print once, and then grab the input, but it ends up constantly printing.
I've tried using io.flush(), but it didn't work, and I'm not exactly sure what else to try...
By calling io.input("script.txt") you set that file as the default input file. Any following calls to io.read() will hence read from that file.
Either use file:read instead of io.read or reset the input to the standard input stream by calling io.input(io.stdin).
I suggest you refer to the Lua reference manual.
https://www.lua.org/manual/5.4/manual.html#6.8
To use io.read(), you have to close the file you opened, because if you have a file open, lua will assume you are reading from the file that you opened.
Try grabbing the input before you open the file

Why the lua function io.write() did not work. It only display the results on the terminal, rather than writing to a file

I am learning the Lua IO library. I'm having trouble with io.write(). In Programming Design in Lua, there is a piece of code that iterates through the file line by line and precedes each line with a serial number.
This is the file I`m working on:
test file: "iotest.txt"
This is my code
io.input("iotest.txt")
-- io.output("iotest.txt")
local count = 0
for line in io.lines() do
count=count+1
io.write(string.format("%6d ",count), line, "\n")
end
This is the result of the terminal display, but this result cannot be written to the file, whether I add IO. Output (" iotest.txt ") or not.
the results in terminal
This is the result of file, we can see there is no change
The result after code running
Just add io.flush() after your write operations to save the data to the file.
io.input("iotest.txt")
io.output("iotestout.txt")
local count = 0
for line in io.lines() do
count=count+1
io.write(string.format("%6d ",count), line, "\n")
end
io.flush()
io.close()
Refer to Lua 5.4 Reference Manual : 6.8 - Input and Output Facilities
io.flush() will save any written data to the output file which you set with io.output
See koyaanisqatsi's answer for the optional use of file handles. This becomes especially useful if you're working on multiple files at a time and gives you more control on how to interact with the file.
That said you should also have different files for input and output. You'll agree that it doesn't make sense to read and write from and to the same file alternatingly.
For writing to a file you need a file handle.
This handle comes from: io.open()
See: https://www.lua.org/manual/5.4/manual.html#6.8
A file handle has methods that acts on self.
Thats the function after the : at file handle.
So io.write() puts out on stdout and file:write() in a file.
Example function that can dump a defined function to a file...
fdump=function(func,path)
assert(type(func)=="function")
assert(type(path)=="string")
-- Get the file handle (file)
local file,err = io.open(path, "wb")
assert(file, err)
local chunk = string.dump(func,true)
file:write(chunk)
file:flush()
file:close()
return 'DONE'
end
Here are the methods, taken from io.stdin
close = function: 0x566032b0
seek = function: 0x566045f0
flush = function: 0x56603d10
setvbuf = function: 0x56604240
write = function: 0x56603e70
lines = function: 0x566040c0
read = function: 0x56603c90
This makes it able to use it directly like...
( Lua console: lua -i )
> do io.stdout:write('Input: ') local result=io.stdin:read() return result end
Input: d
d
You are trying to open the same file for reading and writing at the same time. You cannot do that.
There are two possible solutions:
Read from file X, iterate through it and write the result to another file Y.
Read the complete file X into memory, close file X, then delete file X, open the same filename for writing and write to it while iterating through the original file (in memory).
Otherwise, your approach is correct although file operations in Lua are more often done using io.open() and file handles instead of io.write() and io.read().

How to load host.conf file variables in lua script

I need to load configuration variables from .conf file in lua script, and use those variables to connect to a database. I have tried using:
require "host.conf"
loadfile("host.conf") - error with unexpected token '#'
os.execute("pathToConfFile/host.lua") - and I have created a lua host file with variables in bash shell
io.popen("host.conf") etc..
None of these solutions are valid.
Is there a way to use the existing host.conf file in lua, and avoid the unexpected token error?
Thank you for your suggestions.
local original = io .open('host.conf')
local hostconf = {} -- copy contents into Lua table
for line in original :lines() do
table .insert( hostconf, line )
end ; io .close( original )
print( hostconf[1] ) -- prints line 1
You haven't specified what format your host.conf comes in, but you'll likely want to parse it better than just throwing contents in a list. Perhaps splitting each line into head / tail, based upon a delimiter ( comma, space, whatever you have between variable & value )
Thank you to everyone who helped out. My question wasn't precise and I had more to learn before I have asked and sorry about that. This is what I used to solve the problem.
local open = io.open
local function read_file(path)
local file = open(path, "r")
if not file then return nil end
local content = file:read "*a" -- *a or *all reads the whole file
local lines = {}
for line in io.lines(path) do
--print(line);
if(line:find(var)~=nil)then
local varStart=string.len(var)+2
local varEnd=string.len(line)
var=string.sub(line,varStart,varEnd)
print(var);
end
--repeat for every line
end
file:close()
return lines;
end
local fileContent = read_file("path");

require function can't see the module file

So this is my kek13 lua chunk file:
-- modules
-- a package is a collection of modules
local test = {}
function test.add(n1, n2) -- dont put local as the scope of this function
since you already added
-- a local to the 'test' table... doing so will return an error
return n1 + n2
end
function test.hi(name)
return "my name is " .. name
end
return test
.. and this is my kek13Part2Real lua chunk file:
print("===========================")
local dad = require("kek13")
print(dad.hi("A"))
print(dad.add(1, 5))
print("==============================")
require ("kek13")
print(dad.hi("ur mum"))
print(dad.add(2, 2))
print("========================================")
They are in the same folder, at least in the document folder.
The only problem is that this causes an error. Something like lua can't find or see the file. I'm using Zerobrane IDE for this by the way.
require does not check the folder where the calling script is located it.
Use dofile with a path or add the folder containing the desired script to your LUA_PATH environment variable or append it to package.path
This is not how require works. Please read manuals...
https://www.lua.org/manual/5.3/manual.html#pdf-require

Load Lua-files by relative path

If I have a file structure like this:
./main.lua
./mylib/mylib.lua
./mylib/mylib-utils.lua
./mylib/mylib-helpers.lua
./mylib/mylib-other-stuff.lua
From main.lua the file mylib.lua can be loaded with full path require('mylib.mylib'). But inside mylib.lua I would also like to load other necessary modules and I don't feel like always specifying the full path (e.g. mylib.mylib-utils). If I ever decide to move the folder I'm going to have a lot of search and replace. Is there a way to use just the relative part of the path?
UPD. I'm using Lua with Corona SDK, if that matters.
There is a way of deducing the "local path" of a file (more concretely, the string that was used to load the file).
If you are requiring a file inside lib.foo.bar, you might be doing something like this:
require 'lib.foo.bar'
Then you can get the path to the file as the first element (and only) ... variable, when you are outside all functions. In other words:
-- lib/foo/bar.lua
local pathOfThisFile = ... -- pathOfThisFile is now 'lib.foo.bar'
Now, to get the "folder" you need to remove the filename. Simplest way is using match:
local folderOfThisFile = (...):match("(.-)[^%.]+$") -- returns 'lib.foo.'
And there you have it. Now you can prepend that string to other file names and use that to require:
require(folderOfThisFile .. 'baz') -- require('lib.foo.baz')
require(folderOfThisFile .. 'bazinga') -- require('lib.foo.bazinga')
If you move bar.lua around, folderOfThisFile will get automatically updated.
You can do
package.path = './mylib/?.lua;' .. package.path
Or
local oldreq = require
local require = function(s) return oldreq('mylib.' .. s) end
Then
-- do all the requires
require('mylib-utils')
require('mylib-helpers')
require('mylib-other-stuff')
-- and optionally restore the old require, if you did it the second way
require = oldreq
I'm using the following snippet. It should work both for files loaded with require, and for files called via the command line. Then use requireRel instead of require for those you wish to be loaded with a relative path.
local requireRel
if arg and arg[0] then
package.path = arg[0]:match("(.-)[^\\/]+$") .. "?.lua;" .. package.path
requireRel = require
elseif ... then
local d = (...):match("(.-)[^%.]+$")
function requireRel(module) return require(d .. module) end
end
Under the Conky's Lua environment I've managed to include my common.lua (in the same directory) as require(".common"). Note the leading dot . character.
Try this:Here is my findings:
module1= require(".\\moduleName")
module2= dofile("..\\moduleName2.lua")
module3 =loadfile("..\\module3.lua")
To load from current directory. Append a double backslash with a prefix of a fullstop.
To specify a directory above use a prefix of two fullstops and repeat this pattern for any such directory.e.g
module4=require("..\\..\\module4")

Resources