2015-08-30 16 views
1

我將lua嵌入到我的項目中,遇到了一個奇怪的(對我來說)strlen和lua解釋行爲。我試圖加載一個包含lua代碼的字符串,其編號爲luaL_loadbuffer,它始終在lua代碼的最後一行上拋出「unexpected symbol」的錯誤,除非整個塊被寫入一行。因此,例如:strlen不算換行符?

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

+4

我相信,strlen的不給你的最後一個字符(隱藏\ 0),大小函數被調用後字符串構造函數被調用(即。e最後的字符包含在str2中,但不是由strlen函數賦予的長度) –

+0

'cout << strlen(str)<< endl;'gevies 34對我來說。 – BLUEPIXY

+0

等等呢?那麼str2.size()是什麼呢? //給出strlen(str)34 ; //給出33 –

回答

1

窗口的行結尾(CR + LF)是兩個字符使文件大小超過字符串中的字符的數量多,因此resize操作使用文件大小而不是以空字符結尾的字符串的長度。 strlen報告以空字符結尾的字符串的長度並將\n計爲單個字符。您可以使大小相匹配的C字符串的長度,通過調整串事後匹配:

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

相關:http://stackoverflow.com/questions/2641639/fstreams-tellg-seekg-returning-higher-value-than-expected – ryanpattison

+0

謝謝,用unix行結尾保存文件顯示的差異。 –