Page 1 of 1

[C] [Solved ]Why " fwrite " writes werid number as binary ?

Posted: 2024-11-14 20:29
by Hadi_Lovelorn
Hello Dears

I reversed the order of my code as :

Code: Select all


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <gmp.h>

int main(void)
{

FILE * fr, * fw;
char filename[201];
unsigned long int size = 0;
unsigned long int rt = 999999;
unsigned char ch[1] = {112};


printf("Enter filename : ");
fgets(filename, 200, stdin);
filename[strlen (filename) - 1] = '\0';
fr = fopen(filename, "rb+");

if (fr == NULL)
{
    fprintf(stderr, "Error during opening of file %s\n", filename);
    perror("");
    return 1;
}

fseek(fr, 0L, SEEK_END);
size = ftell(fr);
fseek(fr, 0L, SEEK_SET);

if (size == -1)
{

fprintf(stderr, "Size doesn't match\n'");
perror("");
return 1;

}

if ( size > SIZE_MAX)
{

fprintf(stderr, "The size of file is greater than acceptable\n");
perror("");
return 1;

}

unsigned char * buf = NULL;
buf = malloc((size_t)size);
if(buf == NULL)
{

	fprintf(stderr, "Buffer failure\n");
	perror("");
	return 1;

}

int r;
r = fread(buf, size, 1, fr);
printf("%d\n", r);
if (ferror(fr))
{
	fprintf(stderr, "Error during reading from file %s\n", filename);
	perror("");
	fclose(fr);
	return 1;
}
fclose(fr);
fr = NULL;

mpz_t x;
mpz_init(x);
mpz_t y;
mpz_init(y);

mpz_import(x, size, 1, (size_t)1u, 0, 0, buf);

mpz_root (y, x, rt);

int rootnum = 0;
unsigned long int num = rt;

do
{

	num = num/10;
	++rootnum;

}while(num != 0);

fw = fopen(filename, "wb+");
if(fw == NULL)
printf("File can't be written\n'");
if(ferror(fw))
{

fprintf(stderr, "Error during writing to file %s\n", filename);
	perror("");
	fclose(fw);
	return 1;
	
}
int w;
w = fwrite(&rt, rootnum, 1, fw);
printf("%d\n", w);

fclose(fw);

fw = fopen(filename, "ab+");
if(fw == NULL)
printf("File can't be written\n'");
if(ferror(fw))
{

	fprintf(stderr, "Error during writing to file %s\n", filename);
	perror("");
	fclose(fw);
	return 1;
	
}
fwrite(ch, 1, 1, fw);

fclose(fw);

memset (buf, 0u, size);

mpz_export(buf, NULL, 1, (size_t)1u, 0, 0, y);

printf("\nEnter copied filename : ");
fgets(filename, 200, stdin);
filename[strlen (filename) - 1] = '\0';

fw = fopen(filename, "ab+");
if (fw == NULL) {
	fprintf(stderr, "Error during opening of file %s\n", filename);
	perror("");
	return 1;
}

fwrite(buf, mpz_sizeinbase(y, 10), 1, fw);
if (ferror(fw)) {
	fprintf(stderr, "Error during writing to file %s\n", filename);
	perror("");
	fclose(fw);
	return 1;
}

fclose(fw);


free(buf);
mpz_clear(x);
mpz_clear(y);

return 0;

}

And this is what I get :

Screenshot of GHex

I entered a 1.1 GB file and rt is 999,999 but fwrite writes it as 44 bytes I convert it to decimal both as littleendian and bigendian but there's no true number ....

Can Anyone Help ?

Thnaks

Re: [C] Why " fwrite " writes werid number as binary ?

Posted: 2024-11-14 20:37
by lindi
Can you provide a more minimal example? Just remove all the irrelevant parts please? Also print all arguments of fwrite and show us the output. The second argument of fwrite should be number of bytes to copy, what is the purpose of that "num/10" expression? The size of "rt" is fixed, there is no need to calculate it at run time, just use sizeof()?

Re: [C] Why " fwrite " writes werid number as binary ?

Posted: 2024-11-14 21:43
by Hadi_Lovelorn
lindi

Minimal code :

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <gmp.h>

int main(void)
{

FILE * fr, * fw;
char filename[201];
unsigned long int size = 0;
unsigned long int rt = 999999;
unsigned char ch[1] = {112};

printf("Enter filename : ");
fgets(filename, 200, stdin);
filename[strlen (filename) - 1] = '\0';
fr = fopen(filename, "rb+");

fseek(fr, 0L, SEEK_END);
size = ftell(fr);
fseek(fr, 0L, SEEK_SET);

unsigned char * buf = NULL;
buf = malloc((size_t)size);

fread(buf, size, 1, fr);

fclose(fr);
fr = NULL;

mpz_t x;
mpz_init(x);
mpz_t y;
mpz_init(y);

mpz_import(x, size, 1, (size_t)1u, 0, 0, buf);

mpz_root (y, x, rt);

int rootnum = 0;
unsigned long int num = rt;

do
{

	num = num/10;
	++rootnum;

}while(num != 0);

fw = fopen(filename, "wb+");

fwrite(&rt, rootnum, 1, fw);

fclose(fw);

fw = fopen(filename, "ab+");

fwrite(ch, 1, 1, fw);

fclose(fw);

memset (buf, 0u, size);

mpz_export(buf, NULL, 1, (size_t)1u, 0, 0, y);

printf("\nEnter copied filename : ");
fgets(filename, 200, stdin);
filename[strlen (filename) - 1] = '\0';

fw = fopen(filename, "ab+");

fwrite(buf, mpz_sizeinbase(y, 10), 1, fw);

fclose(fw);


free(buf);
mpz_clear(x);
mpz_clear(y);

return 0;

}

Since the operation of program is so heavy and takes so much time I can't print all arguments of fwrite right now .... But I can do it later

This is a scratch , I want to write a compression application , and rt will change on every step to compress file ...

Thank You for giving Your time and attention to me

Re: [C] Why " fwrite " writes werid number as binary ?

Posted: 2024-11-14 21:50
by lindi
If you want somebody else to debug this you also need to provide some input file. Also, zstandard is a really good compression solution, I recommend taking a look :)

Re: [C] Why " fwrite " writes werid number as binary ?

Posted: 2024-11-14 22:08
by Hadi_Lovelorn
lindi

Once I was free ...... I'm political activist in Iran and the government took me to mental hospital and I'm forced to take heavy psycho-atric medicines ...... Also they put aluminium in my food several months ago ....... Otherwise I wasn't bad in coding ....... I wrote partially C Programming Language in Farsi Wikibooks ........ And I wrote great codes in there ....... I searched for zstandard ; It compress 22 times at best and least size ....... My program makes a 4 GB file to 15 bytes and I'm gonna make it textual so can be written on paper and any one can take it everywhere ......

Re: [C] Why " fwrite " writes werid number as binary ?

Posted: 2024-11-15 13:38
by blackbird
You still use the sizes of a base 10 representation for the binary data you write. We had this topic here one month ago. So first you could change to base 256 when you write byte (num = num/256; and mpz_sizeinbase(y, 256).

And reducing a 4GB file to 15 bytes is possible, but the inverse function will only work for maximum 256^15 different files. So having a general algorithm to reduce file sizes won't work like this. For very special use cases this might work. E.g. only having files which consist completely of the same byte could be reduced to a very small size if this property is known beforehand.

Re: [C] Why " fwrite " writes werid number as binary ?

Posted: 2024-11-15 18:35
by Hadi_Lovelorn
blackbird

Hello Sir

In the GMP tutorial it's said :
Return the size of op measured in number of digits in the given base. base can vary from 2
to 62.
And num/256 will be for hex numbers while we are working with decimal numbers

And for decompression I will use exponentiation and remained numbers ..... It's possible but heavy algorithm is needed that I can't do it now with these garbage psycho-atric medicines .......

Re: [C] Why " fwrite " writes werid number as binary ?

Posted: 2024-11-16 16:40
by Hadi_Lovelorn
I fixed it by separating input file name and output file name .......

Thanks