从字符串类型转换为 int 类型同时将用户输入从字符串转换为 int 时出现意外的 '\n'

问题描述

编译我在 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()。这个错误真的没有那么神秘。