strlen 不计算换行符?
strlen not counting newlines?
我将 lua 嵌入到我的项目中,并遇到了 strlen
和 lua 解释的奇怪(对我来说)行为。我试图加载一个包含 lua 代码和 luaL_loadbuffer
的字符串,它始终在 lua 代码的最后一行抛出错误“unexpected symbol
”,除非整个块写在一行中。例如:
function start()
print("start")
end
总是会导致错误:第 3 行出现意外符号,但是
function start() print("start") end
加载成功。
我发现用 luaL_loadstring
加载相同的块没有错误,并且看到它使用 strlen
来确定指定字符串的长度(我使用 std::string::size
) 并且使用 strlen 向 luaL_loadbuffer
提供字符串的长度也会导致成功加载。
现在的问题是:strlen 和 std::string::size 之间可能有什么区别,最令我惊讶的是答案是 strlen 不计算新行('\n
')。即:
const char* str = "this is a string\nthis is a newline";
std::string str2(str);
str2.size(); // gives 34
strlen(str); // gives 33
大小与 strlen 返回值之间的差异始终是换行符的数量。
我的问题是:
- strlen 真的不计算换行符还是我遗漏了什么?
- 换行符如何影响内部对 lua 代码的解释?
我正在使用 vs 2015 和 lua 5.3.0
编辑:
我的第一个例子不准确,也没有为我产生详细的效果,但我能够从原始代码中重现问题:
std::fstream _Stream("test.lua", std::ios::ate | std::ios::in);
std::string _Source;
if(_Stream.is_open()) {
_Source.resize(_Stream.tellg());
_Stream.seekg(0, std::ios::beg);
_Stream.read(&_Source[0], _Source.size());
_Stream.close();
}
std::cout << "std::string::size() = " << _Source.size() << std::endl;
std::cout << "strlen() = " << strlen(_Source.c_str()) << std::endl;
test.lua的内容是"function start()\n\tprint("start")\nend\n\nstart()"
区别在于换行的数量:
Window 的行结尾 (CR+LF) 是两个字符,使文件大小大于字符串中的字符数,因此 resize
操作使用文件大小而不是空终止字符串的长度。 strlen
报告以 null 结尾的字符串的长度并将 \n
计为单个字符。您可以通过调整字符串的大小使其与 C 字符串的长度相匹配:
_Source.resize(strlen(_Source.c_str()) + 1);
我将 lua 嵌入到我的项目中,并遇到了 strlen
和 lua 解释的奇怪(对我来说)行为。我试图加载一个包含 lua 代码和 luaL_loadbuffer
的字符串,它始终在 lua 代码的最后一行抛出错误“unexpected symbol
”,除非整个块写在一行中。例如:
function start()
print("start")
end
总是会导致错误:第 3 行出现意外符号,但是
function start() print("start") end
加载成功。
我发现用 luaL_loadstring
加载相同的块没有错误,并且看到它使用 strlen
来确定指定字符串的长度(我使用 std::string::size
) 并且使用 strlen 向 luaL_loadbuffer
提供字符串的长度也会导致成功加载。
现在的问题是:strlen 和 std::string::size 之间可能有什么区别,最令我惊讶的是答案是 strlen 不计算新行('\n
')。即:
const char* str = "this is a string\nthis is a newline";
std::string str2(str);
str2.size(); // gives 34
strlen(str); // gives 33
大小与 strlen 返回值之间的差异始终是换行符的数量。
我的问题是:
- strlen 真的不计算换行符还是我遗漏了什么?
- 换行符如何影响内部对 lua 代码的解释?
我正在使用 vs 2015 和 lua 5.3.0
编辑:
我的第一个例子不准确,也没有为我产生详细的效果,但我能够从原始代码中重现问题:
std::fstream _Stream("test.lua", std::ios::ate | std::ios::in);
std::string _Source;
if(_Stream.is_open()) {
_Source.resize(_Stream.tellg());
_Stream.seekg(0, std::ios::beg);
_Stream.read(&_Source[0], _Source.size());
_Stream.close();
}
std::cout << "std::string::size() = " << _Source.size() << std::endl;
std::cout << "strlen() = " << strlen(_Source.c_str()) << std::endl;
test.lua的内容是"function start()\n\tprint("start")\nend\n\nstart()"
区别在于换行的数量:
Window 的行结尾 (CR+LF) 是两个字符,使文件大小大于字符串中的字符数,因此 resize
操作使用文件大小而不是空终止字符串的长度。 strlen
报告以 null 结尾的字符串的长度并将 \n
计为单个字符。您可以通过调整字符串的大小使其与 C 字符串的长度相匹配:
_Source.resize(strlen(_Source.c_str()) + 1);