在将用户输入从字符串转换为 int 时,从类型字符串转换为类型 int 时出现意外的“\n”

Unexpected '\n' when converting from type string to type int while converting user input to int from string

当我编译我在 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

https://dlang.org/phobos/std_array.html#.replace 导入 std.string 并使用 readln().replace("\n", ""); 而不仅仅是 readln()。那个错误真的没有那么神秘。

问题是 readln() returns 用户输入 包括 行终止换行符 (\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 可以有效地给你另一个长度减一的实例,这意味着堆上没有内存分配或复制整个字符串,因此您将避免稍后在程序中进行潜在的 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;

一般来说,这两个函数对于您正在执行并希望清理的所有用户输入都很有用。