在C++中实现文本间隙后的奇怪行为
Strange Behavior After Implementing Text-Gap In C++
我试图实现一个文本间隙文本编辑器,乍一看似乎一切正常。但是,在看似随机的点,垃圾数据将进入混合。我已经包含了删除所有 GUI 和图形恶作剧的代码,只是在一个简单的 main 中实现了文本间隙类及其伙伴,并在使用 g++ main 运行时附加了控制台输出的日志.cpp-o main。
P.S. 文本间隙意味着将内存中的文本划分为至少两种数据结构,但将它们作为不间断的流呈现给用户,从而允许轻松插入/删除/光标语义。Essentiall stringA+stringB=whatusersees.因此,插入是前半部分的简单推回,删除键是后半部分的弹出式前置。向任一方向移动光标意味着简单地从一个方向弹出并向另一个方向推动。
.PPS。在我的多次运行中,垃圾数据在输入被推送时不会显示,无论是作为字符还是作为最终字符串。此外,错误似乎是随机发生的,有时只在几个字符之后,有时在很多字符之后。
购买力平价。我可以通过基本上使用 string-n-copy 函数来清理整组值来摆脱它,但除非我在 concatTextBlockRange 的前半部分运行它,否则这将不起作用。它相对昂贵,当我应该做的只是访问一个取消引用的迭代器,而不是访问一个取消引用的迭代器,然后计算它的一部分。
购买力平价。在concatTextBlockRange的前半部分之前没有垃圾数据,但是每当dataIter指向"污染"的字符位置时,它就会出现,该位置包含字符(h或g或其他)以及一堆难以理解的垃圾数据。后半部分似乎没有产生这种情况。生成是不可靠的,尽管如果您不断输入密钥,就会发生。
法典:
//test2.cpp
#include <iostream>
#include <string>
#include <list>
struct TextBlock{
std::list<char> data;
void assign( std::string inStr ) {
std::string::iterator myIter = inStr.begin();
std::string::iterator end = inStr.end();
while( myIter != end ) {
data.push_back( (*myIter) );
++myIter;
}
}
char pop_front( ) {
if( data.empty() == true ) { std::cout << "ERROR" << std::endl; return '#'; }
char toret = data.front();
data.pop_front();
return toret;
}
char pop_back( ) {
if( data.empty() == true ) { std::cout << "ERROR" << std::endl; return '?'; }
char toret = data.back();
data.pop_back();
return toret;
}
void push_front( char inChar ) { data.push_front( inChar ); }
void push_back( char inChar ) { data.push_back( inChar ); }
void backspace_key( ) { data.pop_back(); }
void delete_key( ) { data.pop_front(); }
int size( ) { return data.size(); }
bool empty( ) { return data.empty(); }
void PrintString( ) {
std::cout << ".:::PRINTING:::." << std::endl;
std::list<char>::iterator myIter = data.begin();
std::list<char>::iterator end = data.end();
while( myIter != end ) {
std::cout << (*myIter);
++myIter;
}
std::cout << std::endl;
}
};
std::string concatTextBlockRange( const TextBlock * const in1, const TextBlock * const in2, int backrange, int frontrange ) {
std::string toret;
std::list<char>::const_iterator dataIter1 = in1->data.end();
for( int i=0; i<backrange; i++ ) { --dataIter1; }
for( int i=0; i<backrange; i++ ) {
toret.append( &(*dataIter1) );
++dataIter1;
}
std::list<char>::const_iterator dataIter2 = in2->data.begin();
for( int i=0; i<frontrange; i++ ) {
toret.append( &(*dataIter2) );
++dataIter2;
}
return toret;
}
class Text{
public:
Text( std::string inFirst, std::string inSecond ) {
First.assign(inFirst);
Second.assign(inSecond);
}
void incGap( ) {
if( Second.empty() == false ) { First.push_back( Second.pop_front() ); }
}
void decGap( ) {
if( First.empty() == false ) { Second.push_front( First.pop_back() ); }
}
void incGap( int reps ) {
for( int i=0; i<reps; i++ ) { First.push_back( Second.pop_front() ); }
}
void decGap( int reps ) {
for( int i=0; i<reps; i++ ) { Second.push_front( First.pop_back() ); }
}
void insert( char inKey ) {
First.push_back( inKey );
}
void delete_key( ) {
Second.delete_key();
}
void backspace_key( ) {
First.backspace_key();
}
void space_key( ) {
insert(' ');
}
std::string retString( int backrange, int frontrange ) {
if( frontrange >= Second.size() ) { frontrange = Second.size(); }
if( backrange >= First.size() ) { backrange = First.size(); }
return concatTextBlockRange( &First, &Second, backrange, frontrange );
}
private:
TextBlock First, Second;
};
int main(){
Text myText( "The cat " , " because " );
char in;
bool tripped;
while( in != '`' ) {
std::cout << myText.retString(1000,1000) << std::endl;
tripped = false;
std::cin >> in;
if( in == ']' ) { myText.incGap(); tripped = true; }
if( in == '[' ) { myText.decGap(); tripped = true; }
if( in == '' ) { myText.backspace_key(); tripped = true; }
if( in == '-' ) { myText.delete_key(); tripped = true; }
if( in == '_' ) { myText.space_key(); tripped = true; }
if( tripped == false ) { myText.insert( in ); }
}
return 0;
}
安慰:
The cat because
qwer
The cat q because
The cat qw because
The cat qwe because
The cat qwer because
qwerttyyu
The cat qwerq because
The cat qwerqw because
The cat qwerqwe because
The cat qwerqwer because
The cat qwerqwert because
The cat qwerqwertt because
The cat qwerqwertty because
The cat qwerqwerttyy because
The cat qwerqwerttyyu because
yuiop
The cat qwerqwerttyyuy because
The cat qwerqwerttyyuyu because
The cat qwerqwerttyyuyui because
The cat qwerqwerttyyuyuio because
The cat qwerqwerttyyuyuiop because
sdfghj
The cat qwerqwerttyyuyuiops because
The cat qwerqwerttyyuyuiopsd because
The cat qwerqwerttyyuyuiopsdf because
The cat qwerqwerttyyuyuiopsdfg because
The cat qwerqwerttyyuyuiopsdfgh because
The cat qwerqwerttyyuyuiopsdfghj because
ertasfj
The cat qwerqwerttyyuyuiopsdfghje because
The cat qwerqwerttyyuyuiopsdfghjer because
The cat qwerqwerttyyuyuiopsdfghjert because
The cat qwerqwerttyyuyuiopsdfghjerta because
The cat qwerqwerttyyuyuiopsdfghjertas because
The cat qwerqwerttyyuyuiopsdfghjertasf because
The cat qwerqwerttyyuyuiopsdfghjertasfj because
dsrtjgf
The cat qwerqwerttyyuyuiopsdfghjertasfjd because
The cat qwerqwerttyyuyuiopsdfghjertasfjds because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsr because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrt because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtj because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjg because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgf because
dftjdgh
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfd because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdf because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdft because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftj because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjd because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdg because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdgh because
sfgkjsdfgj
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdghs because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdghsf because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdghsfg because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdghsfgk��� because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdghsfgk���j���fghj1 because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdghsfgk���j���fghj1s���` because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdghsfgk���j���fghj1s���`d��� because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdghsfgk���j���fghj1s���`d���f���` because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdghsfgk���j���fghj1s���`d���f���`g��� because
The cat qwerqwerttyyuyuiopsdfghjertasfjdsrtjgfdftjdghsfgk���j���fghj1s���`d���f���`g���j���` because
感谢您的阅读!
您使用了错误的string::append
重载,即append(const char *)
。 它期望一个NUL
终止的所谓"C"字符串作为参数,该字符串与从std::list<char>::const_iterator
返回的内容不兼容。
修复此错误的最短方法是通过编写toret.append(1, *dataiter1)
等调用另一个重载append(size_t, char)
。
- http://www.cplusplus.com/reference/string/string/append/
通过在 Valgrind 内存调试器下运行您的示例程序,我可以相对容易地发现此错误:
- http://valgrind.org/docs/manual/quick-start.html
仅供参考,您是否检查过我认为您可以替换自己的间隙缓冲区实现的__gnu_cxx::rope
?
- https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a00066.html
- 初始化派生结构的基部分/意外打包派生结构字段以对齐基结构的间隙
- C++堆栈中数组之间的间隙
- 如何在串行通信中插入间隙?
- CPLEX MIP提前终止,具有相对间隙,getBestObjValue与getObjValue
- 塞奇威克间隙序列公式的"i"是什么?
- 在C++中实现文本间隙后的奇怪行为
- WXWidgets Sizers在侧面留下一个间隙
- 是否保证 std::vector 不会在元素之间留下间隙
- 如何在使用cplex解决问题时设置间隙
- 使用cocos2d制作间隙广告
- 在已编译的可执行文件的.text部分中增加或指定间隙,以手动添加程序集代码
- 阵列最大间隙的计算
- cocos2d-x ResolutionPolicy::SHOW_ALL显示漂亮的图像,而不是黑色的间隙
- 在C++中检查结构是否对齐或包含间隙
- 间隙插入排序实现