how to copy binary files in c - c

hello guys i am trying to make a program which which copying binary files (the values) from the source to the target. but i has a mistake and i don't know how to solve that, how can i complete the code?
int main(int argc, char ** argv)
{
FILE * source, *target;
int numr, numw;
char buffer[100];
source = fopen(argv[1], "rb");
target = fopen(argv[2], "rb");
if ((source = fopen(argv[1], "rb")) == NULL)
{
printf("open read file error.\n");
return 0;
}
while (feof(source) == 0)
{
if ((numr = fread(buffer, 1, 100, source)) != 100)
{
if (ferror(target) != 0)
{
printf("read file error.\n");
return 0;
}
}
fwrite(buffer, 1, numr, target);
if ((numw = fwrite(buffer, 1, numr, target)) != numr)
{
printf("write file error.\n");
return 0;
}
}
fclose(source);
fclose(target);
return 0;
}

At first, you wont open source file twice. Just remove first or second fopen from code.
source = fopen(argv[1], "rb");
if (source == NULL)
{
printf("open read file error.\n");
return 0;
}
Also must open target file with "w" and check it for success.
target = fopen(argv[2], "a+w");
if (target == NULL)
{
fclose(source);
printf("open target file error.\n");
return 0;
}
Also you dont need to check that fread returned 100, if there is something wrong, ferror() will detect error for you.
numr = fread(buffer, 1, 100, source);
if (ferror(target) != 0)
{
printf("read file error.\n");
break;
}
Also you must use write function once
numw = fwrite(buffer, sizeof(char), numr, target);
if (numw != numr)
{
printf("write file error.\n");
break;
}
I edited your code and now it works fine...
int main(int argc, char ** argv)
{
FILE *source, *target;
int numr, numw;
char buffer[101];
source = fopen(argv[1], "rb");
if (source == NULL)
{
printf("open read file error.\n");
return 0;
}
target = fopen(argv[2], "a+w");
if (target == NULL)
{
fclose(source);
printf("open target file error.\n");
return 0;
}
while (feof(source) == 0)
{
memset(buffer, 0, sizeof(buffer));
numr = fread(buffer, 1, 100, source);
if (ferror(target) != 0)
{
printf("read file error.\n");
break;
}
numw = fwrite(buffer, sizeof(char), numr, target);
if (numw != numr)
{
printf("write file error.\n");
break;
}
}
fclose(source);
fclose(target);
return 0;
}

Related

C programming, copying from one file to another using command line arguments

This is my code
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 4) {
printf("Missing arguments\n");
return -1;
}
// Check if buffer is valid before reading anything
int bufferSize = atoi(argv[3]);
if (!bufferSize || bufferSize < 1) {
printf("Invalid buffer size\n");
return -1;
}
printf("*** Copying from '%s' to '%s' (Buffer size: %dB) ***\n",
argv[1], argv[2], bufferSize);
// READ SOURCE FILE
FILE *inputFile = fopen(argv[1], "r");
if (!inputFile) {
printf("Error opening source file\n");
return -1;
}
// READ DESTINATION FILE
FILE *outputFile = fopen(argv[2], "w");
if (!outputFile) {
printf("Error opening destination file\n");
return -1;
}
int buffer[bufferSize];
int bytes;
do {
bytes = fread(buffer, 1, bufferSize, inputFile);
if (fwrite(buffer, 1, bytes, outputFile) != bytes) {
printf("Error writing into destination file\n");
return -1;
}
} while (bytes > 0);
fclose(inputFile);
fclose(outputFile);
return 0;
}
But when I try to exe the file it doesn't work. What could be the problem?
Here's the command line:
/Users/jurajc/Documents/Program/C/L1\ 1/C_program/c_program file.txt fileCopy.txt 512
*** Copying from 'file.txt' to 'fileCopy.txt' (Buffer size: 512B) ***
Error opening source file
The input file file.txt cannot be opened: either because it is not present in the current directory or because you do not have read access to it.
You should output more informative error messages. Note also these problems:
if (!bufferSize || bufferSize < 1) is a redundant test. if (bufferSize < 1) is sufficient.
the error messages should be output to stderr
the files should be open in binary mode to reliably copy all file types on legacy systems.
the read/write loop is incorrect: you should stop when fread returns 0 before attempting to write 0 elements to the output file.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 4) {
fprintf(stderr, "Missing arguments\n");
return -1;
}
// Check if buffer is valid before reading anything
int bufferSize = atoi(argv[3]);
if (bufferSize < 1) {
fprintf(stderr, "Invalid buffer size: %s\n", argv[3]);
return -1;
}
printf("*** Copying from '%s' to '%s' (Buffer size: %dB) ***\n",
argv[1], argv[2], bufferSize);
// READ SOURCE FILE
FILE *inputFile = fopen(argv[1], "rb");
if (!inputFile) {
fprintf(stderr, "Error opening source file %s: %s\n",
argv[1], strerror(errno));
return -1;
}
// READ DESTINATION FILE
FILE *outputFile = fopen(argv[2], "wb");
if (!outputFile) {
fprintf(stderr, "Error opening destination file %s: %s\n",
argv[2], strerror(errno));
return -1;
}
int buffer[bufferSize];
int bytes;
while ((bytes = fread(buffer, 1, bufferSize, inputFile)) != 0) {
if (fwrite(buffer, 1, bytes, outputFile) != bytes) {
fprintf(stderr, "Error writing into destination file: %s\n", strerror(errno));
return -1;
}
}
fclose(inputFile);
fclose(outputFile);
return 0;
}

update file based on a key in C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person
{
char name[10];
char size[6];
char timestamp[15];
};
int main ()
{
FILE *outfile;
// open file for writing
outfile = fopen ("ads.txt", "a");
if (outfile == NULL)
{
fprintf(stderr, "\nError opend file\n");
exit (1);
}
struct person input1 = {"runner", "100", "4376482682"};
//struct person input2 = {"maze", "300", "3232365436"};
// write struct to file
fwrite (&input1, sizeof(struct person), 1, outfile);
//fwrite (&input2, sizeof(struct person), 1, outfile);
if(fwrite != 0)
printf("contents to file written successfully !\n");
else
printf("error writing file !\n");
// close file
fclose (outfile);
FILE *infile;
struct person input;
infile = fopen ("ads.txt", "r");
if (infile == NULL)
{
fprintf(stderr, "\nError opening file\n");
exit (1);
}
// read file contents till end of file
char name[10] = "maze";
char size[6] = "500";
char timestamp[15] = "437838322";
int remaining_size = 100;
int alreadythere =0;
//unpcoming file size
int incoming_file_size = 200;
int target_file_size_toremove = incoming_file_size - remaining_size;
while(fread(&input, sizeof(struct person), 1, infile)){
if(target_file_size_toremove > 0) {
int x = atoi(input.size);
if(target_file_size_toremove < x) {
strcpy(input.name, name);
strcpy(input.size, size);
strcpy(input.timestamp, timestamp);
}
}else {
if(strcmp(input.name, name) == 0) { // if name is eqUAL
if(strcmp(input.size, size) != 0) {
strcpy(input.size, size);
}
if(strcmp(input.timestamp, timestamp) !=0) {
strcpy(input.timestamp, timestamp);
}
alreadythere = 1;
}
printf ("id = %s name = %s %s\n", input.name,
input.size, input.timestamp);
}
}
if(alreadythere == 0) {
struct person incoming = {name, size, timestamp};
fwrite (&incoming, sizeof(struct person), 1, outfile);
}
// close file
fclose (infile);
return 0;
}
The code is in C language. I want to update the size variable when name is equal to "maze". How I can do it, while reading from file?
first the data that is writing in file is -
runner 100 4376482682
maze 300 3232365436
After updating -
runner 100 4376482682
maze 100 3232365436
size should updated from 300 to 100.
I have fixed a number of small bugs in your code related to opening the file in correct mode and checking if fwrite and fread where successful. Then I added the part you where really asking: update the record "maze".
To update the record, we need to read it, change the value and write it back to the file exactly where we have read it. So before reading a record, we query the current file pointer with ftell and before writing, we call fseek to move the file pointer back to the place we read. A call to fflush (another fseek would do as well) is required so that the next fread take place at the correct position.
For testing, I added a third record after "maze" so that we can see - by looking at the file content - that we don't overwrite data.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person
{
char name[10];
char size[6];
char timestamp[15];
};
int main()
{
FILE* outfile;
// open file for writing binary
outfile = fopen("ads.txt", "wb");
if (outfile == NULL) {
fprintf(stderr, "\nError opening file\n");
exit(1);
}
struct person input1 = { "runner", "100", "4376482682" };
struct person input2 = { "maze", "300", "3232365436" };
struct person input3 = { "street", "400", "4232365486" };
// write struct to file, checking for success
if ((fwrite(&input1, sizeof(struct person), 1, outfile) != 1) ||
(fwrite(&input2, sizeof(struct person), 1, outfile) != 1) ||
(fwrite(&input3, sizeof(struct person), 1, outfile) != 1))
printf("error writing file !\n");
else
printf("contents to file written successfully !\n");
// close file
fclose(outfile);
FILE* infile;
struct person input;
// Open for both reading and writing, binary
infile = fopen("ads.txt", "r+b");
if (infile == NULL) {
fprintf(stderr, "\nError opening file for update\n");
exit(1);
}
// read file contents till end of file, update "maze"
while (1) {
long pos = ftell(infile);
if (pos < 0) {
fprintf(stderr, "\nError getting file position\n");
break;
}
if (fread(&input, sizeof(struct person), 1, infile) != 1)
break;
// update the value of size here, if name is equal to "maze"
printf("id = %s name = %s %s\n", input.name, input.size, input.timestamp);
if (strcmp(input.name, "maze") == 0) {
if (fseek(infile, pos, SEEK_SET) != 0) {
fprintf(stderr, "\nError moving file pointer\n");
break;
}
strcpy(input.size, "100");
if (fwrite(&input, sizeof(struct person), 1, infile) != 1) {
fprintf(stderr, "\nError writing file\n");
break;
}
// fflush() is required so that fread() take place a the correct position
if (fflush(infile) != 0) {
fprintf(stderr, "\nError flushing file\n");
break;
}
printf(" Updated id = %s name = %s %s\n", input.name, input.size, input.timestamp);
// Since this code update a single record, we could break the loop
}
}
// close file
fclose(infile);
return 0;
}

CS50 Recover - fread into buffer

I am working on CS50 Recovery and I am unable to get the program to check the JPEG starting header.
I used debug50 and added a couple print statements to try and find the problem. Every time I run the program, it prints out "No Output File 2" meaning no outfile is created, and the IsJPEG boolean check is skipped.
Upon further debugging it seems that the buffer is 0'\000\ all along, so I suspect nothing is written into the buffer, causing the program to skip the boolean check (which trigger fopen) and hence causing it to break.
However, I struggle to find the reason why nothing is written into buffer.
Please help and thank you!
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <stdint.h>
typedef uint8_t BYTE;
bool isJPEG(BYTE buffer[]);
int main(int argc, char *argv[])
{
BYTE buffer[512];
int fileCounter = 0;
char filename[8];
if (argc != 2)
{
printf("%s\n", "Usage: ./recovery file");
return 1;
}
FILE* infile = fopen(argv[1], "r");
if (infile == NULL)
{
printf("%s\n", "Error: File Not Found");
return 1;
}
FILE* outfile;
while (fread(buffer, 512, 1, infile))
{
if (isJPEG(buffer))
{
if (fileCounter == 0)
{
sprintf(filename, "%03i.jpg", fileCounter++);
outfile = fopen(filename, "w");
printf("%s\n", "Bool 1");
}
else
{
fclose(outfile);
sprintf(filename, "%03i.jpg", fileCounter++);
outfile = fopen(filename, "w");
printf("%s\n", "Bool 2");
}
if (outfile == NULL)
{
printf("%s\n", "No Output File 1");
return 1;
}
fwrite(buffer, 512, 1, outfile);
}
else
{
if (outfile == NULL)
{
printf("%s\n", "No Output File 2");
return 1;
}
fwrite(buffer, 512, 1, outfile);
}
}
fclose(outfile);
fclose(infile);
}
bool isJPEG(BYTE buffer[])
{
return buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0;
}
It prints "No output file 2" because it is told to so. When the script is running for the first time, execution is falling into else statement of if (isJPEG(buffer)) where it checks if outfile is NULL. It is indeed NULL because it is pointing to nothing and there No output file 2 is printed. Instead, it should be checked if the outfile is pointing to a file, only then we should write on it. I corrected the script as following;
while (fread(buffer, 512, 1, infile))
{
if (isJPEG(buffer))
{
if (fileCounter == 0)
{
sprintf(filename, "%03i.jpg", fileCounter++);
outfile = fopen(filename, "w");
printf("%s\n", "Bool 1");
}
else
{
fclose(outfile);
sprintf(filename, "%03i.jpg", fileCounter++);
outfile = fopen(filename, "w");
printf("%s\n", "Bool 2");
}
if (outfile != NULL)
{
fwrite(buffer, 512, 1, outfile);
}
}
else
{
if (outfile != NULL)
{
fwrite(buffer, 512, 1, outfile);
}
}
}

Using 3 Pipes(FIFO) to communicate in c , blocking when I tried to communicate with third

I have the following issue. I have two clients each one has one pipe for reading called .name_of_client and I have a pipe for writing to the server with constant name.
When client 1 sends a message to the server then sends a message to same client (possible success message) but when I tried to send to client 2 the server gets trapped , it can't receive another message , and client2 must only read a pipe if have something on them I tried while(!feof(fd)) but it doesn't appear to work. Am I using the wrong function for the job?
My code only necessary to get more information of what I'm doing:
It's only a essential part of my code
server:
void process_msg(char* s){
char* from;
char* to;
char* msg;
strtok(s,":");
from = strtok(NULL,",");
strtok(NULL,":");
to = strtok(NULL,",");
strtok(NULL,":");
msg = strtok(NULL,";");
char path[50];
char path2[50];
sprintf(path,".%s",from);
sprintf(path2,".%s",to);
char buffer[250];
if((fp = fopen(path, "w")) == NULL) {
perror("fopen");
exit(1);
}
if(strcmp(from,to)==0){
sprintf(buffer,"não podes enviar uma mensagem a ti proprio");
fputs(buffer,fp);
fclose(fp);
return;
}
int is_online =0;
int i=0;
for(i=0;i<tamanho;i++)
if(strcmp(list[i].user,to)==0)
is_online =1;
if(!is_online){
sprintf(buffer,"%s nao esta online!\n",to);
fputs(buffer,fp);
fclose(fp);
return;
}
else
printf("-> %s mandou uma mensagem a %s\n",from,to);
fputs("ENVIADO",fp);
fclose(fp);
printf("%s",path2);
if((fp = fopen(path2, "w")) == NULL) {
perror("fopen");
exit(1);
}
sprintf(buffer,"%s > %s\n",from,msg);
fputs(buffer,fp);
fclose(fp);
}
client:
int main(int argc, char *argv[])
{
FILE *fp;
if(argc==1){
printf("Não escolheu utilizador\n");
exit(0);
}
char* password;
sprintf(user,"%s",argv[1]);
printf("Password:\n");
password = get_password();
char mensagem[250];
if((fp = fopen(FIFO_FILE, "w")) == NULL) {
perror("fopen");
exit(1);
}
strcpy(path,".");
strcat(path,user);
umask(0);
mknod(path, S_IFIFO|0666, 0);
sprintf(mensagem,"U:%s,%s;",user,password);
fputs(mensagem, fp);
fclose(fp);
if((fp = fopen(path, "r")) == NULL) {
perror("fopen");
exit(1);
}
fgets(mensagem,250,fp);
fclose(fp);
if(strcmp(mensagem,"SUCCESS")==0){
printf("\n\nUtilizador %s autenticado. Pode começar a usar o sistema!\n\n",user);
}
else if(strcmp(mensagem,"FAIL!")==0){
printf("Password incorrecta!\n");
exit(1);
}
while(1){
printf("name\n"); //DEBUG
if((fp = fopen(path, "r")) == NULL) {
perror("fopen");
exit(1);
}
printf("name2");//DEBUG
while(fgets(mensagem,250,fp)!=NULL){
printf("%s",mensagem);
}
fclose(fp);
printf("**Menu**\n1) Listar utilizadores online\n2) Mandar SMS a um utilizador\n3) Logout\n\n");
char opcao;
op:deactivate_input();
scanf("%c",&opcao);
activate_input();
if(opcao!='1' && opcao!='2' && opcao!='3')
goto op;
if(opcao=='1'){
if((fp = fopen(FIFO_FILE, "w")) == NULL) {
perror("fopen");
exit(1);
}
sprintf(mensagem,"W:%s;",user);
fputs(mensagem, fp);
fclose(fp);
if((fp = fopen(path, "r")) == NULL) {
perror("fopen");
exit(1);
}
printf("////ONLINE LIST\\\\\\\\");
while(!feof(fp)){
fgets(mensagem, 250, fp);
printf("%s\n",mensagem);
}
printf("//// END\\\\\\\\\n");
fflush(fp);
fclose(fp);
}
else if(opcao=='2'){
if((fp = fopen(FIFO_FILE, "w")) == NULL) {
perror("fopen");
exit(1);
}
char tmp[50];
printf("Para quem vais mandar a mensagem?\n");
scanf("%s",tmp);
getchar();
printf("Escreve a mensagem?\n");
//scanf("%s",mensagem);
strcpy(mensagem,"");
char s[50];
fgets(mensagem,250,stdin);
char buffer[500];
sprintf(buffer,"F:%s,T:%s,M:%s;",user,tmp,mensagem);
fputs(buffer, fp);
fclose(fp);
if((fp = fopen(path, "r")) == NULL){
perror("fopen");
exit(1);
}
fgets(mensagem, 250, fp);
fclose(fp);
if(strcmp(mensagem,"ENVIADO")==0){
}else{
printf("%s\n",mensagem);
}
}
else if(opcao=='3'){
if((fp = fopen(FIFO_FILE, "w")) == NULL) {
perror("fopen");
exit(1);
}
sprintf(mensagem,"R:%s;",user);
fputs(mensagem, fp);
fclose(fp);
break;
}
}
return(0);
}
UPDATE: I used two strings to debug but name2 is never printed. I am sure the fp is not busy but it never enters on f((fp = fopen(path, "r")) == NULL)
Does someone know why it stops before it enters on while cause prints name1 but I have nothing in between.

Get Output of system("insmod mmodule.ko")

I want to run shell command in C program and get stdout output.
I did it in this function:
int run_shell_cmd_nout(const char* cmd)
{
FILE *fp;
char out[4096] = {0};
char str[256] = {0};
char full_cmd[1024] = {0};
int result = 0;
// Compose full shell command
if (!sprintf(full_cmd, "/system/bin/%s", cmd))
{
printf("Failed to compose full shell command\n");
return -1;
}
// Open the command for reading.
fp = popen(full_cmd, "r");
if (fp == NULL)
{
printf("Failed to run command\n");
return -1;
}
// Read the output a line at a time - output it.
while(!feof(fp))
{
if(fgets(str, 256, fp) != NULL)
{
result = -1;
strcat(out, str);
}
}
pclose(fp);
if (result != 0)
{
printf("%s\n", out);
return -1;
}
return 0;
}
But it doesn't work with insmod.
Is there any way to intercept all outputs when invoke insmod?

Resources