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 Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to switch between text and binary mode?

Status
Not open for further replies.

Darkwing99

Programmer
May 21, 2003
21
DE
Hello,

I have a "binary" dataset on an z/OS-system where I have to put some LineFeeds at special positions.
If I open the output-dataset in "binary"-mode (e.g. "wb") the '\n' will not be a real LineFeed and if I open it in "text"-mode all HEX'15' of my input-data will be converted to real LineFeeds.

I found a solution in reopen the output-file for every LineFeed. But it uses plenty of time.

Is there a way to switch the mode without close/open the dataset?

Regards,
Thomas
 
> If I open the output-dataset in "binary"-mode (e.g. "wb") the '\n' will not be a real LineFeed
Meaning what?

Just throwing a few linefeeds '\n' into a (binary) file doesn't make it a text file which you can handily read using say fgets().

> if I open it in "text"-mode all HEX'15' of my input-data will be converted to real LineFeeds.
So it really is a binary file then, best keep all access to it as binary then if you want to avoid all these text-mode translations.

If it's a binary file, and you want those '\n' to mean something when you read it (like being a record terminator), then you're going to have to write your own
bin_fgets() and bin_fputs()
which have similar semantics to the text-mode fgets() and fputs()

> I have a "binary" dataset on an z/OS-system where I have to put some LineFeeds at special positions
What does this achieve - apart from some confusion?
What does a '\n' at a non-special position mean, and how would you tell the difference?
 
To explain why I have to insert LineFeeds (LF) in a binary dataset:

The dataset was transfered "binary" from an UNIX-system to the z/OS-Host. The original format was VB, this means every line has a different lenght defined by an 4-byte-length-field at the beginning of each row.
But during the tranfer all LFs vanished so that all lines are in one long row.

To use the dataset as an input for some COBOL-programs, I had to restore the missing LFs by reading the first length-field, copy this amount of bytes in a new dataset, write a LF, read the next length-field and so on....

Maybe there is a better way to do this but I don't see it :-(

Regards,
Thomas
 
> But during the tranfer all LFs vanished so that all lines are in one long row.
Have you tried fixing this process?

> I had to restore the missing LFs by reading the first length-field,
Well this is my stab at it
Code:
#include <stdio.h>

int main ( ) {
    FILE *in, *out;
    int reclen;
    int ch, i;

    in = fopen( &quot;in&quot;, &quot;rb&quot; );
    out= fopen( &quot;out&quot;,&quot;wb&quot; );

    while ( fread( &reclen, sizeof(reclen), 1, in ) == 1 ) {
        fwrite( &reclen, sizeof(reclen), 1, out );
        for ( i = 0; ((ch=fgetc(in)) != EOF ) && i < reclen ; i++ ) {
            fputc( ch, out );
        }
        fputc( '\n', out );
    }

    fclose( out );
    fclose( in );
    return 0;
}
 
First something I find out:
A &quot;real LF&quot; is a combination of CarrierReturn (CR) and LF.
If you write '\n' to a text-file it is automatic converted to a real LF. If you write it to a binary-file no conversion will happen and so no real LF is in your output.


> Have you tried fixing this process?

The only way to fix the transfer was to choose &quot;text&quot; as data-type and then some of the binary-field are &quot;converted&quot; like X'15' to LF


> Well this is my stab at it

Looks similar to my code and so it will not work.
If you open the out-dataset with &quot;wb&quot; (=binary) the command
Code:
  fputc( '\n', out );
will just write a X'15'. (see above: real LF = CR + LF)

I also tried to write
Code:
  fprintf(out, &quot;\r\n&quot;);
but it didn't work either.

Regards,
Thomas
 
cant you just add the LF and CR as individual characters if you need them.

text mode - add LF (get LF and CR)

binary mode - add LF and CR separately.

fputc( '\n', out );
fputc( '\r', out );// do it in hex or whatever.


I dont know Im just a beginner.

tomcruz.net
 
Darkwing99, when you refer to &quot;real LF&quot; it makes me twitch. There is no such thing as a fake LF, hence no real LF neither. You problem is due to the fact that platform handle newlines differently (I guess you figured that out by now). In binary there is no such thing as a newline. If you open a binary file into a text editor you sure may see some newlines but that's because the editor forces textmode on the binary file (i.e. all 0x0A and/or 0x0D to newlines depending the platform you're on). Looks like you made a real mess out of a usually simple task of transfering. I'd check into my transfer method if I were you. But if you really must edit your file, then do so in binary mode and add the carriage return (cr or \r) manually before each line feed (lf or \n) in a numerical represention. 0x0D for hex or 13 for decimal before any 0x0A for hex or 10 decimal.

hope that helps
 
There must be a difference between writing 0x0D and 0x15 (CR and LF in EBCDIC) in binary and '\n' in text-mode but I didn't find it. The '\n' in text works, the other not.

Maybe it's z/OS that needs some more to interpret the two bytes as CRLF.
If I reopen the output with
Code:
   out = reopen(&quot;DD:OUTPUT&quot;,&quot;ab&quot;)
there is a break and the new data is in the next line.
Maybe there is a HEX-Code for EndOfLine or something like that.

The transfer method cannot be changed for the same reason. If I transfer the data in text-mode it will destroy some of my binary data and vice versa.

Now I reopen the output for every line. It takes 1 hour to transfer the data and another 6 hours to &quot;repair&quot; it.....
I hope I will not have to use it very often.



Thanks for all help.

Regards,
Thomas
 
Hey, it gets better: in the good old days of dot matrix printers, a lot of them had a dip-switch inside that allowed you to set them to insert a line feed every time they saw a carriage return. The makers of dot-matrix printers knew that different platforms treat carriage returns differently. In the end these are all just numbers in a file. You can manipulate them quite happily as numbers, ignoring the text side of it. And make them so they look right on your particular platform, but remembering they might not on someone else's...
 
> There must be a difference between writing 0x0D and 0x15 (CR and LF in EBCDIC) in binary
So you're saying that
Code:
FILE *fp = fopen( &quot;test&quot;, &quot;wb&quot; );
fputc( '\r', fp );
fputc( '\n', fp );
fclose( fp );
should result in a file containing two bytes 0x0D and 0x15, since you're on an EBCDIC machine.

Now most people have an ASCII mind-set and associate '\n' with 0x0A, but it should be the case that '\n' is converted by the compiler into the newline character of the host implementation character set (0x15 in this case).

If this is messing up for some reason, you could try just being specific.
Code:
fputc( '\x15', fp );  /* should be a newline */
 
As long as I compile my source with an host-c-compiler (C/370) I assume that '\n' is translated by 0x15.

But simple write the two bytes in binary doesn't result in a CRLF. I tried it in more than one way:

Code:
putc('\r',out);
putc('\n',out);

or

fprintf(out,&quot;\r\n&quot;);

or

char r = 0x0D;
char n = 0x15;

putc(r,out);
putc(n,out);

All produce the same data:
just two bytes in the middle of a row.



Regards,
Thomas
 
Just out of curiosity I would read a file on the apropriate machine that has the proper &quot;LF&quot;. and display the output as hex just to see if I was missing anything. or maybe use a hex editor to read the file. This would be one of my methods to cover all posibilities. Im sure when the answer shows itself it will be obvious in hindsight. Its got to be very simple. as lionhill says its just numbers.

tomcruz.net
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top