Question on fscanf ....

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Question on fscanf ....

Dr.-Ing. Dieter Jurzitza
Dear listmembers,
I've been having a hard time with understanding the format specifiers of
fscanf et al - still not fully done, but anyway. Let me provide an example
what I'd like to do.

Given you have an ASCII file with 10 columns of data and you're interested in
the 2nd and 8th column only. The first column is a string, all other columns
contain numbers. So I tried:

infile=fopen(infilename, "r");
[x]=fscanf(infile, "%*s %f %*lf %*f %*f %*f %*f %f %*f %*f", [2 inf]);
fclose (infile)

given that infile exists this works. However, the result is an array with 2
columns - ok, but as I want the two columns isolated from one another for the
sake of clarity I have to do an extra

t=x(1,:);
and
y=x(2,:);

afterwards. What I would have liked to do is a

[t,y]= ....

directly to assign column 2 to t and column 8 to y. Well, but what to put here
on the right side?

Sad enough I have to admit that it took me a matlab documentation page for an
explanation what is required in the [2 inf] field - this does not become clear
from the octave documentation IMHO, maybe my English capabilities are
insufficient here ... a minimum example would be a big big help.

The second form of fscanf() puts a "C" instead of the [2 inf] and is said to
be more C-ish. Still I could not manage to convince octave to read the two
values into two variables - any ideas?

Suggestions are very much appreciated! If there is no way but splitting the
array afterwards - ok. I had had thought that what I'd like to achieve ought
to be possible in accordance to my understanding of the documentation, but
how.
Thank you very much!
Take care


Dieter Jurzitza


--
-----------------------------------------------------------
Dr.-Ing. Dieter Jurzitza                    76131 Karlsruhe





Reply | Threaded
Open this post in threaded view
|

Re: Question on fscanf ....

nrjank
On Fri, Mar 20, 2020 at 2:56 PM Dr.-Ing. Dieter Jurzitza
<[hidden email]> wrote:

>
> Dear listmembers,
> I've been having a hard time with understanding the format specifiers of
> fscanf et al - still not fully done, but anyway. Let me provide an example
> what I'd like to do.
>
> Given you have an ASCII file with 10 columns of data and you're interested in
> the 2nd and 8th column only. The first column is a string, all other columns
> contain numbers. So I tried:
>
> infile=fopen(infilename, "r");
> [x]=fscanf(infile, "%*s %f %*lf %*f %*f %*f %*f %f %*f %*f", [2 inf]);
> fclose (infile)
>
> given that infile exists this works. However, the result is an array with 2
> columns - ok, but as I want the two columns isolated from one another for the
> sake of clarity I have to do an extra
>
> t=x(1,:);
> and
> y=x(2,:);
>
> afterwards. What I would have liked to do is a
>
> [t,y]= ....
>
> directly to assign column 2 to t and column 8 to y. Well, but what to put here
> on the right side?
>
> Sad enough I have to admit that it took me a matlab documentation page for an
> explanation what is required in the [2 inf] field - this does not become clear
> from the octave documentation IMHO, maybe my English capabilities are
> insufficient here ... a minimum example would be a big big help.
>
> The second form of fscanf() puts a "C" instead of the [2 inf] and is said to
> be more C-ish. Still I could not manage to convince octave to read the two
> values into two variables - any ideas?
>
> Suggestions are very much appreciated! If there is no way but splitting the
> array afterwards - ok. I had had thought that what I'd like to achieve ought
> to be possible in accordance to my understanding of the documentation, but
> how.
> Thank you very much!
> Take care
>

can you provide a short sample file with a few lines of data? and then
tell us what your ideal output would look like?  it might help us
advise you on how to read the file and process any input into
variables.


Reply | Threaded
Open this post in threaded view
|

Re: Question on fscanf ....

Dr.-Ing. Dieter Jurzitza
Hello Nicholas,
hello octave - team,
ok, let me try again:

a snipplet of my data - file:

19.03.2020  00.00     30.9322      0.0000    229.0000     74.4911    229.0000      
0.0000   -155.8958    259.9323
19.03.2020  00.25     30.3245      0.0000    215.0000     73.6548    215.0000      
0.0000   -167.1042    245.3245
19.03.2020  00.50    283.7751      0.0000   1451.3334     71.8259   1451.3334      
0.0000   -948.5000   1735.1084
19.03.2020  00.75     20.7556      3.5018    308.4982     65.9915    312.0000      
0.0000   -270.6667    329.2538
19.03.2020  01.00     23.7027      2.3038    911.6962     63.4976    914.0000      
0.0000   -906.2708    935.3989
19.03.2020  01.25     12.8118      0.0000    198.0000     61.9911    198.0000      
0.0000   -156.4792    210.8118
19.03.2020  01.50     28.3770      0.0000    155.0000     61.1548    155.0000      
0.0000   -116.6667    183.3770
19.03.2020  01.75     33.9556      0.0000    117.0000     60.1572    117.0000      
0.0000      1.7292    150.9556
19.03.2020  02.00     44.0180      0.6392     92.6941     58.9934     93.3333      
0.0000    -27.1458    136.7121
19.03.2020  02.25     10.5807     12.8240    119.8427     53.9903    132.6667      
0.0000    -91.3750    130.4234

I cannot prevent the linebreak, so the first line should continue after
229.0000 and go until 259.9323 and so on and so forth. Put this snipplet into
a file and call it i. e. "data.dat". Call the next "minimalbeispiel.m" with i.
e.
minimalbeispiel (data.dat)


This works ok:
function minimalbeispiel (infilename)
  % open infile for reading ....
  infile=fopen(infilename, "r");
  % read data into one array ....
  [Y]=fscanf(infile, "%*s %f %*lf %*f %*f %*f %*f %f %*f %*f", [2 inf]);
  % close infile
  fclose(infile);
  % separate variables ...
  t=Y(1,:)
  y=Y(2,:)
endfunction

Y contains two arrays,  one consisting of the values of column 2 of the file,
one consisting of the values of column 8 of the file.

My questions:
1.) is there  any way to circumvent the usage of Y and do some kind of
[t,y]=fscanf(infile, "%*s %f %*lf %*f %*f %*f %*f %f %*f %*f", ??????);

2.) the version of fscanf using "C" where I had had put the "??????" now is
said to be more C-ish. However, I did not find a way to read the data shown
above into any variable using the "C" statement - only if I would do it in two
subsequent fscanf - operations assigning one variable at a time.

If some kind soul could provide an information to me - and, moreover, maybe
let me know how the process would work using "C" at all would be very much
appreciated. In C-language I would have two pointers to variables sitting
behind the format - string. But I cannot find a way to do the assignment the
way I'd like to do it at all. I am sure it is my fault - any help is very much
appreciated.

Thank you very much for looking into this,
take care

Dieter Jurzitza


Am Freitag, 20. März 2020, 20:39:17 CET schrieb Nicholas Jankowski:
> On Fri, Mar 20, 2020 at 2:56 PM Dr.-Ing. Dieter Jurzitza
>
> <[hidden email]> wrote:
> > Dear listmembers,
> > I've been having a hard time with understanding the format specifiers of
> > fscanf et al - still not fully done, but anyway. Let me provide an example
> > what I'd like to do.
> >
> > Given you have an ASCII file with 10 columns of data and you're interested
**************

--
-----------------------------------------------------------
Dr.-Ing. Dieter Jurzitza                    76131 Karlsruhe





Reply | Threaded
Open this post in threaded view
|

Re: Question on fscanf ....

nrjank
> My questions:
> 1.) is there  any way to circumvent the usage of Y and do some kind of
> [t,y]=fscanf(infile, "%*s %f %*lf %*f %*f %*f %*f %f %*f %*f", ??????);

I think you may prefer to use textscan.  This function respects the *
'ignore' flag and also stores outputs in separate elements of a cell
array.

Eg.,:

>> foo=fopen('data.dat');
>> bar = textscan(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f")
bar =
{
  [1,1] =

     0.00000
     0.25000
     0.50000
     0.75000
     1.00000
     1.25000
     1.50000
     1.75000
     2.00000
     2.25000

  [1,2] =

     0
     0
     0
     0
     0
     0
     0
     0
     0
     0

}

while these are in a single cell array, they are separately
addressable elements. It may be possible to get the 'C' style version
to work, but on a quick try I can only get it to read in the one line
at a time even if I play with \n's :
 >> foo = fopen('data.dat');
>> [bar1,bar2] = fscanf(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f", "C")
bar1 = 0
bar2 = 0
>> [bar1,bar2] = fscanf(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f", "C")
bar1 =  0.25000
bar2 = 0
>> [bar1,bar2] = fscanf(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f", "C")
bar1 =  0.50000
bar2 = 0
>> [bar1,bar2] = fscanf(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f", "C")
bar1 =  0.75000
bar2 = 0
>> [bar1,bar2] = fscanf(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f", "C")
bar1 =  1
bar2 = 0


Reply | Threaded
Open this post in threaded view
|

Re: Question on fscanf ....

Octave - General mailing list
nrjank wrote

>> My questions:
>> 1.) is there  any way to circumvent the usage of Y and do some kind of
>> [t,y]=fscanf(infile, "%*s %f %*lf %*f %*f %*f %*f %f %*f %*f", ??????);
>
> I think you may prefer to use textscan.  This function respects the *
> 'ignore' flag and also stores outputs in separate elements of a cell
> array.
>
> Eg.,:
>
>>> foo=fopen('data.dat');
>>> bar = textscan(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f")
> bar =
> {
>   [1,1] =
>
>      0.00000
>      0.25000
>      0.50000
>      0.75000
>      1.00000
>      1.25000
>      1.50000
>      1.75000
>      2.00000
>      2.25000
>
>   [1,2] =
>
>      0
>      0
>      0
>      0
>      0
>      0
>      0
>      0
>      0
>      0
>
> }
>
> while these are in a single cell array, they are separately
> addressable elements. It may be possible to get the 'C' style version
> to work, but on a quick try I can only get it to read in the one line
> at a time even if I play with \n's :
>  >> foo = fopen('data.dat');
>>> [bar1,bar2] = fscanf(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f", "C")
> bar1 = 0
> bar2 = 0
>>> [bar1,bar2] = fscanf(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f", "C")
> bar1 =  0.25000
> bar2 = 0
>>> [bar1,bar2] = fscanf(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f", "C")
> bar1 =  0.50000
> bar2 = 0
>>> [bar1,bar2] = fscanf(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f", "C")
> bar1 =  0.75000
> bar2 = 0
>>> [bar1,bar2] = fscanf(foo, "%*s %f %*f %*f %*f %*f %*f %f %*f %*f", "C")
> bar1 =  1
> bar2 = 0

If you insist in doing it in one statement you can brush of textread.m and
ignore the "obsolete" warning:

>> [a, b] = textread ('data.dat',  '%*s %f %*f %*f %*f %*f %*f %f %*f %*f')
warning: textread is obsolete; use textscan instead
a =
        0
   0.2500
   0.5000
   0.7500
   1.0000
   1.2500
   1.5000
   1.7500
   2.0000
   2.2500

b =
   0
   0
   0
   0
   0
   0
   0
   0
   0
   0

textread.m isn't quite as fast as textscan and has some limitations, but
otherwise still works well.

Philip



--
Sent from: https://octave.1599824.n4.nabble.com/Octave-General-f1599825.html