[ create a new paste ] login | about

Link: http://codepad.org/xAKkH2Kc    [ raw code | output | fork ]

mohit_at_codepad - Haskell, pasted on Mar 12:
-- 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', <space>, <comma>]
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)


Output:
1
Decimal integer: 12, Char string: Hello, Hex integer: 256


Create a new paste based on this one


Comments: