【发布时间】:2015-02-28 16:42:44
【问题描述】:
我正在维护一个大型开源项目,因此在 I/O 方面遇到了一个奇怪的边缘案例。
当我的应用解析包含如下文本行的用户参数文件时:
CH3 CH2 CH2 CH2 −68.189775 2 180.0 ! TraPPE 1
...起初它看起来很无辜,因为它是根据需要格式化的。但后来我看到减号是 UTF 字符 (−) 而不是 (-)。
我只是将STL 的>> 与ifstream 对象一起使用。
当它尝试转换为负数并在 UTF 字符上失败时,显然只是将内部标志设置为“坏”,这触发了我停止读取过程的逻辑。这有点好,因为如果没有这种逻辑,我会更难追踪它。
但这绝对不是我想要的错误处理。我想在用>> 读取double 时捕获常见的减号,如果字符串是格式正确的负数,则替换它们并完成转换。
我的用户似乎相对频繁地发生这种情况,因为他们从程序(可能是 Windows 中的计算器或 Excel?)复制和粘贴以获取他们的文件值。
我有点惊讶没有在 Stack Overflow 上发现这个问题,因为它似乎无处不在。我在这个问题上找到了一些参考:
c++ error cannot be used as a function, some stray error [closed]
...但这是一个稍微不同的问题,其中代码包含那种相似但不兼容的“负号”EN DASH UTF 字符。
有没有人有一个好的解决方案(最好是紧凑、便携和可重复使用)来在读取双精度数或有符号整数时捕捉这些坏缺点?
注意:
我不想使用 Boost 或 c++11,信不信由你,我在某些超级计算机上的某些用户无权访问这些库。我尽量保持它的便携性。
【问题讨论】:
-
将每一行一次读入一个字符串,应用任何修复,然后分割字符串(使用
stringstream、regex或其他任何有效的方法)。 -
当然,但这很不具体...我已经知道我可以将它读到
string,然后使用替换该字符的代码...fileformat.info/info/unicode/char/2013/index.htm ...也许使用包装器来包装 ifstream 来捕捉这种情况?无论如何,我想看看是否有人有实际的代码来处理这个......你的回答,很感激,但它基本上就是我所在的地方。我把它放在这里是希望有些人已经解决了这个问题并有一个最佳实践/便携/紧凑的解决方案。 -
您粘贴到问题中的字符不是 u+2013,而是 u+2212。您可能需要针对多种可能性进行编码。
-
另外,C++11 不是库。无论如何,您都可以简单地静态链接所需的库并将它们与您的应用程序一起发布。不过在这里不会有任何区别。
-
P.S.如果您正在寻找有类似问题的其他人,请搜索“智能引号”。