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 返回值之间的差异始终是换行符的数量。

我的问题是:

  1. strlen 真的不计算换行符还是我遗漏了什么?
  2. 换行符如何影响内部对 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()"

区别在于换行的数量:

http://i.stack.imgur.com/y0QOW.png

Window 的行结尾 (CR+LF) 是两个字符,使文件大小大于字符串中的字符数,因此 resize 操作使用文件大小而不是空终止字符串的长度。 strlen 报告以 null 结尾的字符串的长度并将 \n 计为单个字符。您可以通过调整字符串的大小使其与 C 字符串的长度相匹配:

_Source.resize(strlen(_Source.c_str()) + 1);