Wrong data is written to binary file [duplicate] - fwrite

I'm using a large array of floats. After a lot of fiddling I've managed to write it to a binary file. When opening that file at a later time, the reading process only reads a couple of handfuls of floats (according to the return-value of fread(), and it's all values 0.0f). The reading is supposed to put the floats into an (the original) array, and it does not contain the original values.
I'm using Code::Blocks and MinGW doing a program in the 32bit realm on a 64bit pc .. and I'm not very proficient on c/c++ and pointers.
#include<...>
const int mSIZE = 6000 ;
static float data[mSIZE*mSIZE] ;
void myUseFunc(){
const char *chN = "J:/path/flt_632_55.bin" ;
FILE *outFile=NULL ;
# .. sucessfully filling and using data[]
..
size_t st = mSIZE*mSIZE ;
outFile = fopen( chN , "w" ) ;
if(!outFile){ printf("error opening file %s \n", chN); exit(0);}
else{
size_t indt;
indt = fwrite( data , sizeof(float), st , outFile );
std::cout << "floats written to file: " << indt << std::endl ;
#.. value shows that all values ar written
# and a properly sized file has appeared at the proper place
}
fclose( outFile ) ;
}
void myLoadFunc( const char *fileName){
FILE *inFile = NULL ;
inFile = fopen( fileName, "r");
if(!inFile){ printf("error opening file %s \n", fileName); exit(0); }
size_t blok = mSIZE*mSIZE ;
size_t out;
out = fread( dataOne, sizeof(GLfloat), blok , inFile);
fclose(inFile);
if(out != blok){
std::cout<< out << std::endl ;
fputs ("Reading error",stderr);
# no stderr presented at the console ..
printf("some error\n") ;
exit(0);
# .. program exits at out=14
}
...
}
int main( ){
...
const char *FileName = "J:/path/flt_632_55.bin" ;
myLoadFunc( FileName ) ;
...
}

You are not writing to/reading from a binary file, you open the files as text files.
You need to add the "b" to the open mode, like
outFile = fopen( chN , "wb" ) ;

Related

How to make an input a file name?

I would like to take an input from the user and make this input a file name which I will be writing on my code after taking the input.
I would be appreciated if you could help me on this.
Thanks in advance!
MATLAB
filename = input('File name: ','s');
fileID = fopen(filename)
fprintf(fileID, 'That wasn''t so hard')
fclose(fileID)
input - Request user input
fopen - Open file, or obtain information about open files
fprintf - Write data to text file
Python
filename = raw_input('File name: ')
with open(filename, 'w') as f:
f.write('That wasn\'t so hard')
C
#include <stdio.h>
int main() {
char filename[81];
FILE* f;
while (1) {
printf("File name: ");
if (scanf("%80s") == 1) break;
}
f = fopen(filename, "w");
if (!f) {
perror("opening file");
return 1;
}
fprintf(f, "That wasn't so hard\n");
fclose(f);
return 0;
}
sh script
#!/bin/sh
echo -n "File name: "
read filename
echo "That wasn't so hard" > $filename

How to perform operation on specific bits in perl

Lets assume I have a hexadecimal value 0x78. I need to add 1 to first 4 bits ie 3:0 and add 2 to last 4 bits ie. [7:4]. Further when I add 1 to 0xF it should not roll over to the next value and should stay as 0xF. Same applies for subtraction. The approach I have tried so far is:
$byte=0x78;
$byte2 = unpack('b4', $byte);
print "byte2 = $byte2 \n";
--> Here the output is 1000 so I have tried to extract the first 4 bits, and similarly I can right shift and extract last 4 bits and perform the operation.
But to perform addition or subtraction, I wanted to convert 1000 back to hex format so that I can do 0x8 +/- 1. For that I tried:
$hex2 = sprintf('%02x', $byte2);
print "hex2 = $hex2 \n";
--> Output is 3e8. I do not understand why I get 3e8 instead of just 8 or 08, since it is supposed to print only 2 values in hex format.
In the above command when I manually enter
$hex2 = sprintf('%02x', 0b1000); I get the correct result. So perl is taking it as a string rather than a numeric value. Is there some way I can convert that string to a binary number? Any other easier method or approach would be helpful.
We can get each byte by ANDing and shifting:
$byte1 = $byte & 0xf;
$byte2 = ($byte & 0xf0) >> 4;
printf "byte1: 0x%x\n", $byte1;
printf "byte2: 0x%x\n", $byte2;
# prints
byte1: 0x8
byte2: 0x7
Addition/subtraction with special conditions you listed can be done on these bytes and the new value can be reconstructed with shifts and addition:
($byte1 < 0xf) ? ($byte1 += 1) : ($byte1 = 0xf);
($byte2 < 0xe) ? ($byte2 += 2) : ($byte2 = 0xf);
# or do subtraction stuff.
$new_val = ($byte2 << 4) + $byte1;
printf "new val: 0x%x\n", $new_val;
# prints
new val: 0x99
You're getting '3e8' because $byte2 is '1000', which, when translated into hex is '0x3e8'.
I think you're better off with something like:
sub byte_to_two_nibbles($) {
my $byte = shift;
return int($byte / 16), ($byte % 16);
}
sub two_nibbles_to_byte($$) {
return $_[0] * 16 + $_[1];
}
my ($msn, $lsn) = byte_to_two_nibbles 0x78;
$msn += 1; $msn = 15 if $msn > 15;
$lsn += 2; $lsn = 15 if $lsn > 15;
my $result = two_nibbles_to_byte $msn, $lsn;
You can use oct function:
$byte2 = oct("0b$byte2");
my $hex2 = sprintf('%02x', $byte2);
print "hex2 = $hex2 \n";
Prints:
hex2 = 08

Altering multiple text files using grep awk sed perl or something else

I have multiple text files named split01.txt, split02.txt etc... with the data in the format below: (This is what I have)
/tmp/audio_files/n000001.wav;
/tmp/audio_files/n000002.wav;
/tmp/audio_files/n000003.wav;
/tmp/audio_files/p000004.wav;
/tmp/audio_files/p000005.wav;
I would like to create another file with the data taken from the split01.txt, split02.txt etc... file in the format below: (this is the format I would like to see)
[playlist]
NumberOfEntries=5
File000001=n000001.wav
Title000001=n000001.wav
File000002=n000002.wav
Title000002=n000002.wav
File000003=n000003.wav
Title000003=n000003.wav
File000004=p000004.wav
Title000004=p000004.wav
File000005=p000005.wav
Title000005=p000005.wav
Version=2
Can this be done in one instance? The reason I ask is that I'm going to be running/calling the command (awk,grep,sed,etc...) from inside of octave/matlab after the initial process has completed creating the audio files.
example: of what I mean in one instance below: (matlab/octave code)
system(strcat({'split --lines=3600 -d '},dirpathwaveformstmp,fileallplaylistStr,{' '},dirpathwaveformstmp,'allsplit'))
This splits a single file into multiple files with the names allsplit01 allsplit02 etc.. and each file only has a max of 3600 lines.
For those who asked this is creating playlist files for audio files I create with octave/matlab.
Any suggestions?
Here's one way you could do it with awk:
parse.awk
BEGIN {
print "[playlist]"
print "NumberOfEntries=" len "\n"
i = 1
}
{
gsub(".*/|;", "")
printf "File%06d=%s\n" , i, $0
printf "Title%06d=%s\n\n", i, $0
i++
}
END {
print "Version 2"
}
Run it like this:
awk -v len=$(wc -l < infile) -f parse.awk infile
Output:
[playlist]
NumberOfEntries=5
File000001=n000001.wav
Title000001=n000001.wav
File000002=n000002.wav
Title000002=n000002.wav
File000003=n000003.wav
Title000003=n000003.wav
File000004=p000004.wav
Title000004=p000004.wav
File000005=p000005.wav
Title000005=p000005.wav
Version 2
If you're writing your program in Octave, why don't you do it in Octave as well? The language is not limited to numerical analysis. What you're trying to do can be done quite easily with Octave functions.
filepath = "path for input file"
playlistpath = "path for output file"
## read file and prepare cell array for printing
files = strsplit (fileread (filepath)', "\n");
if (isempty (files{end}))
files(end) = [];
endif
[~, names, exts] = cellfun (#fileparts, files, "UniformOutput", false);
files = strcat (names, exts);
files(2,:) = files(1,:);
files(4,:) = files(1,:);
files(1,:) = num2cell (1:columns(files))(:);
files(3,:) = num2cell (1:columns(files))(:);
## write playlist
[fid, msg] = fopen (playlistpath, "w");
if (fid < 0)
error ("Unable to fopen %s for writing: %s", playlistpath, msg);
endif
fprintf (fid, "[playlist]\n");
fprintf (fid, "NumberOfEntries=%i\n", columns (files));
fprintf (fid, "\n");
fprintf (fid, "File%06d=%s\nTitle%06d=%s\n\n", files{:});
fprintf (fid, "Version 2");
if (fclose (fid))
error ("Unable to fclose file %s with FID %i", playlistpath, fid);
endif

Convert the C Function to Perl

I am stuck while trying to convert the C function convertCNGFileToJPGFile mentioned in the program cng2jpg.c
I have been trying to write the same in Perl but don't have enough knowhow with hex,pack and unpack functions.
Would really appreciate if somebody can write a similar code in Perl as mentioned below.
while ((bytesRead = fread(buffer, 1, kBufferSize, inputFile))) {
if (!isValidCNG) {
if (bytesRead < 11 || strncmp("\xa5\xa9\xa6\xa9", (char *)(buffer + 6), 4)) {
fprintf(stderr, "%s does not appear to be a valid CNG file\n", inputFileName);
return 0;
}
isValidCNG = 1;
}
for (size_t i = 0; i < bytesRead; i++)
buffer[i] ^= 0xEF;
size_t bytesWritten = fwrite(buffer, 1, bytesRead, outputFile);
if (bytesWritten < bytesRead) {
fprintf(stderr, "Error writing %s\n", outputFileName);
return 0;
}
}
Thanks in advance.
If I'm reading the code right, all it's doing (besides the validity check) is XORing each byte in the file with the byte 0xEF (i.e. flipping all but the fifth lowest bit of each byte). In Perl, you could implement that with:
local $/ = \(2**16); # ignore line breaks, read in 64 kiB chunks
while (<>) {
$_ ^= "\xEF" x length;
print;
}
The validity check is just checking that the output is actually a valid JPEG file — specifically, that the 7th to 10th bytes of the output file contain the magic word "JFIF" (which becomes "\xa5\xa9\xa6\xa9" when XORed with 0xEF). Generally, unless you're expecting to frequently run this code on files which are not actually CNG files, I wouldn't bother with it, since it's easier to just check the validity of the output afterwards. (Besides, the check will fail if the decoded file is actually an Exif JPEG image, which have the magic word "Exif" instead.)
If you do want to include the check, something like this should do it:
local $/ = \(2**16); # ignore line breaks, read in 64 kiB chunks
while (<>) {
$_ ^= "\xEF" x length;
die "Not a valid CNG file" if $. == 1 and not /^.{6}(JFIF|Exif)/s;
print;
}
Ps. If this code runs too slow, I'd suggest two possible improvements: 1) use a larger buffer, and b) preallocate the mask of 0xEF bytes instead of rebuilding it on the fly each time:
local $/ = \(2**20); # ignore line breaks, read in 1 MiB chunks
my $mask = "\xEF" x $$/;
while (<>) {
$_ ^= substr($mask, 0, length);
die "Not a valid CNG file" if $. == 1 and not /^.{6}(JFIF|Exif)/s;
print;
}

md5 "%02x" fprintf

I have to calculate md5 hash for a file. I succesfully find libraries to do it, and they print the hash on screen.
I have to print the hash on a txt file, but I have some problems. It only prints 00 intead of the all 32 bit hash. This is the print function. I only add the lines to open the file and to print on it, the rest of the function is from the library and works fine, because on the screen the hash is printed in the right way.
Seems to be some kind of problems with fprintf and %02x". Thanks.
static void MDPrint (mdContext)
MD5_CTX *mdContext;
{
int i;
FILE *fp;
if((fp=fopen("userDatabase.txt", "ab"))==NULL) printf("Error while opening the file..\n");
else {
for (i = 0; i < 16; i++)
printf ("%02x", mdContext->digest[i]);
fprintf(fp, "%02x", mdContext->digest[i]);
}
fclose(fp);
}
Your problem is here;
for (i = 0; i < 16; i++)
printf ("%02x", mdContext->digest[i]);
fprintf(fp, "%02x", mdContext->digest[i]);
Since there are no curly braces, only the printf line will be inside the loop. You need to add braces to make both lines be inside the loop;
for (i = 0; i < 16; i++)
{
printf ("%02x", mdContext->digest[i]);
fprintf(fp, "%02x", mdContext->digest[i]);
}