How to convert a binary array into one single variable? - c

I have an binary array and i am trying to convert this into a single variable so that i can read the binary bitwise consecutively. I have tried looping over the array and adding each of them into a variable but this has not work. Can anyone give me some pointers into how to do this?
This is what i have tried:
char* filename = vargs[1];
BYTE buffer[BUFFER_SIZE];
FILE *file_ptr = fopen(filename,"rb");
fseek(file_ptr, 0, SEEK_END);
size_t file_length = ftell(file_ptr);
rewind(file_ptr);
fread(buffer, sizeof(BYTE), BUFFER_SIZE, file_ptr);
char binaryLine = '\0';
for (int i = 0; i > file_length; i++)
{
binaryLine += buffer[i];
printf("%d ", (int)buffer[i]);
}

Maybe there is some miss understanding, but when you read a file in a char* or char[], that is one variable.
Maybe try below code, and see what your missing.
Pay attention to, just to name a few:
for instruction, need to be true to continue
fread you need to get the amount of bytes read to loop it
main, it's a function or it's main, show it
fopen etc, would also neeed you to check for errors, which might help you to figure out why something does not work
regarding your question, It's important to ask a question and provide info, as stated in other comment, what do you want....
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
const char* filename = argv[1];
char * buffer=NULL;
FILE *file_ptr = fopen(filename,"rb");
if (! file_ptr) return 1;
fseek(file_ptr, 0, SEEK_END);
size_t file_length = ftell(file_ptr);
rewind(file_ptr);
if (file_length!=0)
buffer=calloc(1,file_length);
if (buffer)
{
size_t bytes_read=fread(buffer, 1, file_length, file_ptr);
for (int i = 0; i < bytes_read; i++)
{
printf("%d ", (int)buffer[i]);
}
free(buffer);
buffer=NULL;
return 0;
}
return 1;
}

Related

Using od command

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char* argv[]) {
char *filename = argv[1];
char *store = malloc(2);
FILE *fh = fopen(filename, "wb");
for(int i = 0; i < 100; i++) {
sprintf(store, "%u", i);
if (fh != NULL) {
fwrite (store, sizeof (store), 1, fh);
}
}
fclose (fh);
return 0;
}
I want my output to look like this -> https://imgur.com/a/nt2ly. The output it produces currently is all garabge.
The real reason for the garbage is the size of your data on the fwrite statement
fwrite (store, sizeof (store), 1, fh);
sizeof(store) is not the size of the string. It's the size of the pointer.
Aside, allocating 2 bytes for store is wrong. You're forgetting that a 2-digit number as a string needs space for a nul-terminator, so you're writing one char too many.
More minor issue: why testing the handle against NULL in the loop? you could exit in that case.
Also test the argument length (argc).
int main(int argc, char* argv[]) {
if (argc<2) exit(1); // protect against missing arg
char *filename = argv[1];
char store[50]; // use auto memory, faster & simpler, don't be shy on the size, don't shave it too close
FILE *fh = fopen(filename, "wb");
if (fh != NULL) { // test file handle here, not in the loop
for(int i = 0; i < 100; i++) {
// sprintf returns the number of printed chars, use this
// also use the proper format specifier for int
int nb_printed = sprintf(store, "%d", i);
// you may want to check the return value of fwrite...
fwrite (store, nb_printed, 1, fh);
}
fclose (fh);
return 0;
}
Note that this code will create a binary file with all numbers collated:
01234567891011...
so hardly useable. I would perform a sprintf(store, "%d ", i); instead to add spacing between the numbers.
Also note that if you wanted to write characters in a file, you'd be better off with:
fprintf(fh,"%d ",i);
(but I suppose the main point is to learn to use fwrite)

SHA - Output of program is different from sha512sum command

In summary, I program for first time with openssl/sha.h and everything goes right in compilation. here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <openssl/sha.h>
int main()
{
int j;
FILE *hash_file = fopen("hash.txt", "wb");
for(j = 0; j < 256; j++)
{
unsigned char md[SHA512_DIGEST_LENGTH];
char* fileName = malloc(sizeof(int));
sprintf(fileName, "%X%s", j, ".txt");
int i;
FILE *file = fopen(fileName, "rb");
SHA512_CTX mdcontext;
int bytes;
unsigned char data[2048];
if(file == NULL)
{
printf("%s can not be opened\n", fileName);
return;
}
SHA512_Init(&mdcontext);
while((bytes = fread(data, 1, 2048, file) != 0))
SHA512_Update(&mdcontext, data, bytes);
SHA512_Final(md, &mdcontext);
for(i = 0; i < SHA512_DIGEST_LENGTH; i++)
{
printf("%x", md[i]);
fprintf(hash_file, "%x", md[i]);
}
// fprintf(hash_file, "\n");
printf("\n");
free(fileName);
fclose(file);
}
fclose(hash_file);
return 0;
}
and I have this output :
711c22448e721e5491d8245b49425aa861f1fc4a15287f735e23799b65cffec5b5abdfddd91cd643aeb3b530d48f5e258e7e230a94ed525c1387bb4e1b
But when I hash same file with sha512sum command in Linux i got this output:
6e3ea4bec3cd738f06f011c2f4ee4f6cd6d12205cafe41c083d52f94d9de4ab8b9e702664a367b633be14024a96e88a140a2e7fee4dc2c6e2f0bd436e281e35b make.sh
what is the problem?
Oh boi!
A tiny little parantheses can make you pull your hair out.
The problem is in this statement while((bytes = fread(data, 1, 2048, file) != 0)). You see, in this statement the != condition will be evaluated first. So, when fread reads (and returns), let's say n number of characters, it checks if n!=0. If it evaluates to true then it sets bytes to 1 (true is casted to 1).
And now, the function SHA512_Update(&mdcontext, data, bytes); becomes SHA512_Update(&mdcontext, data, 1); while it should have been SHA512_Update(&mdcontext, data, n); (where n is the number of characters successfully read).
Solution
Change while((bytes = fread(data, 1, 2048, file) != 0)) to while((bytes = fread(data, 1, 2048, file)) != 0).
Update [Saving the hash in a char array]:
The output of SHA512 is of 128 characters. So, we need a char array of size twice that of SHA512_DIGEST_LENGTH (64). Then, we can just store it in the char array using sprintf.
char hash[SHA512_DIGEST_LENGTH*2];
for(i = 0; i < SHA512_DIGEST_LENGTH; i++)
sprintf(&hash[i*2], "%02x", md[i]);
Why i*2? Because output has a width of 2 bytes. So, result will be stored at hash[i] and hash[i+1].
Now, to print it:
for(i = 0; i < SHA512_DIGEST_LENGTH*2; i++)
printf("%c", hash[i]);
PS:
Read about precedence.
And don't forget to follow the advices in comments to your post, especially the one about using %02x by Steve.

Fast double file read in C

I have a large file containing floating point numbers and I want to read them.
52.881 49.779 21.641 37.230 23.417 7.506 120.190 1.240 79.167 82.397 126.502 47.377 112.583 124.590 103.339 5.821 24.566 38.916 42.576
This is just the beggining of the file. It has 10000000 numbers.
I got this code but I don't know how to print the numbers.
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <fcntl.h>
#include <sysexits.h>
#include <unistd.h>
int main()
{
int fd;
size_t bytes_read, bytes_expected = 1000000*sizeof(double);
double *data;
char *infile = "file.dat";
if ((fd = open(infile,O_RDONLY)) < 0)
err(EX_NOINPUT, "%s", infile);
if ((data = malloc(bytes_expected)) == NULL)
err(EX_OSERR, "data malloc");
bytes_read = read(fd, data, bytes_expected);
if (bytes_read != bytes_expected)
err(EX_DATAERR, "Read only %d of %d bytes",
bytes_read, bytes_expected);
/* print all */
free(data);
exit(EX_OK);
}
You are attempting to read a text file as if the data was binary, so you will read some bytes but the double values stored in the array will not be the values that you wanted to read from the file, you can probably do this
FILE *file;
double *array;
size_t count;
const char *infile = "file.dat";
file = fopen(infile, "r");
if (file == NULL)
return -1;
count = 0;
while (fscanf(file, "%*lf") == 1)
count += 1;
rewind(file);
array = malloc(count * sizeof(*array));
if (array == NULL) {
fprintf(stderr, "cannot allocate %zu bytes!\n", count * sizeof(*array));
fclose(file);
return -1;
}
// Read the values into the array
for (size_t i = 0; i < count; ++i) {
fscanf(file, "%lf", &array[i]);
}
// Print the array
for (size_t i = 0; i < count; ++i) {
fprintf(stdout, "%f\n", array[i]);
}
// Release memory
free(array);
Since you want a fast solution, maybe you have to sacrifice memory.
The faster manner of reading a file is in binary form.
Thus, I would obtain the file size with an efficient method,
then I would allocate memory accordingly,
with the idea of uploading the entire file to memory.
There, since memory reading is faster than file reading,
the data can be quickly read by using sscanf(...).
We can also observe that each floating point number
needs at least 3 characters to be stored in a text file:
1 char for the dot ('.'),
1 char for some digit,
and 1 char for
a space (' ') used to separating a value from its succesor in the
file.
Thus, the file size divided by 3 will be the upper bound for the size of the array of doubles.
#include <stdio.h>
int main(void) {
char *filename = "file.dat";
FILE *F = fopen(filename, "rb");
fseek(F, 0L, SEEK_END);
long int filesize = ftell(F);
rewind(F);
char *data = malloc(filesize+1);
fread(data, filesize, 1, F);
data[filesize] = '\0'; // End of string, just in case
fclose(F);
// The desired data will be stored in array:
double *array = malloc(sizeof(double) * filesize/3);
int ret;
int n; // represents the no chars in a sscanf(...) reading
double *a = array;
while (1) { // Infinite loop...
ret = sscanf(data, " %lg%n", a, &n);
if (ret == EOF) break; // <<---- EXIT POINT of the loop
a++;
data += n;
}
long int array_size = a - array + 1;
}

C memory allocation with File input

Hello i have a problem with memory allocation,
1. open file
2. take lenght of text inside
3. make buffer in size of lenght (array[] ? malloc ?)
4. make operations on text in buffer.
5. close
it terminates when text any longer than 1xx characters i have no idea whats going on.
ps.attention! im learning and quality of this code can be bad
#include <stdio.h>
#include <stdlib.h>
void copy_to_buffer(FILE *fp, int length, char *buffer){
for(int i = 0; i < length; i++){
char c = fgetc(fp);
buffer[i] = c;
}
}
int length_of_text(FILE *fp) {
fseek(fp, 0L, SEEK_END);
int size = ftell(fp);
rewind(fp);
return size;
}
void char_counter(int length, char *buffer, int *charBuffer) {
int counts[128] = { 0 };
for (int i = 0; i < length; i++) {
counts[(int)(buffer[i])]++;
charBuffer[i] = counts[i];
}
for (int i = 0; i < 128; i++) {
charBuffer[i] = counts[i];
if(counts[i] != 0)
printf("%d.(%c) counted: %d times.\n", i,i, counts[i]);
}
}
/***********************************MAIN***********************************/
int main(int argc, char** argv) {
FILE *fp = fopen("tekst.txt" , "r");
int length = length_of_text(fp); //lenght of text
char *buffer = malloc(sizeof(char)*length); //buffer for text from file
if(buffer == NULL)
printf("error");
else
printf("alocated at = %p\n", &buffer);
int charBuffer[128] = {0}; // charcount buffer
buffer[length] = '\0'; // '\0' after last sign
copy_to_buffer(fp, length, buffer);
char_counter(length, buffer, charBuffer);
free(buffer);
fclose(fp);
return 0;
}
In this line
charBuffer[i] = counts[i];
you will overflow charBuffer[128] when the file size is >= 128, since i is indexing by up to the length of the file.
In your char_counter function you do
charBuffer[i] = counts[i];
in the first for loop but buffer is only defined to be 128 ints. If the text is longer than 128 characters this will cause a buffer overflow and a segmentation fault.
Remove that line and let the 2nd for loop do it.

convert unsigned int to char alphabets

I have the following code that converts a stream data of 16-bit integer to unsigned 8-bit integer.
I am looking to convert them to alphabetical data values and see what they contain.
#include<stdio.h>
int main() {
FILE *fp,*out;
char buffer[256];
size_t i = 0;
fp=fopen("c:/Gosam/input.txt", "rb");
if(fp != NULL) {
fread(buffer, sizeof buffer,1, fp);
}
out = fopen("c:/Gosam/res.txt", "w");
if(out != NULL) {
// buffer = (char*) malloc (sizeof(char)*Size);
for( i = 0; i < sizeof(buffer); i += 2)
{
const unsigned int var = buffer[i] + 256 * buffer[i + 1];
fprintf(out, "%u\n", var);
}
fclose(out);
}
fclose(fp);
}
The following is the form of my output:
263 4294966987 4294967222 4294967032 64 4294967013 73 4294967004 90
4294967028 83 4294966975 37 4294966961 5 4294966976 82 4294966942
4294967022 4294966994 11 4294967024 29 4294966985 4294966986 4294966954 50
4294966993 4294966974 4294967019 4294967007
This are the values I want to convert to alphabetical characters and see their content.
I don't know what you expect as an answer (you didn't ask a question), but there seems to be one suspicious thing in your code:
char buffer[256];
Here char means signed char. If your code does manipulations on them (like multiplying by 256), it probably doesn't do what you expect (though I can only guess what you expect - your question doesn't mention it).
Try the following:
unsigned char buffer[256];
Also please ask a question (that is, something with a question mark), and give some examples (input, output).
Your basic mistakes were:
after opening the inputfile checking out instead of fp against NULL
fread until eof won't return the number of characters that could be read (I've used fseek and ftell for this purpose)
writing uint values instead of char values to your file
I've fixed them and commented the affected lines appropriate. I also changed the buffer to use dynamic memory allocation instead of static allocation (that's how you can allocate memory for a buffer of a size that is unknown at compile-time). Please try the following code, which will copy all ASCII characters from one file to your output file (which is probably what you meant by 'alphabetical strings'):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
FILE *fp, *out;
char *buffer = NULL; /* use a pointer for dynamic memory allocation */
size_t i = 0, charCount = 0;
fp = fopen("c:/input.txt", "r"); /*read as ascii - not binary */
if(fp != NULL){ /*use 'fp' here 'out' is not initalized */
fseek(fp, 0, SEEK_END); /* go to end of the file */
charCount = ftell(fp) - 1; /* get position */
fseek(fp, 0, SEEK_SET); /* return to the beginning of the file */
buffer = (char*)malloc(sizeof(char)*charCount); /* allocate memory */
fread(buffer, sizeof(char) * charCount, 1, fp); /* reads all characters from the file */
}
out = fopen("c:/output.txt", "w");
if(out != NULL){
for(i = 0; i < charCount; i += 1){ /* loop from 0 to count of characters */
const unsigned char var = buffer[i];
fprintf(out, "%c", var);
}
fclose(out);
}
fclose(fp);
if(buffer != NULL){
free(buffer); /* deallocate memory */
}
return 0;
}

Resources