OpenBI Docs Buy

Reading and writing files

Reading and writing graphs as edge lists and in the NCOL, LGL, GraphML, GML, Pajek, DIMACS, graph database, DL, DOT and LEDA formats.

20 entries: 20 functions. Part of the Open Graph reference; All functions lists every entry on one page, with a filter. The badges say how each entry is checked.

Edge lists, NCOL and LGL

read_graph_edgelist#

Exact

Builds a graph from a text stream of whitespace-separated vertex id pairs.

og_error_t og_read_graph_edgelist(
    og_t *graph,
    FILE *instream,
    og_int_t n,
    og_bool_t directed
);

The stream is read as a sequence of decimal integers separated by any whitespace; line breaks have no special meaning. Each consecutive pair (from, to) becomes one edge, in file order, so edge ids follow the order of the pairs. Vertex ids are 0-based.

The graph gets max(n, largest id + 1) vertices: n only adds isolated vertices at the end, and an id at or above n is not an error. Self-loops and repeated pairs are kept as they are. No attributes are created.

Parameters
  • graph An uninitialised graph. On success it holds the result; destroy it with destroy.
  • instream An open stream; it is read to its end. NULL is OG_EINVAL.
  • n The smallest number of vertices the graph gets; 0 lets the largest id decide. Must not be negative.
  • directed OG_DIRECTED or OG_UNDIRECTED: the direction of the new graph (the file does not record it).
Returns
OG_SUCCESS, or one of the error codes below. On error no graph is left initialised.
Errors
  • OG_EINVAL n is negative, or instream is NULL.
  • OG_PARSEERROR An odd number of ids (the last edge is incomplete), or a token that is not a decimal integer (hex, letters, a decimal point).
  • OG_EINVVID A vertex id is negative.
  • OG_EOVERFLOW A number is too large to represent.
  • OG_EUNDERFLOW A number is too small (too negative, or a real that rounds to zero or minus infinity).
  • OG_EFILE Reading the input stream fails.
  • OG_ENOMEM Not enough memory.
Complexity
O(|V| + |E|), linear in the size of the stream.
Checked
Same graphs and the same error codes as python-igraph 1.0 on 282 reads (hand-written texts with signs, hex, overflow and NUL bytes; files python-igraph wrote, half of them mutated) and 220 round trips of graphs with 0 to 300 vertices.
C name
og_read_graph_edgelist
In notebooks
Og.ReadGraphEdgelist
igraph 1.0
igraph_read_graph_edgelist
See also
write_graph_edgelist, read_graph_ncol, read_graph_graphdb
FILE *f = fopen("edges.txt", "r");
og_t g;
if (f != NULL && og_read_graph_edgelist(&g, f, 0, OG_UNDIRECTED) == OG_SUCCESS) {
    printf("%" OG_PRId " vertices, %" OG_PRId " edges\n", og_vcount(&g), og_ecount(&g));
    og_destroy(&g);
}
if (f != NULL) {
    fclose(f);
}

write_graph_edgelist#

Exact

Writes every edge as one line holding the two vertex ids.

og_error_t og_write_graph_edgelist(const og_t *graph, FILE *outstream);

Each edge becomes a line "from to" with 0-based vertex ids. Lines are grouped by the first vertex in increasing order and, for each vertex, sorted by the other end; an undirected edge is written smaller id first. Attributes are not written.

The format carries no vertex count, so isolated vertices with the largest ids are lost when the file is read back with read_graph_edgelist, unless the reader is given n.

Parameters
  • graph The graph to write.
  • outstream An open stream to write to.
Returns
OG_SUCCESS, or one of the error codes below.
Errors
  • OG_EFILE The output stream refuses data (a write fails).
Complexity
O(|V| + |E|).
Checked
Byte-identical to python-igraph 1.0's output on 200 random graphs and 220 graphs of 0 to 300 vertices.
C name
og_write_graph_edgelist
In notebooks
Og.WriteGraphEdgelist
igraph 1.0
igraph_write_graph_edgelist
See also
read_graph_edgelist, write_graph_ncol

read_graph_ncol#

Exact

Reads a named edge list in the NCOL format of the LGL package: one "name name [weight]" line per edge.

og_error_t og_read_graph_ncol(
    og_t *graph,
    FILE *instream,
    const og_strvector_t *predefnames,
    og_bool_t names,
    og_add_weights_t weights,
    og_bool_t directed
);

Each non-empty line holds two vertex names and an optional weight, separated by spaces or tabs. A name is any run of printable bytes without blanks, compared case-sensitively. Vertices get ids in the order their names first appear, after the names in predefnames, which take ids 0, 1, ... in their given order (so known vertices can be given fixed ids). Edges follow the line order. CR, LF, CR LF and LF CR all end a line; other control characters are an error.

With names true the names are stored as the string vertex attribute "name". weights decides about the numeric edge attribute "weight": OG_ADD_WEIGHTS_NO never makes it, OG_ADD_WEIGHTS_YES always, OG_ADD_WEIGHTS_IF_PRESENT only when at least one line has a weight; edges without a weight get 1. Attributes are stored only when an attribute handler is installed (set_attribute_table(&og_cattribute_table)); without one the structure is read and attribute data is dropped.

Weights are parsed with the C library (strtod), which follows the numeric locale: see enter_safelocale.

Parameters
  • graph An uninitialised graph. On success it holds the result; destroy it with destroy.
  • instream An open stream; it is read to its end. NULL is OG_EINVAL.
  • predefnames Names that take the first vertex ids, in order, or NULL. A name met in the file reuses its predefined id.
  • names Whether to store the vertex names as the "name" attribute.
  • weights OG_ADD_WEIGHTS_NO, OG_ADD_WEIGHTS_YES or OG_ADD_WEIGHTS_IF_PRESENT (enum og_add_weights_t).
  • directed OG_DIRECTED or OG_UNDIRECTED: the direction of the new graph (the file does not record it).
Returns
OG_SUCCESS, or one of the error codes below. On error no graph is left initialised.
Errors
  • OG_EINVAL weights is not one of the three og_add_weights_t values, or instream is NULL.
  • OG_PARSEERROR A line with only one name, text after the weight, a weight that is not a number, or a control character.
  • OG_EOVERFLOW A number is too large to represent.
  • OG_EUNDERFLOW A number is too small (too negative, or a real that rounds to zero or minus infinity).
  • OG_EFILE Reading the input stream fails.
  • OG_ENOMEM Not enough memory.
Complexity
O(|V| + |E|) expected (names are looked up in a hash table), linear in the size of the stream.
Checked
Same graphs, names, weights and error codes as python-igraph 1.0 on 396 reads under every names/weights/directed combination. python-igraph cannot pass predefnames, so that argument is covered by unit tests only.
C name
og_read_graph_ncol
In notebooks
Og.ReadGraphNcol
igraph 1.0
igraph_read_graph_ncol
See also
write_graph_ncol, read_graph_lgl, read_graph_edgelist, enter_safelocale

write_graph_ncol#

Exact

Writes the edges as "name name [weight]" lines in the NCOL format.

og_error_t og_write_graph_ncol(
    const og_t *graph,
    FILE *outstream,
    const char *names,
    const char *weights
);

One line per edge, in edge id order; an undirected edge is written smaller id first. When names gives a string vertex attribute, both ends are written by that attribute, otherwise by vertex id. When weights gives a numeric edge attribute, its value follows (15 significant digits; Inf, -Inf and NaN spelled out). An attribute that is missing or of the wrong type gives a warning and is left out.

NCOL has no place for vertices without edges, so they are not written. A written name must be non-empty printable ASCII without blanks; any other name makes the call fail, because the file could not be read back.

Parameters
  • graph The graph to write.
  • outstream An open stream to write to.
  • names Name of the string vertex attribute to write instead of ids, or NULL for ids.
  • weights Name of the numeric edge attribute to write as weights, or NULL for none.
Returns
OG_SUCCESS, or one of the error codes below.
Errors
  • OG_EINVAL A vertex with edges has an empty name, or one with a blank, a control byte or a non-ASCII byte.
  • OG_EFILE The output stream refuses data (a write fails).
  • OG_ENOMEM Not enough memory.
Complexity
O(|V| + |E|).
Checked
Byte-identical to python-igraph 1.0 on 167 writes (names and weights present, missing or of the wrong type, names it refuses) and 220 graphs of 0 to 300 vertices.
C name
og_write_graph_ncol
In notebooks
Og.WriteGraphNcol
igraph 1.0
igraph_write_graph_ncol
See also
read_graph_ncol, write_graph_lgl, write_graph_edgelist

read_graph_lgl#

Exact

Reads the LGL format, where a "# name" line opens a block that lists that vertex's neighbours.

og_error_t og_read_graph_lgl(
    og_t *graph,
    FILE *instream,
    og_bool_t names,
    og_add_weights_t weights,
    og_bool_t directed
);

A line "# name" makes name the current vertex; every following line "name [weight]" adds an edge from the current vertex to that neighbour, in file order. An empty line ends the block, and an edge line outside a block is an error. A "#" line with nothing after it still creates its vertex, which is how LGL files keep isolated vertices.

Names, vertex ids in order of first appearance, line endings and the names and weights switches work as in read_graph_ncol, producing the same "name" and "weight" attributes. Attributes are stored only when an attribute handler is installed (set_attribute_table(&og_cattribute_table)); without one the structure is read and attribute data is dropped.

Parameters
  • graph An uninitialised graph. On success it holds the result; destroy it with destroy.
  • instream An open stream; it is read to its end. NULL is OG_EINVAL.
  • names Whether to store the vertex names as the "name" attribute.
  • weights OG_ADD_WEIGHTS_NO, OG_ADD_WEIGHTS_YES or OG_ADD_WEIGHTS_IF_PRESENT (enum og_add_weights_t).
  • directed OG_DIRECTED or OG_UNDIRECTED: the direction of the new graph (the file does not record it).
Returns
OG_SUCCESS, or one of the error codes below. On error no graph is left initialised.
Errors
  • OG_EINVAL weights is not one of the three og_add_weights_t values, or instream is NULL.
  • OG_PARSEERROR An edge line outside a block, '#' without a name, text after the name or the weight, a weight that is not a number, or a control character.
  • OG_EOVERFLOW A number is too large to represent.
  • OG_EUNDERFLOW A number is too small (too negative, or a real that rounds to zero or minus infinity).
  • OG_EFILE Reading the input stream fails.
  • OG_ENOMEM Not enough memory.
Complexity
O(|V| + |E|) expected, linear in the size of the stream.
Checked
Same results and error codes as python-igraph 1.0 on 372 reads (hand-written files and files it wrote, half of them mutated) and 220 graphs of 0 to 300 vertices.
C name
og_read_graph_lgl
In notebooks
Og.ReadGraphLgl
igraph 1.0
igraph_read_graph_lgl
See also
write_graph_lgl, read_graph_ncol

write_graph_lgl#

Exact

Writes the graph in the LGL format, one "# vertex" block per vertex that has edges starting at it.

og_error_t og_write_graph_lgl(
    const og_t *graph,
    FILE *outstream,
    const char *names,
    const char *weights,
    og_bool_t isolates
);

Vertices are taken in id order. A vertex with at least one edge starting at it (in an undirected graph: being the smaller end) gets a "# vertex" line followed by one line per such edge, naming the other end in increasing id order and, optionally, the weight. With isolates true, every vertex without any edge is then written as a bare "# vertex" line, so it survives a round trip.

names and weights work as in write_graph_ncol; an LGL name also must not contain '#'.

Parameters
  • graph The graph to write.
  • outstream An open stream to write to.
  • names Name of the string vertex attribute to write instead of ids, or NULL for ids.
  • weights Name of the numeric edge attribute to write as weights, or NULL for none.
  • isolates Whether to list the vertices without edges at the end.
Returns
OG_SUCCESS, or one of the error codes below.
Errors
  • OG_EINVAL A written vertex has an empty name, or one with a blank, '#', a control byte or a non-ASCII byte.
  • OG_EFILE The output stream refuses data (a write fails).
  • OG_ENOMEM Not enough memory.
Complexity
O(|V| + |E|).
Checked
Byte-identical to python-igraph 1.0 on 167 writes (isolates on and off, names it refuses) and 220 graphs of 0 to 300 vertices.
C name
og_write_graph_lgl
In notebooks
Og.WriteGraphLgl
igraph 1.0
igraph_write_graph_lgl
See also
read_graph_lgl, write_graph_ncol

GraphML

read_graph_graphml#

Exact

Reads one graph of a GraphML document, with its graph, vertex and edge attributes.

og_error_t og_read_graph_graphml(
    og_t *graph,
    FILE *instream,
    og_int_t index
);

The document is parsed by Open Graph's own XML 1.0 parser with namespaces; no XML library is used. It reads UTF-8, UTF-16 in either byte order, ISO-8859-1, ISO-8859-15, windows-1252 and US-ASCII, character and entity references, CDATA sections, comments and default attribute values from an internal DTD; external entities and DTDs are never loaded. index selects the graph when the document holds several (0 is the first).

Each <key> declares an attribute of the graph, the nodes or the edges, named by attr.name (by its id when attr.name is missing): attr.type boolean gives a Boolean attribute, int, long, float and double a numeric one, string a string one; keys without a type are not stored. A key's <default> fills elements that have no <data> for it. Vertices get ids in the order their node ids first appear (in <node> elements or as edge ends); the file's node ids are kept as the string vertex attribute "id", and edge ids, when the file has any, as the edge attribute "id", unless a key already uses that name. The graph is directed when edgedefault is "directed". Nested graphs and hyperedges are not read. Attributes are stored only when an attribute handler is installed (set_attribute_table(&og_cattribute_table)); without one the structure is read and attribute data is dropped.

In three places Open Graph follows the GraphML format where python-igraph 1.0's answer differs: '&' inside XML attribute values, the edges' own ids, and graphs with index above 0.

Parameters
  • graph An uninitialised graph. On success it holds the result; destroy it with destroy.
  • instream An open stream; it is read to its end. NULL is OG_EINVAL.
  • index 0-based position of the graph to read among the document's <graph> elements.
Returns
OG_SUCCESS, or one of the error codes below. On error no graph is left initialised.
Errors
  • OG_EINVAL index is negative or there is no graph with that index, a node id is empty, or instream is NULL.
  • OG_PARSEERROR The document is not well-formed XML, uses an unsupported encoding, has an invalid <key> (unknown attr.type or for, missing or repeated id or name), an edge without source or target, or a Boolean value that cannot be read.
  • OG_EFILE Reading the input stream fails.
  • OG_ENOMEM Not enough memory.
Complexity
Linear in the size of the document, plus O(|V| + |E|) per attribute.
Checked
958 reads against python-igraph 1.0 (keys, defaults, types, empty data, namespaces, encodings, errors, random documents, multi-graph files), with its error codes. In 301 of them ('&' in attribute values, edge ids, index above 0) the expected answer is what the GraphML format gives, where python-igraph 1.0's differs.
C name
og_read_graph_graphml
In notebooks
Og.ReadGraphGraphml
igraph 1.0
igraph_read_graph_graphml
See also
write_graph_graphml, read_graph_gml, set_attribute_table
og_t g;
FILE *f = fopen("network.graphml", "rb");
og_set_attribute_table(&og_cattribute_table);   /* keep the attributes */
if (f != NULL && og_read_graph_graphml(&g, f, 0) == OG_SUCCESS) {
    /* ... use g and its attributes ... */
    og_destroy(&g);
}
if (f != NULL) {
    fclose(f);
}

write_graph_graphml#

Exact

Writes the graph and all its graph, vertex and edge attributes as a GraphML document.

og_error_t og_write_graph_graphml(
    const og_t *graph,
    FILE *outstream,
    og_bool_t prefixattr
);

The output is UTF-8 GraphML: one <key> per attribute (numeric as double, string as string, Boolean as boolean; other attribute types are skipped with a warning), then one <graph> with edgedefault "directed" or "undirected", nodes named n0, n1, ... in id order and edges in id order, each with its <data>. NaN numeric values are left out. The five XML special characters are escaped.

With prefixattr true the key ids get the prefixes g_, v_ and e_, so a graph, a vertex and an edge attribute of the same name cannot clash; with false the key id is the attribute name. Without an attribute handler only the structure is written.

Parameters
  • graph The graph to write.
  • outstream An open stream to write to.
  • prefixattr Whether key ids get the prefixes g_, v_ and e_.
Returns
OG_SUCCESS, or one of the error codes below.
Errors
  • OG_EINVAL An attribute name or string value holds a control character other than tab, LF and CR, which XML 1.0 cannot carry.
  • OG_EFILE The output stream refuses data (a write fails).
  • OG_ENOMEM Not enough memory.
Complexity
O((|V| + |E|) x number of attributes).
Checked
Byte-identical to python-igraph 1.0 on 174 writes (prefixattr on and off, every attribute type, escaping, UTF-8, control-character errors) and 220 graphs of 0 to 300 vertices, apart from the comment line that names the creator.
C name
og_write_graph_graphml
In notebooks
Og.WriteGraphGraphml
igraph 1.0
igraph_write_graph_graphml
See also
read_graph_graphml, write_graph_gml
FILE *f = fopen("out.graphml", "wb");
if (f != NULL) {
    og_error_t err = og_write_graph_graphml(&g, f, true);
    fclose(f);
    if (err != OG_SUCCESS) {
        /* handle the error */
    }
}

GML

read_graph_gml#

Exact

Reads the first graph of a GML file, with its simple-valued attributes.

og_error_t og_read_graph_gml(og_t *graph, FILE *instream);

GML is a nested list of key-value pairs. The reader looks at the top-level Version (anything but 1 gives a warning) and the first graph list. Inside it every node list is a vertex and every edge list an edge whose integer source and target name node ids. Vertices take ids in file order; the file's node ids are kept as the numeric vertex attribute "id". The graph is directed when a directed key holds a non-zero whole number.

Every other key becomes an attribute of the graph, the vertex or the edge, named exactly as the key is written (a prefix a writer put in front, such as write_graph_gml's og, stays part of the name): numbers as numeric attributes, strings as string attributes. Where a key holds a list instead of a value, the element gets NaN or the empty string, and a key that only ever holds lists is dropped with a warning; when a key repeats in one record the last value counts. Strings may use the entities &quot;, &amp;, &apos;, &lt; and &gt;; unknown entities are kept as written. Lists are parsed without recursion, so deep nesting cannot overflow the stack. Attributes are stored only when an attribute handler is installed (set_attribute_table(&og_cattribute_table)); without one the structure is read and attribute data is dropped.

Parameters
  • graph An uninitialised graph. On success it holds the result; destroy it with destroy.
  • instream An open stream; it is read to its end. NULL is OG_EINVAL.
Returns
OG_SUCCESS, or one of the error codes below. On error no graph is left initialised.
Errors
  • OG_PARSEERROR A syntax error, no graph list, graph, node or edge that is not a list, a node with several or non-integer ids, two nodes with the same id, or an edge with a missing, repeated or non-integer source or target, or one that names an id no node has.
  • OG_EINVAL instream is NULL.
  • OG_EFILE Reading the input stream fails.
  • OG_ENOMEM Not enough memory.
Complexity
Linear in the size of the file, plus O(|V| log |V|) to match node ids.
Checked
Same graphs, attributes and error codes as python-igraph 1.0 on 458 reads (138 hand-written texts, 320 files it wrote, half of them mutated) and 220 graphs of 0 to 300 vertices; warnings are not compared.
C name
og_read_graph_gml
In notebooks
Og.ReadGraphGml
igraph 1.0
igraph_read_graph_gml
See also
write_graph_gml, read_graph_graphml

write_graph_gml#

Exact

Writes the graph and its attributes in the GML format.

og_error_t og_write_graph_gml(
    const og_t *graph,
    FILE *outstream,
    og_write_gml_sw_t options,
    const og_vector_t *id,
    const char *creator
);

The file holds a Creator line, "Version 1" and a graph list with directed 0 or 1, the graph attributes, a node list per vertex (with its id) and an edge list per edge (source, target); an undirected edge is written larger end first. Numbers are written with 15 significant digits, NaN values left out and infinities kept with a warning; Booleans as 0 and 1 (with a warning); strings in double quotes with '"' as &quot; and '&' as &amp; (options OG_WRITE_GML_ENCODE_ONLY_QUOT_SW leaves '&' alone).

GML keys are alphanumeric and start with a letter: other characters are dropped from attribute names, and a name that does not start with a letter gets Open Graph's own prefix "og" ("_weight" is written as ogweight, "2024" as og2024). read_graph_gml gives the prefix no meaning: such a key reads back as the attribute it names, ogweight. An attribute whose GML name would collide with the structure (graph attributes directed, node and edge; edge attributes source and target) is skipped with a warning.

Node ids come from id when it is given, else from a numeric vertex attribute "id", else they are the vertex ids; ids that are not all distinct whole numbers are ignored with a warning. creator NULL writes "Open Graph version <version> <date>"; an empty string writes no Creator line.

Parameters
  • graph The graph to write.
  • outstream An open stream to write to.
  • options Bit flags (og_write_gml_sw_t): OG_WRITE_GML_DEFAULT_SW, or OG_WRITE_GML_ENCODE_ONLY_QUOT_SW to escape only '"'.
  • id Node ids to write, one per vertex, or NULL.
  • creator Text of the Creator line; NULL for Open Graph's name, version and the date; "" for none.
Returns
OG_SUCCESS, or one of the error codes below.
Errors
  • OG_EINVAL id does not have one value per vertex.
  • OG_EFILE The output stream refuses data (a write fails).
  • OG_ENOMEM Not enough memory.
Complexity
O((|V| + |E|) x number of attributes + |V| log |V|).
Checked
Byte-identical to python-igraph 1.0 on 210 writes and 220 graphs of 0 to 300 vertices, apart from the prefix of names that do not start with a letter (python-igraph writes its own name there, Open Graph "og"). OG_WRITE_GML_ENCODE_ONLY_QUOT_SW and a NULL creator are unit-tested only; non-integer ids are not compared (python-igraph rounds them before the call, Open Graph ignores them as the reference manual says).
C name
og_write_graph_gml
In notebooks
Og.WriteGraphGml
igraph 1.0
igraph_write_graph_gml
See also
read_graph_gml, write_graph_graphml

Pajek

read_graph_pajek#

Exact

Reads a Pajek .net file, including two-mode networks, vertex coordinates and drawing parameters.

og_error_t og_read_graph_pajek(og_t *graph, FILE *instream);

Reading starts at the "*Vertices n" line ("*Vertices n n1" for a two-mode network); lines before it, among them one *Network line, are skipped. Vertex lines "id [label [x y [z]] [shape] parameters]" give the string attribute "name", the numeric attributes x, y and z, and the string attribute "shape". Edges come from *Arcs and *Edges sections, their list forms *Arcslist and *Edgeslist, and *Matrix sections (every non-zero entry an edge, weighted by it). Vertex numbers are 1-based; the graph has n vertices. The last edge section decides the direction: *Arcs, *Arcslist and a one-mode *Matrix make it directed. Sections that are not read are skipped up to the next line that starts with '*'.

Pajek's short parameter codes become attributes with readable names, each with Pajek's default for elements that do not set it (vertices: ic color, bc framecolor, x_fact xfact, r radius, ...; edges: w edgewidth, c color, p linepattern, l label, ...); the edge value becomes "weight". An unknown parameter becomes a string attribute of its own name, with '_' appended when the name is taken. In a two-mode network the Boolean vertex attribute "type" is true for the second mode. Attributes are stored only when an attribute handler is installed (set_attribute_table(&og_cattribute_table)); without one the structure is read and attribute data is dropped.

Parameters
  • graph An uninitialised graph. On success it holds the result; destroy it with destroy.
  • instream An open stream; it is read to its end. NULL is OG_EINVAL.
Returns
OG_SUCCESS, or one of the error codes below. On error no graph is left initialised.
Errors
  • OG_PARSEERROR No *Vertices line, a malformed line or section header, a control character, or a first-mode count above the vertex count.
  • OG_EINVAL A negative vertex count, a vertex number outside 1..n, or instream is NULL.
  • OG_EINVVID A *Matrix section has more rows or columns than the network has vertices.
  • OG_EOVERFLOW A number is too large to represent.
  • OG_EFILE Reading the input stream fails.
  • OG_ENOMEM Not enough memory.
Complexity
Linear in the size of the file (a *Matrix section has n^2 entries).
Checked
Same graphs, attributes and error codes as python-igraph 1.0 on 758 reads (318 hand-written texts covering every section, parameter and quoting rule; 440 files it wrote, half of them mutated) and 220 graphs of 0 to 300 vertices. Not compared: *Arcslist/*Edgeslist edges when edge attributes exist, where python-igraph 1.0 leaves the values uninitialised and Open Graph uses the defaults.
C name
og_read_graph_pajek
In notebooks
Og.ReadGraphPajek
igraph 1.0
igraph_read_graph_pajek
See also
write_graph_pajek

write_graph_pajek#

Exact

Writes the graph as a Pajek .net file, with names, coordinates, weights and the drawing parameters Pajek knows.

og_error_t og_write_graph_pajek(const og_t *graph, FILE *outstream);

The file has a *Vertices line; vertex lines when the graph has any vertex attribute Pajek can carry (name, x, y, z, shape, color, framecolor, labelcolor, fontsize and the other drawing parameters); then *Arcs (directed) or *Edges with one line per edge in edge id order, using 1-based numbers, followed by the "weight" attribute and the edge drawing parameters (edgewidth, color, label, ...). Attribute names are turned back into Pajek's codes; other attributes are not written. Strings are quoted, with '"' written as &#34; and a line break as the two characters \n.

A Boolean vertex attribute "type" makes a two-mode network: the vertices with type false come first, *Vertices gets their count as a second number and the edges are renumbered to match. Lines end in LF only and no byte-order mark is written.

Parameters
  • graph The graph to write.
  • outstream An open stream to write to.
Returns
OG_SUCCESS, or one of the error codes below.
Errors
  • OG_EFILE The output stream refuses data (a write fails).
  • OG_ENOMEM Not enough memory.
Complexity
O((|V| + |E|) x number of attributes).
Checked
Byte-identical to python-igraph 1.0 on 236 writes (random attribute sets of right and wrong types, two-mode graphs, quoting and escaping) and 220 graphs of 0 to 300 vertices.
C name
og_write_graph_pajek
In notebooks
Og.WriteGraphPajek
igraph 1.0
igraph_write_graph_pajek
See also
read_graph_pajek

DIMACS, graph database, DL, DOT and LEDA

read_graph_dimacs_flow#

Exact

Reads a DIMACS network-flow file: a maximum-flow problem with source, target and capacities, or an edge problem with vertex labels.

og_error_t og_read_graph_dimacs_flow(
    og_t *graph,
    FILE *instream,
    og_strvector_t *problem,
    og_vector_int_t *label,
    og_int_t *source,
    og_int_t *target,
    og_vector_t *capacity,
    og_bool_t directed
);

Each line starts with a type letter and one separator: c (comment), p (the problem line, "p max nodes arcs" or "p edge nodes edges"), n (node lines), a (arcs "a from to capacity", max problems) and e (edges "e from to", edge problems). Ids in the file are 1-based. The graph has the node count of the problem line, or more when an arc names a larger id; edges follow the file order.

For a max problem the node lines "n id s" and "n id t" give the source and the target, returned as 0-based ids (-2 when the file names none), and capacity receives one value per arc. For an edge problem the node lines "n id label" give integer labels: label receives one entry per vertex, the vertex's 0-based index when the file gives none, and capacity is emptied. problem receives "max" or "edge".

Parameters
  • graph An uninitialised graph. On success it holds the result; destroy it with destroy.
  • instream An open stream; it is read to its end. NULL is OG_EINVAL.
  • problem Receives one string, "max" or "edge"; may be NULL.
  • label Edge problems: receives the label of every vertex; may be NULL.
  • source Max problems: receives the 0-based source (-2 when there is none); may be NULL.
  • target Max problems: receives the 0-based target (-2 when there is none); may be NULL.
  • capacity Max problems: receives the capacity of each edge in edge order; emptied for edge problems; may be NULL.
  • directed OG_DIRECTED or OG_UNDIRECTED: the direction of the new graph (the file does not record it).
Returns
OG_SUCCESS, or one of the error codes below. On error no graph is left initialised.
Errors
  • OG_EINVAL The file has no problem line, or instream is NULL.
  • OG_PARSEERROR An unknown line type, a second problem line, a line that cannot be read, a negative count, an arc in an edge problem or an edge line in a max problem, or a repeated source or target line.
  • OG_EINVVID An arc or edge names an id below 1, or a label line names a vertex the graph does not have.
  • OG_EFILE Reading the input stream fails.
  • OG_ENOMEM Not enough memory.
Complexity
O(|V| + |E|).
Checked
Max-flow files: same graph, source, target, capacities and error codes as python-igraph 1.0 on 293 reads and 220 graphs of 0 to 300 vertices. Edge problems are unit-tested only: python-igraph 1.0 does not read them as the reference manual describes, and Open Graph follows the manual.
C name
og_read_graph_dimacs_flow
In notebooks
Og.ReadGraphDimacsFlow
igraph 1.0
igraph_read_graph_dimacs_flow
See also
write_graph_dimacs_flow, maxflow

write_graph_dimacs_flow#

Exact

Writes a maximum-flow problem in the DIMACS format.

og_error_t og_write_graph_dimacs_flow(
    const og_t *graph,
    FILE *outstream,
    og_int_t source,
    og_int_t target,
    const og_vector_t *capacity
);

The output is a comment line, the problem line "p max |V| |E|", the source and target node lines and one "a from to capacity" line per edge in edge id order, all ids 1-based. An undirected edge is written as one arc from its smaller to its larger end. A NULL capacity writes 1 for every edge. source and target are written as given and not checked.

Parameters
  • graph The graph to write.
  • outstream An open stream to write to.
  • source The 0-based source vertex.
  • target The 0-based target vertex.
  • capacity One capacity per edge, or NULL for 1 everywhere.
Returns
OG_SUCCESS, or one of the error codes below.
Errors
  • OG_EINVAL capacity does not have one value per edge.
  • OG_EFILE The output stream refuses data (a write fails).
Complexity
O(|E|).
Checked
Byte-identical to python-igraph 1.0 on 116 writes and 220 graphs of 0 to 300 vertices, apart from the first comment line, which names Open Graph.
C name
og_write_graph_dimacs_flow
In notebooks
Og.WriteGraphDimacsFlow
igraph 1.0
igraph_write_graph_dimacs_flow
See also
read_graph_dimacs_flow

read_graph_graphdb#

Exact

Reads a graph in the binary format of the graph database of De Santo, Foggia, Sansone and Vento (2003).

og_error_t og_read_graph_graphdb(
    og_t *graph,
    FILE *instream,
    og_bool_t directed
);

The file is a sequence of 16-bit little-endian words: the vertex count, then for every vertex its number of outgoing edges followed by their 0-based targets. Edges are added in that order. A target at or beyond the vertex count enlarges the graph. The file does not record the direction; directed chooses it.

A file that ends inside a record, or has bytes left over after the last vertex, is refused. There is no writer for this format.

Parameters
  • graph An uninitialised graph. On success it holds the result; destroy it with destroy.
  • instream An open stream; it is read to its end. NULL is OG_EINVAL.
  • directed OG_DIRECTED or OG_UNDIRECTED: the direction of the new graph (the file does not record it).
Returns
OG_SUCCESS, or one of the error codes below. On error no graph is left initialised.
Errors
  • OG_PARSEERROR The file ends too early, or has extra bytes after the graph.
  • OG_EINVAL instream is NULL.
  • OG_EFILE Reading the input stream fails.
  • OG_ENOMEM Not enough memory.
Complexity
O(|V| + |E|).
Checked
Same graphs and errors as python-igraph 1.0 on 148 files (truncated ones and out-of-range targets included) and 200 files of 0 to 300 vertices.
C name
og_read_graph_graphdb
In notebooks
Og.ReadGraphGraphdb
igraph 1.0
igraph_read_graph_graphdb
See also
read_graph_edgelist

read_graph_dl#

Exact

Reads a UCINET DL file in full-matrix, edge-list or node-list form.

og_error_t og_read_graph_dl(
    og_t *graph,
    FILE *instream,
    og_bool_t directed
);

The file starts with "DL n=<count>", then an optional "FORMAT = FULLMATRIX | EDGELIST1 | NODELIST1" (full matrix by default), an optional "LABELS:" list or "LABELS EMBEDDED", and "DATA:". Keywords are case-insensitive, labels case-sensitive. A full matrix holds 0/1 entries row by row, each 1 an edge; an edge list holds "from to [weight]" lines; a node list holds "from to1 to2 ..." lines. Vertex numbers are 1-based; with embedded labels the vertices are named by labels instead (for a matrix: a header line of column labels and a label at the start of each row).

Labels, from the list or embedded, become the string vertex attribute "name" (missing labels are empty, extra ones dropped); edge-list weights become the edge attribute "weight" (NaN for edges without one). After DATA: a comma or a NUL byte ends the data. Attributes are stored only when an attribute handler is installed (set_attribute_table(&og_cattribute_table)); without one the structure is read and attribute data is dropped.

Parameters
  • graph An uninitialised graph. On success it holds the result; destroy it with destroy.
  • instream An open stream; it is read to its end. NULL is OG_EINVAL.
  • directed OG_DIRECTED or OG_UNDIRECTED: the direction of the new graph (the file does not record it).
Returns
OG_SUCCESS, or one of the error codes below. On error no graph is left initialised.
Errors
  • OG_PARSEERROR A malformed header or statement, a wrong kind of token (a number where a label belongs or the reverse, a matrix entry that is not a digit), a missing final line break, or a file that ends inside the label list.
  • OG_EINVAL A vertex number below 1, a matrix digit other than 0 or 1, or instream is NULL.
  • OG_EINVVID A vertex number above n.
  • OG_EOVERFLOW A number is too large to represent.
  • OG_EUNDERFLOW A number is too small (too negative, or a real that rounds to zero or minus infinity).
  • OG_EFILE Reading the input stream fails.
  • OG_ENOMEM Not enough memory.
Complexity
Linear in the size of the file (a full matrix has n^2 entries).
Checked
Same graphs, names, weights and error codes as python-igraph 1.0 on 719 reads and 200 files of 1 to 300 vertices. One deliberate difference: a LABELS list shorter than n gives the remaining vertices empty names, where python-igraph reads past its list.
C name
og_read_graph_dl
In notebooks
Og.ReadGraphDl
igraph 1.0
igraph_read_graph_dl
See also
read_graph_pajek, read_graph_edgelist

write_graph_dot#

Exact

Writes the graph and its attributes in the Graphviz DOT language.

og_error_t og_write_graph_dot(const og_t *graph, FILE *outstream);

The output is a "graph" (undirected) or "digraph" (directed) block: a "graph [...]" line with the graph attributes, one line per vertex by id with its attributes, then one line per edge in edge id order with "--" or "->" and its attributes; an undirected edge is written larger end first. A value is written bare when DOT reads it as a plain name or numeral, and quoted otherwise (DOT keywords such as node or edge, blanks, other characters), with backslash, '"' and line breaks escaped. Whole numbers are written in full, other reals with 15 significant digits, Inf, -Inf and NaN bare.

DOT is an output format here; there is no DOT reader. Without an attribute handler only the structure is written.

Parameters
  • graph The graph to write.
  • outstream An open stream to write to.
Returns
OG_SUCCESS, or one of the error codes below.
Errors
  • OG_EFILE The output stream refuses data (a write fails).
  • OG_ENOMEM Not enough memory.
Complexity
O((|V| + |E|) x number of attributes).
Checked
Byte-identical to python-igraph 1.0 on 151 writes (every attribute type, keywords, numerals, strings that need quotes) and 220 graphs of 0 to 300 vertices, apart from the first comment line, which names Open Graph and its version.
C name
og_write_graph_dot
In notebooks
Og.WriteGraphDot
igraph 1.0
igraph_write_graph_dot
See also
write_graph_graphml, write_graph_gml

write_graph_leda#

Exact

Writes the graph in LEDA's native graph format, with at most one vertex and one edge attribute as data.

og_error_t og_write_graph_leda(
    const og_t *graph,
    FILE *outstream,
    const char *vertex_attr_name,
    const char *edge_attr_name
);

The file starts with LEDA.GRAPH, the data types of the vertices and edges (string, double, bool, or void for none), and -1 for a directed or -2 for an undirected graph. Then come the vertex section, one |{value}| line per vertex, and the edge section: "from to reverse |{value}|" per edge with 1-based numbers, grouped by the first vertex in id order, where reverse is the 1-based id of an edge going the opposite way (0 when there is none).

vertex_attr_name and edge_attr_name choose the attributes written as data; NULL writes none, and a missing attribute or one of a type LEDA cannot hold gives a warning and is left out. Booleans are written |{true}| and |{false}|.

Parameters
  • graph The graph to write.
  • outstream An open stream to write to.
  • vertex_attr_name Name of the vertex attribute to write as vertex data, or NULL.
  • edge_attr_name Name of the edge attribute to write as edge data, or NULL.
Returns
OG_SUCCESS, or one of the error codes below.
Errors
  • OG_EINVAL A string value contains a line break, which the format cannot hold.
  • OG_EFILE The output stream refuses data (a write fails).
  • OG_ENOMEM Not enough memory.
Complexity
O(|V| + |E| log d), d the largest degree (the reverse-edge lookup).
Checked
Byte-identical to python-igraph 1.0 on 156 writes with numeric and string attributes and 220 graphs of 0 to 300 vertices. Boolean values (written as |{true}| and |{false}|) are unit-tested only, as python-igraph 1.0's output for them differs.
C name
og_write_graph_leda
In notebooks
Og.WriteGraphLeda
igraph 1.0
igraph_write_graph_leda
See also
write_graph_graphml

The number format

enter_safelocale#

Unit tests

Switches the calling thread to the C numeric locale, so that numbers are read and written with a decimal point.

og_error_t og_enter_safelocale(og_safelocale_t *loc);

The readers and writers parse and print reals with the C library, which follows the current numeric locale; under a locale with a decimal comma 1.5 would be written "1,5". This function makes LC_NUMERIC "C" for the calling thread alone where the platform allows it (Windows: a per-thread locale; POSIX: newlocale and uselocale), and for the whole process otherwise (setlocale), which is not safe while other threads use the locale.

Every successful call must be paired with exit_safelocale on the same thread and with the same og_safelocale_t; pairs may nest. og_safelocale_t is a small struct the caller declares and treats as opaque (in igraph it is an opaque pointer; the calls are used the same way).

Parameters
  • loc Storage for what must be restored; pass the same object to exit_safelocale.
Returns
OG_SUCCESS, or one of the error codes below.
Errors
  • OG_FAILURE The locale could not be switched.
  • OG_ENOMEM Not enough memory.
Complexity
O(1).
Checked
Not reachable from python-igraph. Tested under a decimal-comma locale on Windows and macOS: printf and Open Graph's readers and writers use '.', nested pairs work and nothing leaks.
C name
og_enter_safelocale
In notebooks
Og.Native.og_enter_safelocale
igraph 1.0
igraph_enter_safelocale
See also
exit_safelocale, write_graph_gml, read_graph_ncol
og_safelocale_t loc;
if (og_enter_safelocale(&loc) == OG_SUCCESS) {
    og_write_graph_gml(&g, f, OG_WRITE_GML_DEFAULT_SW, NULL, "");   /* writes 1.5, never 1,5 */
    og_exit_safelocale(&loc);
}

exit_safelocale#

Unit tests

Restores the numeric locale that enter_safelocale replaced.

void og_exit_safelocale(og_safelocale_t *loc);

Puts back the locale saved in loc, per thread or for the process, whichever enter_safelocale used, and frees what loc held. Call it once for every successful enter_safelocale, on the same thread. On a loc whose enter_safelocale failed it does nothing harmful.

Parameters
Returns
Nothing.
Complexity
O(1).
Checked
After it a decimal-comma locale formats "1,5" again (Windows and macOS).
C name
og_exit_safelocale
In notebooks
Og.Native.og_exit_safelocale
igraph 1.0
igraph_exit_safelocale
See also
enter_safelocale

Last updated · Open Graph 0.1.0 · OpenBI Studio 0.3.78