strlen不算新行?

时间:2015-08-30 23:12:22

标签: visual-c++ lua visual-studio-2015

我将lua嵌入到我的项目中,并遇到了strlen和lua解释的奇怪(对我来说)行为。我试图加载一个包含lua代码的字符串luaL_loadbuffer,并且它始终抛出" unexpected symbol"在任何是lua代码的最后一行,除非整个块写在一行。例如:

  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& #39)。那就是:

 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代码的解释?
  3. 我正在使用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

1 个答案:

答案 0 :(得分:1)

窗口的行结尾(CR + LF)是两个字符,使文件大小大于字符串中的字符数,因此 static void Main(string[] args) { var id = Guid.Parse("bleh"); Expression<Func<Thingemebob, bool>> selector = x => x.Id == id; var tickList = new List<long>(); for (int i = 0; i < 100000; i++) { var sw = Stopwatch.StartNew(); GetValueWithExpressionsAndReflection(selector); sw.Stop(); tickList.Add(sw.ElapsedTicks); } Trace.WriteLine("GetValueWithExpressionsAndReflection: Average over 100000, first call included: " + tickList.Average()); Trace.WriteLine("GetValueWithExpressionsAndReflection: First call: " + tickList[0]); Trace.WriteLine("GetValueWithExpressionsAndReflection: Average over 100000, first call excluded: " + tickList.Skip(1).Average()); tickList = new List<long>(); for (int i = 0; i < 100000; i++) { var sw = Stopwatch.StartNew(); GetValueWithCompiledExpression(selector); sw.Stop(); tickList.Add(sw.ElapsedTicks); } Trace.WriteLine("GetValueWithCompiledExpression: Average over 100000, first call included: " + tickList.Average()); Trace.WriteLine("GetValueWithCompiledExpression: First call: " + tickList[0]); Trace.WriteLine("GetValueWithCompiledExpression: Average over 100000, first call excluded: " + tickList.Skip(1).Average()); Debugger.Break(); } private static void GetValueWithCompiledExpression(Expression<Func<Note, bool>> selector) { BinaryExpression binaryExpression = (BinaryExpression)selector.Body; MemberExpression memberExpression = (MemberExpression)((UnaryExpression)binaryExpression.Right).Operand; var o = Expression.Lambda(memberExpression).Compile().DynamicInvoke(); } private static void GetValueWithExpressionsAndReflection(Expression<Func<Note, bool>> selector) { BinaryExpression binaryExpression = (BinaryExpression)selector.Body; MemberExpression memberExpression = (MemberExpression)((UnaryExpression)binaryExpression.Right).Operand; ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression; FieldInfo member = (FieldInfo)memberExpression.Member; var instance = constantExpression.Value; var guid = member.GetValue(instance); } 操作使用文件大小而不是以null结尾的字符串的长度。 resize报告以null结尾的字符串的长度,并将strlen计为单个字符。您可以通过调整字符串大小以匹配以后匹配C字符串的长度:

\n