what's the best way to hardcode a multiple-line string?

10,679

Solution 1

I think there is no problem with using StringBuilder in F# as you did.

There is a function fprintfn in Printf module, so you can use it with a StringWriter object:

let sw = new StringWriter()
fprintfn sw "myline1"
fprintfn sw "myline2"
fprintfn sw "myline3"
sw.ToString()

I like fprintf and fprintfn since they are flexible. You can write to console output by supplying stdout instead.

Solution 2

Little known feature: you can indeed indent string content - by ending each line with a backslash. Leading spaces on the following line are stripped:

let poem = "The lesser world was daubed\n\
            By a colorist of modest skill\n\
            A master limned you in the finest inks\n\
            And with a fresh-cut quill.\n"

You will still need to include \n or \n\r at line ends though (as done in the example above), if you want these embedded in your final string.

Edit to answer @MiloDCs question:

To use with sprintf:

let buildPoem character =
    sprintf "The lesser world was daubed\n\
             By a colorist of modest skill\n\
             A master limned %s in the finest inks\n\
             And with a fresh-cut quill.\n" character

buildPoem "you"            
buildPoem "her"
buildPoem "him"

Solution 3

If you are under F# 3.0, triple-quoted strings may be the answer:

let x = """
myline1
myline2
myline3"""   

Solution 4

I'm surprised nobody has mentioned this:

[ "My first line"
  "second line"
  "another line" ]
|> String.concat "\n"

Solution 5

You can create directly multi-line string literals in F#:

let multiLineStr = 
  "myline1
myline2
myline3"

and C#:

var multiLineStr =
  @"myline1
myline2
myline3";
Share:
10,679
colinfang
Author by

colinfang

Updated on June 02, 2022

Comments

  • colinfang
    colinfang almost 2 years

    In unit test I would like to hard code a block of lines as a string.

    In C# I would do

    var sb = new StringBuilder();
    sb.AppendLine("myline1");
    sb.AppendLine("myline2");
    sb.AppendLine("myline3");
    

    Since I converted to F# I tried to minimize the usage of .Net method by using bprintf instead, but somehow there is no bprintfn support which seems strange to me.

    It is tedious to add \r\n at the end of each line manually.

    Or is there any better way than StringBuilder?

  • MiMo
    MiMo over 11 years
    I think this gives myline1myline2myline3 - without the end lines
  • colinfang
    colinfang over 11 years
    One drawback of this is, that you cannot indent the string content which looks bad.
  • Thorkil Holm-Jacobsen
    Thorkil Holm-Jacobsen over 11 years
    Wow, did NOT know that! +1
  • Onorio Catenacci
    Onorio Catenacci over 11 years
    Good tip @Kit--that's a new one to me too.
  • colinfang
    colinfang over 11 years
    it is basically the same as @jellyfish 's method, but looks extremely useful under such formatting.
  • knocte
    knocte about 10 years
    I don't like this approach because I guess it wouldn't use the platform-agnostic Environment.NewLine
  • Michelrandahl
    Michelrandahl over 7 years
    this is IMO how triple quotes should have worked. If you want to write pretty code with triple quotes as it is now it just screws up the indentation.
  • MiloDC
    MiloDC almost 4 years
    How to do this with sprintf?
  • Kit
    Kit almost 4 years
    @MiloDC Edited to answer your question. ;-)
  • Aisah Hamzah
    Aisah Hamzah almost 4 years
    The @ prefix can also be used in F#.
  • Pac0
    Pac0 over 3 years
    With sprintf, I get an error when using formatters. sprintf "foo %s bar,\n\ then on the other line: foobar %s\n." "a" "b" (with indentation) is getting me expecting a string -> a -> b but given a string -> string. EDIT : wait, it compiles and work fine! The error is only in Visual Studio editor! Looks like a VS bug.
  • Pac0
    Pac0 over 3 years
    caveat with that approach is that you must "clip" the string lines at the beginning of line, otherwise the indentation spaces will be taken into the string. It looks a bit ugly when you have indented code,