```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 ``` ```-- Author Mohit Jain {- == Problem statement == Implement a simplified version of scanf. == INPUT == 2 strings as command line arguments. String 1: Format string String 2: Data string == OUTPUT == \$./myscanf %3d%2x%5s 123ffHello dec integer: 123, hex integer: 255, char string: Hello \$ == Other Samples == - %2d 10 - dec integer: 10 - %2x 10 - dec integer: 16 - %2s 10 - char string: 10 == Rules == 1. [input 1] First argument specifies the scan pattern. - Length of scan pattern is always 3n (0 < n <= 10) - Character at index 3m (0 < m < n) is always '%' - Character at index 3m + 1 (0 < m < n) is always in range ['1' - '9'] specifying length of data. - Character at index 3m + 2 (0 < m < n) is always ['d', 'x', 's'] specifying scan pattern. - Format specifier ['d', 'x', 's'] are always lowercase. 2. [input 2] Second argument specified the input data. - Length of input data is less than 100 bytes. - input data contains only ['a'-'z', 'A'-'Z', '0'-'9', , ] 3. [output] For every scan pattern read the data and print. - d: print string "dec integer: " followed by decimal and hex representation of scanned number. - x: print string "hex integer: " followed by decimal and hex representation of scanned number. - s: print string "char string: " followed by the scanned string. 4. Length of second argument is equal to the sum of format lengths. -} module Main where import List import Char main = putStrLn \$ similarScanf "%2d%5s%3x" "12Hello100" similarScanf :: String -> String -> String -- This function reads the format string and data string -- And scans data string based on format string similarScanf [] _ = "" similarScanf format dataStr = init \$ init \$ similarScanfHelper format dataStr -- I used init twice in above line of code because, output of similarScanfHelper -- is a string. similarScanfHelper recursively appends the result and adds separator ", " -- after each result formatted text. Calling init twice removes last two separator characters -- [FIXME]:: similarScanfHelper should return [String] and intercalate "," or -- concatenate \$ intersperse ", " should be used. similarScanfHelper ::String -> String -> String -- This function parses the format string and unformatted data string -- And returns the formatted data string similarScanfHelper [] _ = "" similarScanfHelper f d = outList where -- Example: f = "%3d%2s", d = "213ab" sizeOfData = digitToInt (f!!1) -- Example: sizeOfData = 3 typeOfData = (f!!2) -- Example: typeOfData = 'd' unformattedData = take sizeOfData d -- Example: unformattedData = "213" remainingFormat = drop 3 f -- Example: remainingFormat = "%2s" remainingData = drop sizeOfData d -- Example: remainingData = "ab" outList = formattedData ++ ", " ++ similarScanfHelper remainingFormat remainingData formattedData = case typeOfData of 's' -> "Char string: " ++ unformattedData --'d' -> show \$ read unformattedData 'd' -> "Decimal integer: " ++ unformattedData 'x' -> "Hex integer: " ++ (show \$ readMyHex unformattedData) readMyHex ::[Char] -> Int -- Returns the integer equivalent of input hex string -- Test input: "100" -- Test output: 256 readMyHex [] = 0 readMyHex x = (digitToInt \$ last x) + 16 * (readMyHex \$ init x) ```
 ```1 ``` ```Decimal integer: 12, Char string: Hello, Hex integer: 256 ```