Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

reading entries from string separated by space

Status
Not open for further replies.

jags015

Technical User
Mar 6, 2013
4
FR
Hi,
Greetings for the day !
I am trying to read a number of entries from a string where I don't know how many spaces will be there in between each entries and I have hexadecimal numbers to read from the string so I can't use unformatted read.
e.g. string -> 3 c 2cfb 0 d e
e.g. another sting -> 3 c 2cfb 0 d e

Currently I read the entries in character variables and then read hexadecimal numbers from these character variables. some like this

read (string,*) (string_entries(i),i=1,6)
do i=1,6
read(string_entries(i),'(z)')a(i)
end do

I was wondering if there is any way by which I can read directly these entries from string.

Thanks,
Jags

 
I guess there is no other way than to read the string from file and somehow deal with these blanks.
You do it by reading character substrings from this string, other option would be to advance to the next non-blank character for every reading of a(i). But I would say, this would require more codelines.

But maybe somebody has a better idea.

Norbert


The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
The simplest way would be to find a code that do what you need. For example download a module with string utilities by Dr. George Benthien here:

Now create a little program like this
jags015.f95
Code:
[COLOR=#a020f0]program[/color] jags015
  [COLOR=#a020f0]use[/color] strings
  [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]20[/color]):: str 
  [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color]) :: delims
  [COLOR=#2e8b57][b]integer[/b][/color], [COLOR=#2e8b57][b]parameter[/b][/color] :: StrMax[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]10[/color], Nmax [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]20[/color]
  [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color]StrMax), [COLOR=#2e8b57][b]dimension[/b][/color](Nmax) :: args
  [COLOR=#2e8b57][b]integer[/b][/color] :: nargs, k
  
  str [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]'3 c 2cfb 0 d e'[/color]
  delims [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]' '[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'str = "'[/color], [COLOR=#008080]trim[/color](str),[COLOR=#ff00ff]'"'[/color]

  [COLOR=#0000ff]! split strings according delimiters[/color]
  [COLOR=#a020f0]call[/color] parse(str, delims, args, nargs)
  
  [COLOR=#0000ff]! write result[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'nargs = '[/color], nargs
  [COLOR=#804040][b]do[/b][/color] k[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color], nargs
    [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'args('[/color],k,[COLOR=#ff00ff]') = "'[/color], [COLOR=#008080]trim[/color](args(k)), [COLOR=#ff00ff]'"'[/color] 
  [COLOR=#804040][b]end do[/b][/color]
[COLOR=#a020f0]end program[/color] jags015

Then compile+link your program with the modules and execute it (I tried it only with the free compilers: gfortran and g95)
Code:
$ gfortran precmod.f90 stringmod.f90 jags015.f95 -o jags015

$ jags015
 str = "3 c 2cfb 0 d e"
 nargs =            6
 args(           1 ) = "3"
 args(           2 ) = "c"
 args(           3 ) = "2cfb"
 args(           4 ) = "0"
 args(           5 ) = "d"
 args(           6 ) = "e"

$ g95 precmod.f90 stringmod.f90 jags015.f95 -o jags015

$ jags015
 str = "3 c 2cfb 0 d e"
 nargs =  6
 args( 1 ) = "3"
 args( 2 ) = "c"
 args( 3 ) = "2cfb"
 args( 4 ) = "0"
 args( 5 ) = "d"
 args( 6 ) = "e"
 
Thanks Gummibaer and Mikrom,
Currently I am following a similar procedure. But my concern is that I am working with large data and my worry is that this procedure makes the process slow. I am under the impression that if that I can read this string directly and convert the hex numbers into integers simultaneously as we do in reading unformatted string, I can improve the speed.

Now, I think this is the best way of doing this kind of stuff.

Please suggest if anyone has a better solution.

Thanks,
Jags
 
Would it be a good idea to seperate data conversion and data input?
Then you would work in two steps:

(1) Write a seperate prog for reading and conversion of your data and to save them in a new file, preferrably unformatted for rapid reading.
(2) Your working program is to input from this file only.

Advantage: You have to do the conversion only once for any of your files.

Norbert

The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
I would do the data file converion separately with a tool suitable for it - e.g.: shell, awk, perl, python, ...etc

For example if you have this data file
hex_format.dat
Code:
1 2 3 4 5 6
3 c 2cfb 0 d e
A B  C    D E   FF
then this short shell script
hex2dec.sh
Code:
[COLOR=#804040][b]while[/b][/color][COLOR=#804040][b] [/b][/color][COLOR=#804040][b]read[/b][/color][COLOR=#804040][b] a b c d e f[/b][/color][COLOR=#804040][b];[/b][/color][COLOR=#804040][b] [/b][/color]
[COLOR=#804040][b]do[/b][/color] 
  printf [COLOR=#804040][b]"[/b][/color][COLOR=#ff00ff]%d %d %d %d %d %d[/color][COLOR=#6a5acd]\n[/color][COLOR=#804040][b]"[/b][/color]     [COLOR=#804040][b]"[/b][/color][COLOR=#ff00ff]0x[/color][COLOR=#a020f0]$a[/color][COLOR=#804040][b]"[/b][/color] [COLOR=#804040][b]"[/b][/color][COLOR=#ff00ff]0x[/color][COLOR=#a020f0]$b[/color][COLOR=#804040][b]"[/b][/color] [COLOR=#804040][b]"[/b][/color][COLOR=#ff00ff]0x[/color][COLOR=#a020f0]$c[/color][COLOR=#804040][b]"[/b][/color] [COLOR=#804040][b]"[/b][/color][COLOR=#ff00ff]0x[/color][COLOR=#a020f0]$d[/color][COLOR=#804040][b]"[/b][/color] [COLOR=#804040][b]"[/b][/color][COLOR=#ff00ff]0x[/color][COLOR=#a020f0]$e[/color][COLOR=#804040][b]"[/b][/color] [COLOR=#804040][b]"[/b][/color][COLOR=#ff00ff]0x[/color][COLOR=#a020f0]$f[/color][COLOR=#804040][b]"[/b][/color]
[COLOR=#804040][b]done[/b][/color] [COLOR=#804040][b]<[/b][/color] hex_format.dat
does the job for you:
Code:
$ hex2dec.sh
1 2 3 4 5 6
3 12 11515 0 13 14
10 11 12 13 14 255
 
Thanks Mikrom and Gummibaer,
Mikdrom, Ideas suggested by you seems promising. If I could do this, I assume that definitely I can make my program faster. I would like to know if is it possible to retrun the values read by a shell script to fortran code directly. I have to use shell scripts something like a subroutine/function in my fortran code. As my first thought (please correct me if I am wrong) is reading a file which has mixed type of data (hex, strings, integers, real numbers) through a shell scripts and storing it in another file and reading this file in fortran will not serve the purpose of making the program run faster.

Thanks,
Jagmohan
 
jags015 said:
... reading a file which has mixed type of data through a shell scripts and storing it in another file and reading this file in fortran will not serve the purpose of making the program run faster

Don't know - maybe not, but it makes your Fortran program shorter and simpler. Then, you will not need to program a data conversion, or to use a module for this purpose in your program, when it's probably of topic for the processing, which your Fortran program should do.
And maybe you can delegate the conversion task to your data producer, which could run the hex data through a short script and deliver you the decimal data file you need.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top