1、我们都知道,在任何语言当中都有输入输出,比如c语言当中就有很多printf,scanf,get ,put,gets,puts,文件io:open,read,write,close,标准io:fopen,fread,fwrite,fclose.在lua语言当中,也有相同的一些输入输出特性,叫io.open,io.read,io.write,io.close,这类似的输入输出函数。
两者相似但是有一些区别,那么下面我们就来对比学习。
官方参考手册原话:
I/O 库提供了两套不同风格的文件处理接口。 第一种风格使用隐式的文件句柄; 它提供设置默认输入文件及默认输出文件的操作, 所有的输入输出操作都针对这些默认文件。 第二种风格使用显式的文件句柄。
当使用隐式文件句柄时, 所有的操作都由表 io
提供。 若使用显式文件句柄, io.open 会返回一个文件句柄,且所有的操作都由该文件句柄的方法来提供。
表 io
中也提供了三个 和 C 中含义相同的预定义文件句柄: io.stdin
, io.stdout
, 以及 io.stderr
。 I/O 库永远不会关闭这些文件。
两者的权限参数基本相同。只不过在lua语言当中更加简洁
模式 | C 语言 (fopen ) | Lua (io.open ) | 描述 |
---|---|---|---|
r | "r" | "r" | 只读模式打开文件。文件必须存在,否则会失败。 |
w | "w" | "w" | 只写模式打开文件。如果文件存在,内容会被清空;如果文件不存在,会创建。 |
a | "a" | "a" | 追加模式打开文件。如果文件存在,写入内容会追加到文件末尾;如果文件不存在,会创建。 |
r+ | "r+" | "r+" | 读写模式打开文件。文件必须存在,否则会失败。 |
w+ | "w+" | "w+" | 读写模式打开文件。如果文件存在,内容会被清空;如果文件不存在,会创建。 |
a+ | "a+" | "a+" | 读写模式打开文件。如果文件存在,写入内容会追加到文件末尾;如果文件不存在,会创建。 |
1、fopen()和io.open()
c语言当中的fopen是标准io,返回值是file*指针,是一个文件指针类型
FILE *file = fopen("test.txt", "r");
if (file == NULL) {printf("Failed to open file.\n");
}
lua语言当中io.open,返回值是userdata类型,是一个文件对象
local file = io.open("test.txt", "r")
if not file thenprint("Failed to open file.")
end
2、scanf()和io.read()
在c语言当中,一般使用scanf来获取文件信息
char buffer[100];
int n;
scan("%d",&n);
printf("%d", n);
在lua语言当中,一般使用io.read()来读取终端的输入信息
local n=io.read()
io.write("n="..n.."\n")
3、fprintf()和io.write()
在c语言标准io中,使用fprintf()来输出信息
fprintf(file, "Hello, C!\n");
在lua语言中,使用io.write()来输出信息
io.write("hello! lua")
4、fclose()和close()
在c语言标准io当中,使用fclose来关闭一个已经打开的文件,参数是文件
fclose(file);
在lua语言当中,使用close来关闭一个已经打开的文件,参数是文件对象
file:close()
上面我说到c语言当中的文件io和标准io,那么在lua当中有没有标准和文件之分呢?
其实是有的。
write和io.write的区别
特性 | file:write() | io.write() |
---|---|---|
数据目标 | 向已打开的文件对象中写入数据。 | 向标准输出(通常是控制台)写入数据。 |
使用场景 | 用于文件操作。 | 用于控制台输出或标准输出流操作。 |
是否需要打开文件 | 需要先通过 io.open 打开文件。 | 不需要打开文件,直接写入到标准输出。 |
返回值 | 返回文件对象本身(支持链式调用)。 | 返回 io 对象本身(支持链式调用)。 |
常用场景 | 写入文件内容。 | 打印调试信息或输出到控制台。 |
其实在lua当中使用io.read和c里面使用scanf差不多,如果是普通的read,是对文件进行操作的,必须要先打开一个文件,这样才能进行读和写的操作。
特性 | file:read("*a") | io.read() |
---|---|---|
数据来源 | 从已打开的文件对象中读取数据。 | 从标准输入(通常是控制台)读取数据。 |
使用场景 | 用于文件操作。 | 用于用户输入或标准输入流操作。 |
模式参数 | 支持 "*a" (读取整个文件)等模式。 | 支持 "*a" (读取所有输入)等模式。 |
返回值 | 返回文件内容(字符串)。 | 返回用户输入内容(字符串或数字等)。 |
是否需要打开文件 | 需要先通过 io.open 打开文件。 | 不需要打开文件,直接从标准输入读取。 |
举例练习:
1、下面是一个修改键的值的代码,请问修改之后,表的顺序改变了吗?
local t = {1,2,3,key="value"}print(t[1],t["key"])
--修改键
--方法如下
local old=1
local new=10
local value=t[old]
t[old]=nil
t[new]=value
print(t[10],t["key"])
表的顺序已经发生了改变,为什么呢,由于lua表是哈希表存储的,键 1
被删除,键 10
被添加,存储位置和遍历顺序发生了变化。
如果做一个遍历查询会比较直观,
local t = {1, 2, 3, key = "value"}-- 第一次遍历
print("Before modification:")
for k, v in pairs(t) doprint(k, v)
end-- 修改键
local old = 1
local new = 10
local value = t[old]
t[old] = nil
t[new] = value-- 第二次遍历
print("After modification:")
for k, v in pairs(t) doprint(k, v)
end
输出结果如下
Before modification:
1 1
2 2
3 3
key valueAfter modification:
2 2
3 3
10 1
key value
可以发现,这时候发现表中的数据顺序已经发生了改变
2、下面的代码输出什么
local x=15
if x > 10 thenprint(x..">"..10)
elseif x < 10 thenprint(x.."<".."10")
elseif x > 5 thenprint(x..">".."5")
elseprint("x<5")
end
输出:
15>10
这里是一个条件分支结构,只会选择一条支路执行
3,下面的代码输出什么
--第三题
local function add(a,b)return a+b
end
print(add(3,4))
输出7,这个没什么说的
4、下面的代码输出什么
--four
local s="hello! lua"
print(string.sub(s,1,5))
输出hello
5、下面的输出是什么
--five
local m={1,2,3,4}
m[#m+1]=4
print(#m,m[4])
输出5,4
6、下面输出的是什么
--six
local t = {10, 20, 30}
for i, v in ipairs(t) doprint(i, v)
end
输出10 1 ,20 2,30 3.
7、下面代码输出什么
local t1 = {1, 2, 3}
local t2 = {4, 5, 6}
setmetatable(t1, {__add = function(a, b)local result = {}for i, v in ipairs(a) dotable.insert(result, v + b[i])endreturn result
end})
local t3 = t1 + t2
print(table.concat(t3, ", "))
输出5,7,9