# Reading datafile entry by entry

In order to use pstricks in a certain fashion, I would like to access a datafile line by line, inside a multido loop. For example, let's say my file is called Datafile.dat. It contains the (x,y) coordinates of say, 20 points. I would like something like

\multido{\iA=0+1}{20}{%
\psdot(Datafile.dat(\iA,1),Datafile.dat(\iA,2))
}


I know there exists functions to do this, but my emphasis is on being able to access the datafile element by element.

This might do it for you.

Let's say the dataA.txt file contained the following space-separated data:

.15 12   13 14
.20 22   23 24
.25 45.6 33 Ending


Then this code can read the file using the defined \readdef command (like dataA in the example) or you can cut and paste it into the file (like dataB in the example)

\documentclass{article}
\usepackage{stringstrings}
%
\newcounter{index}
\newcounter{row}
\newcounter{col}
%
\setcounter{index}{0}%
\setcounter{row}{1}%
\setcounter{col}{0}%
\getargs{#1}%
\whiledo{\value{index} < \narg}{%
%    \arabic{index}:~%
\ifthenelse{\value{col} > #3}%
{}%
%    \arabic{row}-\arabic{col}\\%
\expandafter\edef\csname#2X\roman{row}X\roman{col}\endcsname%
{\expandafter\csname arg\roman{index}\endcsname}%
}%
}
%
\newcommand\Arrayij[3]{%
\setcounter{row}{#2}
\setcounter{col}{#3}
\csname#1X\roman{row}X\roman{col}\endcsname
}
%
\catcode\endlinechar=10\relax%
\def#2{}%
\openin\file=#1%
\loop\unless\ifeof\file%
% Do something with \fileline%
\edef#2{#2\fileline}%
\repeat%
\closein\file%
\catcode\endlinechar=5\relax%
}
%
\begin{document}
%
%  The \readdef produces the equivalent result to
%  \edef\dataA{
%  .15 12   13 14
%  .20 22   23 24
%  .25 45.6 33 Ending
%  }
%
\def\dataB{%
B.15 B12 B13 B14
B.20 B22 B23 B24
B.25 B32 B33 BEnding
}
%
% This says to read the variable \dataA, stick it into an "array"
% called arA with a 4-column width
\noindent
The data in the 3,2 position of the dataA file is \Arrayij{arA}{3}{2}\\
The data in the 3,4 position of dataB is \Arrayij{arB}{3}{4}
\end{document}


The \readArray command takes the space separated data and sticks it into an array, and then you can call back individual array elements with \Arrayij invocations. It's currently defined for 2-D (x,y) data input, but it could be adapted for 3-D, for example.

(As an aside, the stringstrings routine used is \getargs. If slow speed for large data is an issue, faster versions of that routine have been put forth by various bright sx users at Parsing strings containing diacritical marks (macros?).)

Note: edited so that \readdef could be used more than once without overwriting itself.

• Thanks, this is perfect. I will adapt this to 3D data :) Mar 17 '13 at 8:30
• @Mathusalem, I added a percent on the line \def\dataB{%. While stringstrings didn't need it, the alternate versions of getargs that I cited do. And it's just good practice to do it. Mar 18 '13 at 10:29
• @Mathusalem This solution approach is codified as the readarray package, now available on CTAN Apr 2 '13 at 11:49