问题描述
编译我在 dlang 中编写的代码时出现一个神秘错误,它显示
“从字符串类型转换为 int 类型时出现意外的 '\n'”
我在 google 上查了一下,但没有找到解决方案(因为 d 不是一种流行的编程语言)。
这是我写的代码-
import std.stdio;
import std.conv;
void main()
{
string a = readln();
auto b = to!int(a);
}
这是产生的完整错误-
std.conv.ConvException@/usr/include/dmd/phobos/std/conv.d(1947): Unexpected '\n' when converting from type string to type int
----------------
/usr/include/dmd/phobos/std/conv.d:85 pure @safe int std.conv.toImpl!(int,immutable(char)[]).toImpl(immutable(char)[]) [0x562507a98a0f]
/usr/include/dmd/phobos/std/conv.d:223 pure @safe int std.conv.to!(int).to!(immutable(char)[]).to(immutable(char)[]) [0x562507a9760f]
source/app.d:11 _Dmain [0x562507a95d34]
Program exited with code 1
解决方法
问题在于 readln()
返回用户输入包括行终止换行符(\n
、\r\n
或 \r
或可能更奇特的)并且 std.conv to
函数在发现意外空白时抛出。您可以简单地取一个不包括最后一个字节的切片,但是当输入结束时没有换行符(即从文件读取或按 Ctrl-D 时的文件结尾)作为用户)它不会包含终止换行符并给你错误的数据。
要清理它,您可以使用 CircuitCoder 的回答中提到的 replace
,但是标准库为此用例提供了更快/更有效(无分配)的方法:chomp
(1):
import std.string : chomp;
string a = readln().chomp; // removes trailing new-line only
int b = a.to!int;
chomp
始终只删除一个尾随换行符。 (字符 = 在 \r\n
的情况下可能是多个字节)因为 D 中的字符串只是数组 - 即 ptr
+ length
- 这意味着 chomp
可以有效地给你另一个长度递减 1 的实例,这意味着堆上没有内存分配或复制整个字符串,因此您将避免程序后期潜在的 GC 清理,这在您阅读大量行时特别有用。
或者,如果您不关心用户提供给您的精确输入,而是希望从输入的开头和结尾完全删除空格(包括换行符),您可以使用 strip
(2):
import std.string : strip;
string a = readln().strip; // user can now enter spaces at start and end
int b = a.to!int;
总的来说,这两个函数对于您正在执行和想要清理的所有用户输入都很有用。
,https://dlang.org/phobos/std_array.html#.replace
导入 std.string
并使用 readln().replace(“\n”,“”);
而不仅仅是 readln()
。这个错误真的没有那么神秘。