import qualified Data.ByteString.Lazy.Char8 as BS
stuff <- BS.readFile "stuff.txt"
如何从bytestring中获取特定字符然后更改其ASCII然后将其放回? 我是否使用readInt?
Ex:“aaaaa”,“a”是97,所以减1并且你有“aa`aa”
答案 0 :(得分:2)
BS.map pred
怎么样?您还可以使用fromEnum
和toEnum
转换为Int
的转换。
答案 1 :(得分:2)
其他人已经解决了执行字节操作的问题,因此我将重点关注问题的另一半:选择并更新ByteString
内的特定字节。让我们从使用更熟悉的界面实现普通列表的操作开始:
onNth :: Int -> (a -> a) -> ([a] -> [a])
onNth n f xs = case splitAt n xs of
(beginning, x:ending) -> beginning ++ f x : ending
_ -> xs -- happens when n is out-of-bounds
您可以使用take
和drop
而不是splitAt
等效地实现此目的。现在,我们如何将其翻译为ByteString
s?好吧,ByteString
界面提供了take
,drop
,splitAt
,append
和cons
;我们唯一没有得到的是我们在上面的x:ending
部分中进行的模式匹配。幸运的是,ByteString
确实提供了类似的东西:
uncons :: ByteString -> Maybe (Word8, ByteString)
因此,使用它,我们可以编写一个适用于onNth
的新ByteString
函数:
second :: (b -> c) -> (a, b) -> (a, c)
second f (a, b) = (a, f b)
onNth :: Int -> (Word8 -> Word8) -> (ByteString -> ByteString)
onNth n f bs = case second uncons (splitAt n bs) of
(beginning, Just (x, ending)) -> append beginning (cons (f x) ending)
_ -> bs -- again, for out-of-bounds cases
最后,我们可以讨论我们应该使用哪个函数作为上面的f :: Word8 -> Word8
参数。虽然您在谈论上面的文字,但我会指出您不应该使用ByteString
作为文本(ByteString
s是字节序列,而不是Char
s的序列。因此,如果您选择使用ByteString
,则必须讨论字节而不是文本。 ; - )
因此,你真的想问一个将字节减少一个的函数,可能是在边界上缠绕。 subtract 1
是一个完全相同的功能,因此要将pack [97, 97, 97, 97, 97]
转换为pack [97, 97, 96, 97, 97]
,您可以编写onNth 2 (subtract 1)
。阅读几乎像英语!
答案 2 :(得分:1)
使用Char
将字节转换为BS.unpack
后,您可以使用fromEnum :: Char -> Int
(或等效地ord
来自Data.Char
)将Char
转换为其ASCII值,然后可以像普通整数一样进行操作。要将Int
的ASCII值转换回Char
,请使用toEnum
或Data.Char.chr
,然后可以将Char
转换回{ {1}} ByteString
或类似内容。