reading from a binary file into an int - c

i'm a little puzzled about binary files and how to read from them, so if someone could help that would be great.
i have a file that contains the following bits:
00000000000000000000000000000111
(32 bits. i counted)
now i have written this code:
int main()
{
FILE * f1;
f1 = fopen("file2", "rb");
int i = 0;
fread(&i, sizeof(int), 1, f1);
printf("%d", i);
fclose(f1);
return 0;
}
that prints me 808464432.
why? shouldnt it print 7?
thank you for reading.

That is not a binary file, it's a text file, try this instead
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *file;
int value;
char text[33];
char *endptr;
file = fopen("file2", "r");
if (file == NULL) /* check that the file was actually opened */
return -1;
if (fread(text, 1, sizeof(text) - 1, f1) != sizeof(text) - 1)
{
fclose(file);
return -1;
}
text[32] = '\0';
value = strtol(text, &endptr, 2);
if (*endptr == '\0')
printf("%d", value);
fclose(file);
return 0;
}
To write a binary file you need this
#include <stdio.h>
void hexdump(const char *const filename)
{
FILE *file;
unsigned char byte;
file = fopen(filename, "rb");
if (file == NULL)
return;
fprintf(stdout, "hexdump of `%s': ", filename);
while (fread(&byte, 1, 1, file) == 1)
fprintf(stdout, "0x%02x ", byte);
fprintf(stdout, "\n");
}
int main()
{
const char *filename;
FILE *file;
int value;
filename = "file.bin";
file = fopen(filename, "wb");
if (file == NULL)
return -1;
value = 7;
if (fwrite(&value, sizeof(value), 1, file) != 1)
fprintf(stderr, "error writing to binary file\n");
fclose(file);
/* check that the content of the file is not printable, i.e. not text */
hexdump(filename);
file = fopen(filename, "rb");
if (file == NULL)
return -1;
value = 0;
if (fread(&value, sizeof(value), 1, file) != 1)
fprintf(stderr, "error writing to binary file\n");
else
fprintf(stdout, "The value read was %d\n", value);
fclose(file);
return 0;
}
as you will see from the example above, the stored data in file.bin is not in text format, you cannot inspect it with a text editor because the bytes 0x00 and 0x07 are not printable, in fact 0x00 is the nul byte which is used in c to mark the end of a string.

This is one way you can write and read to a binary file. you should know the difference between a binary and ASCII file, before reading from them.
Read this once https://stackoverflow.com/a/28301127/3095460 and understand what is type of file you are reading using your code.
if you open a file in an editor and see 00000000000000000000000000000111 it does not mean its a binary file, most of the editor process files as ascii text file only. you need a binary editor to open a binary file and read meaningful data from them.
#include <stdio.h>
int main()
{
FILE *Read_fptr = NULL;
FILE *Write_fptr = NULL;
int data = 20;
size_t nElement = 1;
if ( (Write_fptr = fopen("data.bin", "wb")) != NULL ) {
if ( fwrite(data, nElement, sizeof data, Write_fptr) != sizeof data ) {
fprintf(stderr,"Error: Writing to file\n");
fclose(Write_fptr);
return -1;
}
} else {
fprintf(stderr,"Error: opening file for writing\n");
return -1;
}
fclose(Write_fptr);
data = 0;
if ( (Read_fptr = fopen("data.bin", "rb")) != NULL ) {
if ( fread(data, nElement, sizeof data, Read_fptr) != sizeof data) {
if( !feof(Read_fptr) ) {
fprintf(stderr,"Error: Reading from file\n");
fclose(Read_fptr);
return -1;
}
}
} else {
fprintf(stderr,"Error: opening file for reading\n");
return -1;
}
fclose(Read_fptr);
printf("%d\n",data);
return 0;
}

Related

Its supposed to be a simple keyword search function imitating a national instruments function. Why wont it work?

I am trying to write this program in C. The intent of the program is to run a designated keyword search on one file, find the information stored on that line, and then copy that information to the same location in another file. The keyword is utilized to determine the line in the file to be copied and to replace. I am using Microsoft Visual. Built in ".c" I am receiving this message: " (process 24612) exited with code -1073741819"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable : 4996)
#define MAX_LENGTH 1000
void locate(const char* keyword, int start, int end, int lineCount, char* line, int* a, int* a_index) {
if (lineCount >= start && lineCount <= end) {
if (strstr(line, keyword) != NULL) {
a[*a_index] = lineCount;
(*a_index)++;
}
}
}
void replaceLines(const char* filename1, const char* filename2, const char* keyword, int start, int end) {
char buffer[MAX_LENGTH];
char line[MAX_LENGTH];
int lineCount = 0;
int i;
int a[20];
int a_index = 0;
// Open the first file in read
FILE* file1 = fopen(filename1, "r");
if (file1 == NULL) {
printf("Error opening file %s\n", filename1);
exit(1);
}
// Open the second file in read
FILE* file2 = fopen(filename2, "r");
if (file2 == NULL) {
printf("Error opening file %s\n", filename2);
exit(1);
}
// Read the first file into a buffer
while (fgets(buffer + strlen(buffer), MAX_LENGTH, file1)) {
;
}
// Close the first file
fclose(file1);
// Open the first file in read/write
file1 = fopen(filename1, "w+");
if (file1 == NULL) {
printf("Error opening file %s\n", filename1);
exit(1);
}
// Read file1 line by line
while (fgets(line, MAX_LENGTH, file1)) {
lineCount++;
locate(keyword, start, end, lineCount, line, a, &a_index);
}
lineCount = 0; //reset lineCount
// Read file2 line by line and copy line from file2 to buffer using the line found in file1 keyword search
while (fgets(line, MAX_LENGTH, file2)) {
lineCount++;
if (lineCount >= start && lineCount <= end) {
if (strstr(line, keyword) != NULL) {
strncpy(buffer + a[a_index] * MAX_LENGTH, line, MAX_LENGTH);
}
}
}
// Close the second file
fclose(file2);
// Write the modified buffer back to file1
fputs(buffer, file1);
// Close the first file
fclose(file1);
}
int main(void) {
replaceLines("c:\\LocationFolder\\Overwrite.txt", "c:\\LocationFolder\\Baseline.txt", "Simulated Primary Open", 3, 22);
return 0;
}

C recover compiles but return null for the files read

Trying to solve this problem i keep finding the same errors:
:) recover.c exists.
:) recover.c compiles.
:) handles lack of forensic image
:( recovers 000.jpg correctly
000.jpg not found
:( recovers middle images correctly
001.jpg not found
:( recovers 049.jpg correctly
049.jpg not found
That makes me think that the files are not been read or opened at all and i can't find why because the code compiles.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
int main(int argc, char* argv[])
{
//checks if there is an input
if (argc != 2)
{
printf("./recover Usage: ./recover image \n");
return 1;
}
else
{
char* filename = argv[1];
FILE* input = fopen(filename, "r");
if (strcmp(filename, "card.raw") != 0)
{
printf("Unable to open: %s\n", filename);
return 2;
}
else
{
//Create buffer
uint8_t buffer[512];
//Create pointer for the buffer
FILE* output = NULL;
// create 8 bytes file
char files[8];
//Files counters
int jpeg_counter = 0;
//Check
while (fread(buffer, sizeof(buffer), 1, input))
{
//check 4 first bytes of file to see if they contain the jpg signature
if ((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0))
{
if (output != NULL) {
// sprintf(char *str, const char *format, ...) and "03i" means 3 digits in format 001, 002...
sprintf(files, "%03i.jpg", jpeg_counter);
//use created pointer to save jpeg files from input folder card.raw
output = fopen(filename, "w");
//add jpeg to the new buffer using ouput pointer
fwrite(buffer, sizeof(buffer), 1, output);
// update counter
jpeg_counter++;
}
else //no more files to read(end of folder array) - or no images found.
{
printf("Could not open file\n");
return 0;
}
}
}
fclose(output);
fclose(input);
return 0;
}
}
}
Here is another attempt at a solution, however, it only writes out the first 512 bytes (unlike the original) but I don't think jpeg uses 512 bytes fixed chunks so neither the op or or #BarmakShemirani solution would work as expected. (buffer[3] & 0xf0) == 0xe0 means variable sized, application specific and there is a reference that data is laid out like TIFF, In either case op did not share card.raw so whatever format is used would be speculation:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILENAME_LEN 8
int main(int argc, char* argv[]) {
int r = 0;
FILE *input = NULL;
if (argc != 2) {
printf("./recover Usage: ./recover image \n");
r = 1;
goto out;
}
char *filename = argv[1];
input = fopen(filename, "rb");
if (!strcmp(filename, "card.raw")) {
printf("Unable to open: %s\n", filename);
r = 2;
goto out;
}
for(int jpeg_counter = 0; !r; jpeg_counter++) {
uint8_t buffer[512];
size_t n = fread(buffer, sizeof(buffer), 1, input);
// use an existing library instead?
if(
n < 4 ||
buffer[0] != 0xff ||
buffer[1] != 0xd8 ||
buffer[2] != 0xff ||
(buffer[3] & 0xf0) != 0xe0
) {
printf("invalid header\n");
r = 3;
break;
}
char filename2[FILENAME_LEN];
if(snprintf(filename2, FILENAME_LEN, "%03i.jpg", jpeg_counter) >= FILENAME_LEN) {
printf("%s: output filename truncated", filename);
r = 4;
break;
};
FILE *output = fopen(filename2, "wb");
if(!output) {
printf("%s: fopen failed\n", filename);
r = 5;
break;
}
// TBD: replace with a loop once we figure out
// how a given file is terminated.
if(fwrite(buffer, n, 1, output) != n) {
printf("%s: write failed\n", filename);
r = 6;
}
fclose(output);
}
out:
if(input) fclose(input);
return r;
}
uint8_t buffer[512];
fread(buffer, sizeof(buffer), 1, input)
This should be change to: fread(buffer, 1, sizeof(buffer), input). This way fread will read up to 512 bytes. When it gets to the end of file, it reads whatever is left, for example 1 byte, and returns that number. Likewise, fwrite should change. It should write the same number which was read earlier.
Open the file in binary mode.
If fopen fails then stop immediately.
Check the file header only once, not every read loop.
Your condition for checking the file header may have a typo (buffer[3] & 0xf0) == 0xe0. Checking the first 3 bytes should be okay.
int main()
{
FILE* input = fopen("input.jpg", "rb");
if (!input)
{ perror("input error"); return 0; }
FILE* output = fopen("output.jpg", "wb");
if (!output)
{ perror("output error"); fclose(input); return 0; }
uint8_t buf[1000];
int check_header = 1;
while (1)
{
size_t read_count = fread(buf, 1, sizeof(buf), input);
if (!read_count)
break;
if (check_header)
{
if (buf[0] == 0xff && buf[1] == 0xd8 && buf[2] == 0xff)
// && buf[3] == 0xe0 ?
{ printf("header is okay\n"); }
else
{ printf("not okay\n"); break; }
check_header = 0; //don't check header again
}
fwrite(buf, 1, read_count, output);
}
fclose(input);
fclose(output);
return 0;
}
Thanks for the help. Tried those and got the same error. What surprisingly worked for me was to refactor even more the code and give use of the counter for the if conditions as shown below.
int main(int argc, char* argv[])
{
//checks if there is an input
if (argc != 2)
{
printf(".Usage: Looking for card.raw \n");
return 1;
}
else
{
char* filename = argv[1];
FILE* input;
input = fopen(filename, "r");
//to track if it fails to open
if (input == NULL)
{
printf("Could not open file");
return 2;
}
//Create buffer. Unsigned int variable type. Array of 512 bytes
uint8_t buffer[512];
//Create pointer for the buffer.
FILE* output = NULL;
// create 8 bytes file
char files[8];
//Files counters
int jpeg_counter = 0;
//Check
while (fread(buffer, sizeof(buffer), 1, input))
{
//check 4 first bytes of file to see if they contain the jpg signature
if ((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0))
{
if (jpeg_counter != 0)
{
fclose(output);
}
// sprintf(char *str, const char *format, ...) and "03i" means 3 digits in format 001, 002...
sprintf(files, "%03i.jpg", jpeg_counter);
//use created pointer to save jpeg files from input folder card.raw
output = fopen(files, "w");
//add jpeg to the new buffer using ouput pointer
fwrite(buffer, sizeof(buffer), 1, output);
// update counter
jpeg_counter++;
} else if (jpeg_counter != 0)
{
fwrite(buffer, sizeof(buffer), 1, output);
}
}
fclose(output);
return 0;
}
}

How to convert a text file from UNIX format to DOS format

I am trying to make a program in C, that reads a text file and replace \n with \r\n to the same file converting the line ending from UNIX to DOS. I use another code in stackoverflow that convert DOS to UNIX and treat the file as a binary file. my problem is converting to UNIX to DOS. Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
// Return a negative number on failure and 0 on success.
int main()
{
const char* filename = "textfile.txt";
// Get the file size. We assume the filesize is not bigger than UINT_MAX.
struct stat info;
if (stat(filename, &info) != 0)
return -1;
size_t filesize = (size_t)info.st_size;
// Allocate memory for reading the file
char* content = (char*)malloc(filesize);
if (content == NULL)
return -2;
// Open the file for reading
FILE* fptr = fopen(filename, "rb");
if (fptr == NULL)
return -3;
// Read the file and close it - we assume the filesize is not bigger than UINT_MAX.
size_t count = fread(content, filesize, 1, fptr);
fclose(fptr);
if (count != 1)
return -4;
// Remove all '\r' characters followed by a '\n' character
size_t newsize = 0;
for (long i = 0; i < filesize; ++i) {
char ch = content[i];
char ch2 = (i < filesize - 1) ? content[i + 1] : 0;
if (ch == '\r' && ch2 == '\n') {
ch = '\n';
++i;
}
content[newsize++] = ch;
}
// Test if we found any
if (newsize != filesize) {
// Open the file for writing and truncate it.
FILE* fptr = fopen(filename, "wb");
if (fptr == NULL)
return -5;
// Write the new output to the file. Note that if an error occurs,
// then we will lose the original contents of the file.
if (newsize > 0)
count = fwrite(content, newsize, 1, fptr);
fclose(fptr);
if (newsize > 0 && count != 1)
return -6;
}
// For a console application, we don't need to free the memory allocated
// with malloc(), but normally we should free it.
// Success
return 0;
} // main()

Better way to convert string to integer

I wrote this code to read a variable in a .txt file, ignore the first character and convert into a integer.It works but looks dumb, is there a better way to do this? I'm using just one string here but it's supposed to work with four.
void read(char a[])
{
int i;
char a1[3];
for (i = 0; i<3; ++i){
a1[i]= a[i+1];
}
int b1 = atoi(a1);
}
int main()
{
FILE *file;
file = fopen( "file.txt", "r");
if (file == NULL) {
printf( "Arquivo nao encontrado\n");
}
char a[4];
fscanf(file, "%s\n",&a);
read(a);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
const char filename[] = "file.txt";
FILE *fp = fopen(filename, "r");
if (fp == 0)
{
fprintf(stderr, "Failed to open file %s for reading\n", filename);
return(EXIT_FAILURE);
}
int value;
if (fscanf(fp, "%*c%d", &value) != 1)
{
fprintf(stderr, "Failed to read integer value from file %s\n", filename);
fclose(fp);
return EXIT_FAILURE;
}
printf("Read %d\n", value);
fclose(fp);
return 0;
}
The %*c reads a single character but does not assign it. The * to suppress an assignment is a general mechanism in the scanf()
family of functions.
Untested code.

Unable to read a file and pass into arguments

1) I'm trying to open a file, read the mix data (ints, chars and strings) and store them into args.
1.1) so in the sample.txt is a total of 13 (excluding args[0])
2) Need to read a file from terminal "./myprog.c < sample.txt"
Heres my code and have no idea where i went wrong:
sample.txt:
123 213 110 90 1
hello my friend
boo bleh
a b c
myprog.c:
#include <stdio.h>
int main()
{
int i = 1;
FILE *fstin=fopen(argv[0], "r"); //open the file
if (fstin == NULL) {
puts("Couldn't fopen...");
return -1;
}
//Getting all the inputs from file
while ((fscanf(fstin, "%d", argv[i])) != EOF){
i++;
}
fclose(fstin);
for (i=0; i<10; i++) {
printf("%d\n",argv[i]);
}
return 0;
}
Any help is greatly appreciated!
PS: Would like if anyone could post their complete solution? Will upload unto this post and let everyone have a review of this problem
PPS: Please excuse the poor level of coding as I am a beginner and completely new to C.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int ac, char *av[]){
int i, argc=0;
char **argv=NULL, data[16];
FILE *fstin = stdin;
if(ac == 2){
if(NULL==(fstin = fopen(av[1], "r"))){
puts("Couldn't fopen...");
return -1;
}
}
while (1==fscanf(fstin, "%15s", data)){
argv = realloc(argv, (argc+1)*sizeof(char*));
argv[argc] = malloc(strlen(data)+1);
strcpy(argv[argc++], data);
}
if(ac == 2)
fclose(fstin);
for (i=0; i<argc; ++i) {
printf("%s\n", argv[i]);
}
//deallocate
return 0;
}
You are making mistake at 2nd point where you divert your file to other file which is wrong. Actually you need to first compile and need to make executable.
gcc -o my_prog ./myprog.c -Wall
You need to execute this program as below to read file from c program:
./my_prog ./sample.txt
As you are new to C programming first go to man pages related to file operations.
Solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
//If command line argument is not inserted then stop operation
if (2 != argc) {
printf("Invalid number of arguments : %d\n", argc);
return -1;
}
int size = 0, ret = 0;
char *data = NULL;
FILE *fp = NULL;
//Open file in read mode given from command line argument
if (NULL != (fp = fopen(argv[1], "r")))
{
//Find size of file
fseek(fp, 0L, SEEK_END);
size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
//if file is empty no need to read it.
if (size > 0)
{
//Data pointer which contains file information
data = (char *) calloc(sizeof(char), size);
if (NULL != data)
{
//Read whole file in one statement
fread(data, sizeof(char), size, fp);
printf("File %s is readed successfully\n", argv[1]);
printf("Data:\n");
printf("%s\n", data);
free(data); data = NULL;
}
else
{
perror("memory allocation failed\n");
ret = -1;
}
}
else
{
printf("File %s is empty\n", argv[1]);
}
fclose(fp); fp = NULL;
}
else
{
perror("File open failed\n");
ret = -1;
}
return ret;
}
Now Test it on your setup and if any query please post comments.

Resources