View source code
Display the source code in std/csv.d from which this page was generated on github.
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.

Function std.csv.csvReader

Returns an input range for iterating over records found in input.

auto csvReader(Contents, Malformed ErrorLevel = Malformed.throwException, Range, Separator) (
  Range input,
  Separator delimiter = ',',
  Separator quote = '"',
  bool allowInconsistentDelimiterCount = false
)
if (isInputRange!Range && is(immutable(ElementType!Range) == immutable(dchar)) && isSomeChar!Separator && !is(Contents T : T[U], U : string));

auto csvReader(Contents, Malformed ErrorLevel = Malformed.throwException, Range, Header, Separator) (
  Range input,
  Header header,
  Separator delimiter = ',',
  Separator quote = '"',
  bool allowInconsistentDelimiterCount = false
)
if (isInputRange!Range && is(immutable(ElementType!Range) == immutable(dchar)) && isSomeChar!Separator && isForwardRange!Header && isSomeString!(ElementType!Header));

auto csvReader(Contents, Malformed ErrorLevel = Malformed.throwException, Range, Header, Separator) (
  Range input,
  Header header,
  Separator delimiter = ',',
  Separator quote = '"',
  bool allowInconsistentDelimiterCount = false
)
if (isInputRange!Range && is(immutable(ElementType!Range) == immutable(dchar)) && isSomeChar!Separator && is(Header : typeof(null)));

An optional header can be provided. The first record will be read in as the header. If Contents is a struct then the header provided is expected to correspond to the fields in the struct. When Contents is not a type which can contain the entire record, the header must be provided in the same order as the input or an exception is thrown.

Returns

An input range R as defined by isInputRange. When Contents is a struct, class, or an associative array, the element type of R is Contents, otherwise the element type of R is itself a range with element type Contents.

If a header argument is provided, the returned range provides a header field for accessing the header from the input in array form.

Throws

CSVException When a quote is found in an unquoted field, data continues after a closing quote, the quoted field was not closed before data was empty, a conversion failed, or when the row's length does not match the previous length.

HeaderMismatchException when a header is provided but a matching column is not found or the order did not match that found in the input. Read the exception documentation for specific details of when the exception is thrown for different types of Contents.

Example

The Contents of the input can be provided if all the records are the same type such as all integer data:

import std.algorithm.comparison : equal;
string text = "76,26,22";
auto records = text.csvReader!int;
assert(records.equal!equal([
    [76, 26, 22],
]));

Example

Using a struct with modified delimiter:

import std.algorithm.comparison : equal;
string text = "Hello;65;2.5\nWorld;123;7.5";
struct Layout
{
    string name;
    int value;
    double other;
}

auto records = text.csvReader!Layout(';');
assert(records.equal([
    Layout("Hello", 65, 2.5),
    Layout("World", 123, 7.5),
]));

Example

Specifying ErrorLevel as Malformed.ignore will lift restrictions on the format. This example shows that an exception is not thrown when finding a quote in a field not quoted.

string text = "A \" is now part of the data";
auto records = text.csvReader!(string, Malformed.ignore);
auto record = records.front;

writeln(record.front); // text

Example

Read only column "b"

import std.algorithm.comparison : equal;
string text = "a,b,c\nHello,65,63.63\nWorld,123,3673.562";
auto records = text.csvReader!int(["b"]);

assert(records.equal!equal([
    [65],
    [123],
]));

Example

Read while rearranging the columns by specifying a header with a different order"

import std.algorithm.comparison : equal;
string text = "a,b,c\nHello,65,2.5\nWorld,123,7.5";
struct Layout
{
    int value;
    double other;
    string name;
}

auto records = text.csvReader!Layout(["b","c","a"]);
assert(records.equal([
    Layout(65, 2.5, "Hello"),
    Layout(123, 7.5, "World")
]));

Example

The header can also be left empty if the input contains a header row and all columns should be iterated. The header from the input can always be accessed from the header field.

string text = "a,b,c\nHello,65,63.63";
auto records = text.csvReader(null);

writeln(records.header); // ["a", "b", "c"]

Example

Handcrafted csv files tend to have an variable amount of columns.

By default std.csv will throw if the number of columns on a line is unequal to the number of columns of the first line. To allow, or disallow, a variable amount of columns a bool can be passed to all overloads of the csvReader function as shown below.

import std.algorithm.comparison : equal;

string text = "76,26,22\n1,2\n3,4,5,6";
auto records = text.csvReader!int(',', '"', true);

assert(records.equal!equal([
    [76, 26, 22],
    [1, 2],
    [3, 4, 5, 6]
]));

Example

ditto

import std.algorithm.comparison : equal;

static struct Three
{
    int a;
    int b;
    int c;
}

string text = "76,26,22\n1,2\n3,4,5,6";
auto records = text.csvReader!Three(',', '"', true);

assert(records.equal([
    Three(76, 26, 22),
    Three(1, 2, 0),
    Three(3, 4, 5)
]));

Example

ditto

import std.algorithm.comparison : equal;

auto text = "Name,Occupation,Salary\r" ~
    "Joe,Carpenter,300000\nFred,Blacksmith\r\n";

auto r = csvReader!(string[string])(text, null, ',', '"', true);

assert(r.equal([
    [ "Name" : "Joe", "Occupation" : "Carpenter", "Salary" : "300000" ],
    [ "Name" : "Fred", "Occupation" : "Blacksmith" ]
]));

Authors

Jesse Phillips

License

Boost License 1.0.