【问题标题】:C++ append string pointerC++ 追加字符串指针
【发布时间】:2012-04-19 14:51:38
【问题描述】:

当我将 Iterator 附加到字符串时,我遇到了一些意外的字符串行为。基本上,我有一个文件可以读取以下内容:

int x := 10;
print x;

我已经有一个包含此文件内容的字符串,我正在遍历它并立即删除空格。

void Lexer::parse()
{
    Pointer = Filestring.begin(); // both private members
    while(Pointer < Filestring.end())
    {
        if(is_whitespace(0)) // 0 indicates current Pointer position
        {
            advance(Pointer, 1);
            continue;
        }

        CurToken.append(&*Pointer); // CurToken is private member string
        advance(Pointer, 1);
    }

    cout << CurToken << endl;
}

在循环结束时,我希望 CurToken 是一个字符串,它只包含删除了所有空格的字符。相反,我得到如下内容:

int x := 1 + 2;
print x;



nt x := 1 + 2;
print x;



t x := 1 + 2;
print x;

...

rint x;



int x;



nt x;



t x;



x;



;

我认为问题是取消引用指针,如果是这样,我如何附加当前指针位置的字符?如果我不取消引用它,我最终会得到invalid conversion from ‘char’ to ‘const char*’

注意: is_whitespace() 我已经测试过,并且可以按预期工作。因此可以排除可能的问题。

【问题讨论】:

  • 你为什么不写it 而不是Pointer 而写++it 而不是advance(Pointer,1)?另外,为什么不用std::isspace(*it) 而不是is_whitespace(0)?你不必要地让它变得复杂。
  • 指针是一个字符串迭代器 *
  • *Pointer 返回什么?为什么不能用指针代替 &*Pointer?看起来您可能会在每次循环时附加整个令牌的其余部分 - 而不仅仅是一个字符。
  • 正确处理空白。
  • 你为什么要为此编写所有这些复杂的非标准代码?在空白处标记文件就像fstream f("file.txt"); string s; while(f &gt;&gt; s) cout &lt;&lt; s &lt;&lt; endl; 一样简单

标签: c++ string pointers iterator


【解决方案1】:
CurToken.append(&*Pointer);

假设Pointer是一个指针,就相当于

CurToken.append(Pointer);

并将字符串的整个尾部附加到CurToken(假设它指向一个C风格的以零结尾的字符串;如果没有终止符,那么任何事情都可能发生)。看起来您只想附加当前字符:

CurToken.append(*Pointer);

更新:你说Pointerstd::string::iterator。在这种情况下,&amp;*Pointer 仍然是指向字符的指针; append 仍会将其解释为指向 C 样式字符串的指针。由于字符串中的字符不一定会终止(尽管实际上它们几乎肯定会终止,尤其是在 C++11 库中),因此您的行为未定义。

【讨论】:

  • 我会假设Pointer 是一个自制的智能指针。
  • 它的string::iterator Pointer;
  • @MarkB:也许;相当复杂的一个,因为您可以对其进行算术运算。即便如此,&amp;* 的效果与普通指针一样。
  • @Headspin:好的,这将具有与指针相同的效果,但具有额外的未定义行为。您仍然希望 *Pointer 仅获取当前字符。
【解决方案2】:

CurTokenPointer 的类型是什么? CurToken 看起来像 std::stringPointerstd::string* 吗? append 有很多重载。其中之一是:

string& append ( const string& str );

如果你想点击那个,你应该去掉'&',只给你取消引用的指针:

CurToken.append(*Pointer);

应该可以,但请记住,它会附加整个字符串,而不仅仅是字符。如果不是,您可能需要确定append() 的哪个过载。如果您只想要第一个字符,请尝试:

CurToken.append(1, (*Pointer)[0]); 

【讨论】:

  • 完美。我想你最了解我在这里想要完成的事情,尽管我不得不使用CurToken.append(1, (Pointer)[0]);
猜你喜欢
  • 2011-08-24
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
相关资源
最近更新 更多