i need to copy bitmap image file in c language using a buffer - c

i have to copy a bitmap image file using a buffer.
here is an example of what i need to do.
i have to read different parts of a bitmap into the buffer first at once and then write it to the target file.
when i read different parts into the buffer , the previous string gets overwritten and the last string that is read is only written. i dont want to use read and write function for every part that has to be written.
please help me with the code.
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
void fskip(FILE *fp, int num_bytes) {
int i;
for (i = 0; i < num_bytes; i++)
fgetc(fp);
}
int main() {
FILE *fp, *fp1;
fp = fopen("c:\\users\\tapan\\desktop\\splash.bmp", "rb");
fp1 = fopen("c:\\users\\tapan\\desktop\\splash2.bmp", "wb");
int *j;
j = (int *)malloc(3000);
int k = 223121;
int *i = &k;
fread(j, 2, 1, fp);
fread(j, 10, 1, fp);
fwrite(j, 12, 1, fp1);
fclose(fp1);
fclose(fp);
getch();
}

First of all, I will try to address your specific question and avoid any comments about other things in the code.
It looks like the fread() and fwrite() statements are not correct. The following code might be more exact.
int main() {
FILE *fp, *fp1;
fp = fopen("c:\\users\\tapan\\desktop\\splash.bmp", "rb");
fp1 = fopen("c:\\users\\tapan\\desktop\\splash2.bmp", "wb");
int *j;
j = (int *) malloc(3000);
int k = 223121;
int *i = &k;
// read 2 items of sizeof(int) into j from fp
fread(j, sizeof(int), 2, fp);
// read 10 items of sizeof(int) into j + 2 from fp
fread(j+2, sizeof(int), 10, fp);
// write 12 items of sizeof(int) from j to fp1
fwrite(j, sizeof(int), 12, fp1);
fclose(fp1);
fclose(fp);
getch();
}
// Note. The above code has NOT been tested, it is thrown-up here for discussion.
Format of fread() and fwrite() is per K&R, second edition, page 247.

Related

Understanding fseek() in C

I was learing File I/O in C and was interested in using it to read and write structures to files via fwrite() and fread() functions, now after my code ran successfully I was wondering if I could read a specific structure from an array of structures and put it in some given structure.
Here is my attempt at it
#include <stdio.h>
#include <stdlib.h>
typedef struct tools {
int recordno;
char toolname[50];
int quantity;
float cost;
} tools;
void recordprinter(tools a) {
printf("%d %s %d %f\n", a.recordno, a.toolname, a.quantity, a.cost);
}
int main() {
FILE * fp;
fp = fopen("file.txt", "rb+");
tools * a = (tools * ) malloc(100 * sizeof(tools));
for (int i = 0; i < 100; i++) {
a[i].cost = 0;
a[i].toolname[0] = 'a';
a[i].toolname[1] = '\0';
a[i].quantity = 0;
a[i].recordno = i + 1;
}
for (int i = 0; i < 100; i++) {
fwrite(a + i, sizeof(tools), 1, fp);
fseek(fp, sizeof(tools), SEEK_CUR);
// I used fseek here just because fwrite doesnot move the cursor when\
it writes something to the file.(and fwrite(a + i, sizeof(tools), 100, fp) gives weird gliches)
}
fseek(fp, 0, SEEK_SET); // to bring cursor back to start of the file.
fread(a, sizeof(tools), 1, fp);
fseek(fp, sizeof(tools) * 50, SEEK_SET); // now I expect the cursor to be at 51th structure.
fread(a + 3, sizeof(tools), 1, fp); // I am now writing the 51th structure in a[3]
recordprinter(a[3]);
// this gives output 26 and not 51
return 0;
}
Now when I ran the programm I expected 51 a 0 0.00000 as output,
but to my surprise it is picking up the 26th structure and putting it in a[3]
Any help will be appritiated!!
Try changing fopen to use w+ instead of rb+
Also, remove the fseek when creating the file, as mentioned, fwrite definitely advances the file offset after writing data (provided fwrite does write data at all).
Here is the output observed using the modified code below.
gcc main.c
./a.out
51 a 0 0.000000
// main.c
#include <stdio.h>
#include <stdlib.h>
typedef struct tools {
int recordno;
char toolname[50];
int quantity;
float cost;
} tools;
void recordprinter(tools a) {
printf("%d %s %d %f\n", a.recordno, a.toolname, a.quantity, a.cost);
}
int main() {
FILE * fp;
// recommend for this example using w+
// w because it creates the file if the file doesn't exist
// r fails if the file doesn't exist (and that doesn't seem useful here)
// + because you are reading and writing
// avoiding b and choosing POSIX - linux
// may be wrong, if libc docs says b is needed then use b
// my doc "man fopen" says b is ignored
fp = fopen("file.txt", "w+");
// check return values, file pointer exist? fail if not
if (fp==NULL) { printf( "oops file not opened\n" ); return 1; }
tools * a = (tools * ) malloc(100 * sizeof(tools));
for (int i = 0; i < 100; i++) {
a[i].cost = 0;
a[i].toolname[0] = 'a';
a[i].toolname[1] = '\0';
a[i].quantity = 0;
a[i].recordno = i + 1;
}
// alternative way to save 100 objects
// if ( fwrite(a, sizeof(tools), 100, fp) != 100 )
// {
// printf( "oops 100 objects not written to file\n" );
// return 1;
// }
for (int i = 0; i < 100; i++) {
fwrite(a + i, sizeof(tools), 1, fp);
// remove fseek, not needed, fwrite does what is needed here
//fseek(fp, sizeof(tools), SEEK_CUR);
// I used fseek here just because fwrite doesnot move the cursor when
// it writes something to the file.(and fwrite(a + i, sizeof(tools), 100, fp) gives weird gliches)
}
// no review after this line, it seems to do what author intends
fseek(fp, 0, SEEK_SET); // to bring cursor back to start of the file.
fread(a, sizeof(tools), 1, fp);
fseek(fp, sizeof(tools) * 50, SEEK_SET); // now I expect the cursor to be at 51th structure.
fread(a + 3, sizeof(tools), 1, fp); // I am now writing the 51th structure in a[3]
recordprinter(a[3]);
// this gives output 51 as desired
return 0;
}

Trying to print out contents from a file but I get segmentation fault error

I am trying to apply dynamic memory allocation on reading text files but I don't really get how I could access the contents of the file. I am still having difficulties understanding memory allocation so if it is possible, please explain how I can apply it on file handling.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int counter = 0;
char ch;
char **chpt;
FILE *fp;
fp = fopen("test.txt", "r");
while((ch = fgetc(fp)) != EOF ){
counter++;
}
rewind(fp);
chpt = (char **)malloc(counter * sizeof(char));
fread(chpt, counter * sizeof(char), 1, fp);
for (int i = 0; i < counter; i++){
for (int j = 0; j < counter; j++) {
printf("%c", chpt[i][j]);
}
}
fclose(fp);
free(chpt);
return 0;
}
Your nested for loops don't make any sense and you're trying to print counter*counter characters, but you have only read counter characters. You don't have a 2D array here, and you don't need one either.
Furthermore:
you need to check if fopen fails
the cast with malloc is not needed (but it doesn't harm either)
Your file contains obviously counter characters. So you need to allocate memory for counter characters, read counter characters from the file, and then display the counter characters you've just read.
You want this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int counter = 0;
char ch;
char* chpt; // just a pointer to char
FILE* fp;
fp = fopen("test.txt", "r");
if (f == NULL) // check if fopen failed
{
printf("Can't open file\n"); // print error message
return 1; // and abort
}
while ((ch = fgetc(fp)) != EOF) {
counter++;
}
rewind(fp);
chpt = malloc(counter * sizeof(char)); // no cast needed
fread(chpt, counter * sizeof(char), 1, fp);
for (int i = 0; i < counter; i++) { // one loop is enough
printf("%c", chpt[i]);
}
fclose(fp);
free(chpt);
return 0;
}
There is still room for further improvement:
you should check if malloc fails, even if it's unlikely to fail if the file isn't huge
your method of determining the file size is very inefficient, for more information read this
sizeof(char) is not needed, it is 1 by definition.

Reading and writing files in c

i wanna know why my program can't input the numbers of my .txt file them into my array. It reads them but i can't manage to input them into an array for later use.
Can anybody help me to understand better the management of reading and writing files in c, please i'm new at this topic, i know i'm supposed to use int instead of chars since my .txt file contains only numbers. But with the functions such as fgets is for chars only i think.
#include <stdio.h>
int main()
{
FILE* file;
char name[10] = "100.txt";
char line[10];
int n;
char i[5];
file = fopen(name, "rt");
if (file == NULL)
{
printf("There is no such file!\n");
return 0;
}
for (n=0; n < 100; n++){
fgets(line, 5, file);
//puts(line);
i[n]=line;
puts(i[n]);
}
fclose(file);
return 0;
}
if you switch to fscanf you can use int instead of char, and given that you are parsing a text file containing numbers it makes more sense. Assuming your 100.txt has 100 number separated by a whitespace this should work:
int main(int argc, char* argv[])
{
FILE* file;
char name[10] = "100.txt";
char line[10];
int n;
int numberArray[100];
file = fopen(name, "rt");
if (file == NULL)
{
printf("There is no such file!\n");
return 0;
}
for (n=0; n < 100; n++){
fscanf(file, "%d", &numberArray[n]);
}
fclose(file);
return 0;
}
Here is the link for an explanation of fscanf.
EDIT:
There is another, and more elegant solution, to use fscanf:
while (fscanf(file,"%d",&numberArray[n++]) == 1);
in that way you loop through your text file as long as there are numbers (i.e. until EOF). Be careful as the program could crash if the count of numbers in the text file is greater than the space allocated for the array.
For writing back to a file:
FILE* fp = fopen( "out_file.txt", "w" ); // Open file for writing
int arrNumSize = sizeof(numberArray) / sizeof(int);
for (int i = 0; i < arrNumSize; i++)
{
fprintf(fp, "%d", numberArray[i] );
}
fclose(fp);

Unclear reading file in C

I tried cyclically read file in buffer of 100 byte.
When i read file first time - buffer was full. Returned value is 0. No error and no eof (functions "ferror" and "feof" shows no error). Then i tried read file second time and again returned value is 0, no error and no eof. But then i have empty buffer. I don't know what is the problem?
if(fopen_s(&file_in, argv[1], "rb") == 0){
printf("File was opened.\n");
while(!feof(file_in)){
read_code = fread_s(file_data, 100, sizeof(unsigned char), 100, file_in);
if(ferror(file_in)) {
printf("Error!\n");
}
if(feof(file_in)) {
printf("Eof!\n");
}
printf("Read result: %d\n", read_code);
/*Using the buffer*/
memset(file_data, 0, 100);
}
fclose(file_in);
}
For the reasons given in comments regarding fopen_s, et. al., Here is an alternative implementation of reading a binary file using getc(), along with fopen(), fclose(), etc. (I am not using a Microsoft implementation, but am using ANSI C99)
It has a commented section I used to create a test binary file. Other than that it sizes the file you are reading so you can allocate the right amount of memory, then reads the binary data into a buffer.
For navigating your file, take a look at fseek() with its stdio.h defined arguments:
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
In this example, everything is closed or freed before exiting:
#include <windows.h>
#include <ansi_c.h>
long int getFileSizeFromPath(char * path)
{
FILE * file;
long int fileSizeBytes = 0;
file = fopen(path,"r");
if(file){
fseek(file, 0, SEEK_END);
fileSizeBytes = ftell(file);
fseek(file, 0, SEEK_SET);
fclose(file);
}
return fileSizeBytes;
}
int main(int argc, char *argv[])
{
FILE *fp=0;
char *binBuf;
long int size=0;
int i=0;
int byte=0;
//create 100 byte test file (c:\\dev\\tessst.bin)
// fp = fopen(argv[1], "wb");
//
// srand(clock());
// for(i=0;i<100;i++)
// {
// byte = rand();
// putc(byte, fp);
// }
// putc(EOF, fp);
//
// fclose(fp);
size = getFileSizeFromPath(argv[1]);
binBuf = calloc(size + 1, sizeof(char));
fp = fopen(argv[1], "rb");
byte = getc(fp);
while(byte != EOF)
{
binBuf[i++] = (char)byte;
byte = getc(fp);
}
fclose(fp);
free(binBuf);
return 0;
}

Creating copy of binary file from hex representation of it

I'd like to make copy of my binary file, but I need to make it from hex representation of my binary file.
In the first program I create txt file with with hex representation of my binary file:
#include <stdio.h>
#include <stdlib.h>
const int BYTE = 1;
int counter = 0;
int read;
long size;
FILE *file1 = NULL;
FILE *file2 = NULL;
fpos_t length;
int main() {
unsigned char hex[3];
unsigned char buffer[1];
file1 = fopen("server.pdf", "rb");
fseek(file1, 0, SEEK_END);
fgetpos(file1, &length);
size = length.__pos;
fseek(file1, 0, SEEK_SET);
if (file1) {
file2 = fopen("test.txt", "w");
while (counter < size) {
read = fread(buffer, 1, BYTE, file1);
counter += read;
i = 0;
while(i<read) {
sprintf(hex, "%02x", (unsigned int) buffer[i++]);
fwrite(hex, 1, BYTE, file2);
}
}
} else
printf("ERROR");
fclose(file1);
fclose(file2);
}
In the second, I read data from txt file and after that I write it to binary file:
#include <stdio.h>
FILE *file1;
FILE *file2;
int size;
fpos_t length;
int main(){
file1 = fopen("test.txt", "r");
fseek(file1, 0, SEEK_END);
fgetpos(file1, &length);
size = length.__pos;
fseek(file1, 0, SEEK_SET);
char buffer[1];
char hex[3];
int counter = 0;
int read;
if(file1){
file2 = fopen("test.pdf", "wb");
while (counter < size) {
read = fread(hex, 1, 3, file1);
counter += read;
sscanf(hex, "%02x", buffer);
fwrite(buffer, 1, 1, file2);
}
}
fclose(file1);
fclose(file2);
}
Unfortunately I can't open my copy. What is the reason?
Have you looked at the files content? You wont be able to sprintf the hex representation to the variable hex since it's 1 byte in size.
The variable hex is declared hex[BYTE] where BYTE = 1, but your sprintf format string looks like this: "%02x" ie 2 bytes, then you need room for a terminating zero.
The same goes for when you write to the file, you only write 1 byte from your hex string.
Declaring a variable as: var[1] is pointless you can achieve the same thing with var btw.
Besides this you should also add proper error handling, if you can not successfully open the file. This means checking the file pointer after your call to fopen, then take an appropriate action. perror() will print an error string that corresponds to errno, and in case of a file that does not exist it will print something like: "no such file or directory" or similar.
When you said you can't open your copy, you mean you have an error in fopen("test.txt", "r")? Did you check errno value? Check perror() and strerror().
Besides, you have no loop in second program.

Resources