[英]std::codecvt do_out skipping characters after 1:N conversions
但是,我嘗試編寫一個自動縮進器 - 它在向流中添加新字符時跳過字符。 我試過調試它並驗證 from_next 和 to_next 以及 from 和 to 工作正常。
當然,我錯過了規范中的某些內容,但這是我的代碼,也許您能幫幫我:
virtual result_t do_out(state_type& state, const intern_type* from, const intern_type* from_end, const intern_type*& from_next,
extern_type* to, extern_type* to_end, extern_type*& to_next) const override
{
auto result = std::codecvt_base::noconv;
while (from < from_end && to < to_end)
{
if (getState(state).missingWhitespaces > 0u && *from != '\n')
{
while (getState(state).missingWhitespaces > 0u && to < to_end)
{
*to = ' ';
to++;
getState(state).missingWhitespaces--;
}
if (to < to_end)
{
result = std::codecvt_base::partial;
}
else
{
result = std::codecvt_base::partial;
break;
}
}
else
{
*to = *from;
if (*from == '\n')
{
getState(state).missingWhitespaces = tabSize * indentLevel;
}
to++;
from++;
}
}
from_next = from;
to_next = to;
return result;
};
狀態對象也正常工作。 問題只發生在函數調用之間。
編輯:將if (to < to_end)
后的結果更改為std::codecvt_base::ok
也不能解決問題。
經過更多挖掘,我找到了解決問題的方法。 我從這個網站得到了std::codecvt
的詳細解釋: http std::codecvt
原來,我忘了覆蓋這兩個方法:
virtual int do_length(state_type& state, const extern_type *from, const extern_type *end, size_t max) const;
確定並返回n
,其中n
是源范圍[from,end)
中extern_type
的元素數,這些元素可以轉換為intern_type
max
或更少字符,就像通過調用in(state, from, from_end, from_next, to, to_end, to_next)
其中to_end == to + max
。將 state 的值設置為對應於
from + n
開始的序列的移位狀態。必須在以下前提條件下調用函數
do_length
:
state
要么初始化為序列的開頭,要么等於序列上一次轉換的結果。
from <= end
定義明確且為真。請注意,此函數的行為與 C 標准庫函數
mbsrtowcs()
。 請參閱 mbsrtowcs.cpp 示例程序以了解使用 codecvt 方面的此函數的實現。
virtual int do_max_length() const throw();
返回
do_length()
可以為其前三個參數的任何有效組合返回的最大值,第四個參數max
設置為 1。
我以這種方式實現它們並且它起作用了:
virtual int do_length(state_type& state, const extern_type* from, const extern_type* end, size_t max) const override
{
auto numberOfCharsAbleToCopy = max;
numberOfCharsAbleToCopy -= std::min(static_cast<unsigned int>(numberOfCharsAbleToCopy), getState(state).missingWhitespaces);
bool newLineToAppend = false;
for (auto c = from + getState(state).missingWhitespaces; c < end && numberOfCharsAbleToCopy > 0u; c++)
{
if (*c == '\n' && !newLineToAppend)
{
newLineToAppend = true;
}
else if (*c != '\n' && newLineToAppend)
{
numberOfCharsAbleToCopy -= std::min(tabSize * indentLevel, numberOfCharsAbleToCopy);
if (numberOfCharsAbleToCopy == 0u)
{
break;
}
newLineToAppend = false;
}
}
return numberOfCharsAbleToCopy;
}
virtual int do_max_length() const throw() override
{
return tabSize * indentLevel;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.