在不使用专用计数器的情况下检查 QTextStream 读取的总行数
Posted
技术标签:
【中文标题】在不使用专用计数器的情况下检查 QTextStream 读取的总行数【英文标题】:Checking total lines read by QTextStream without using a dedicated counter 【发布时间】:2017-11-16 04:37:42 【问题描述】:我目前正在编写用于解析行数未知的文件的代码。格式大致是这样的:
ShapeId: 1
ShapeType: Line
ShapeDimensions: 20, 90, 100, 20
PenColor: blue
PenWidth: 2
PenStyle: DashDotLine
PenCapStyle: FlatCap
PenJoinStyle: MiterJoin
// and so on and so forth; formats vary slightly depending on the entry
作为一个文本文件,显然我们需要检查错误。目前,我通过抛出带有(相当)信息性消息的异常来做到这一点。
但是,我的异常消息不能太具体,因为我的许多帮助解析文件的函数都过于通用而无法包含特定消息。考虑到台词的多样性,为每种台词定制信息是不切实际的。
正如我在标题中提到的,我使用的是QTextStream。我正在使用readLine 读取每一行,然后用该行做一些事情。我还使用skipWhiteSpace 来跳过数据块之间的间隙。
我希望QTextStream 会提供此功能,但事实并非如此。我能找到的最接近的是pos。这总比没有好,但它几乎没有行号那么有用。
我可以在遍历每一行时添加一个整数计数器来进行计数。但是,这在我的程序的上下文中是不切实际的,我有许多可以读取行的辅助函数。另外,skipWhiteSpace 可以跳过多行,所以如果我手动计数,我就无法使用它。
很遗憾,我还没有找到好的解决方案。最接近的是this 之类的东西,但这是假设我们已经在一个简单的循环中单步执行文件,一次一行。同样,在这种情况下这太不切实际了。
所以...我想我的问题是:有没有一种优雅的方法来检查 QTextStream 指向的行号而不依赖任何以前的代码?我错过了什么明显的东西吗?
(我宁愿避免使用 Qt 以外的库和基本的 C++ 库。)
【问题讨论】:
【参考方案1】:我认为答案是否定的。如果您查看QTextStreamPrivate,则没有包含行数的成员字段。类本身不需要它。
您还可以查看用于读取行的scan()
方法以获取提示。
【讨论】:
【参考方案2】:只是一个想法:如果您可以使用QTextStream::pos()
函数获取当前位置,则可以通过读取该位置之前的整个文本并计算该字符串中的换行符来计算行号。比如:
qint64 currentPos = stream.pos();
QString str = stream.read(currentPos);
int lineNum = str.count(QRegExp("\\r\\n?|\\n")) + 1;
这可能很慢,但是您只需要用于错误报告的行号,因此调用一次就可以了。
【讨论】:
这工作得很好,除了我需要 1) 将流重置到开头(使用stream.seek(0)
),以及 2) 不要在最后一行添加一个。 (我认为这在某些操作系统上可能是必需的。)否则,它符合我的需要并且是一个优雅的解决方案。谢谢!【参考方案3】:
您可以将QTextStream
包装在可以计算行数的内容中。
class StreamWithLineCount
QTextStream stream;
int lineCount;
public:
QString readLine(qint64 maxlen = 0)
++lineCount;
return stream.readLine(maxLen);
void skipWhitespace()
qint64 pos = stream.pos();
while (!stream.atEnd() && readLine().simplified().isEmpty())
pos = stream.pos();
seek(pos);
【讨论】:
以上是关于在不使用专用计数器的情况下检查 QTextStream 读取的总行数的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 fql 的情况下获取帖子 URL 的 Facebook 点赞、分享和评论计数?
如何在不使用临时表的情况下检索当前行和先前行的值之间的值差异?