I have an elf file that called example. I wrote following code which it's read the content of the example file in the binary mode and then I wanted to save their content in another file called example.binary. But when I run the following program it shows me a segmentation fault. What's wrong with this program? I can't find out my mistake.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// typedef macro
typedef char* __string;
//Function prototypes
void readFileToMachine(__string arg_path);
int main(int argc, char *argv[]) {
__string pathBinaryFile;
if(argc != 2){
printf("Usage : ./program file.\n");
exit(1);
}
pathBinaryFile = argv[1];
readFileToMachine(pathBinaryFile);
return EXIT_SUCCESS;
}
void readFileToMachine(__string arg_path){
int ch;
__string pathInputFile = arg_path;
__string pathOutputFile = strcat(pathInputFile, ".binary");
FILE *inputFile = fopen(pathInputFile, "rb");
FILE *outputFile = fopen(pathOutputFile, "wb");
ch = getc(inputFile);
while (ch != EOF){
fprintf(outputFile, "%x" , ch);
ch = getc(inputFile);
}
fclose(inputFile);
fclose(outputFile);
}
You have no room to concatenate extention to path so you have to create space for that.
One solution could be:
char ext[] = ".binary";
pathOutputFile = strdup(arg_path);
if (pathOutputFile != NULL)
{
pathOutputFile = realloc(pathOutputFile, strlen(arg_path) + sizeof(ext));
if (pathOutputFile != NULL)
{
pathOutputFile = strcat(pathInputFile, ext);
// YOUR STUFF
}
free(pathOutputFile);
}
Side note: typedef a pointer is not a good idea...
change your typedef to typedef char* __charptr
void rw_binaryfile(__charptr arg_path){
FILE *inputFile;
FILE *outputFile;
__charptr extension = ".binary";
__charptr pathOutputFile = strdup(arg_path);
if (pathOutputFile != NULL){
pathOutputFile = realloc(pathOutputFile, strlen(arg_path) + sizeof(extension));
if (pathOutputFile != NULL){
pathOutputFile = strcat(pathOutputFile, ".binary");
inputFile = fopen(arg_path, "rb");
outputFile = fopen(pathOutputFile, "wb");
write_file(inputFile, outputFile);
}
}
}
void write_file(FILE *read, FILE *write){
int ch;
ch = getc(read);
while (ch != EOF){
fprintf(write, "%x" , ch);
ch = getc(read);
}
}
Related
I'm reading file using fread().[read file only]
On compilation, the compiler throws a "Segmentation fault (core dumped)" error.
I'm using structure.
I wrote this code.
type #include <string.h>
#include <stdio.h>
#include <stdlib.h>
int twilio_send_functionapi(char *channel, char *status); // function declartion
struct credentials
{
char *account_sid;
char *auth_token;
char *from_number;
char *to_number;
} c1;
int main(int argc, char *argv[])
{
FILE *fp;
struct credentials input;
fp = fopen("data.config", "r");
if (fp == NULL)
{
printf("Error\n");
return -1;
}
dentials.to_number = (char*)malloc(sizeof(char)*100);
while(fread(&c1,sizeof(struct credentials),1 ,fp))
fscanf(fp,"%s %s %s %s", c1.account_sid, c1.auth_token,c1.from_number, c1.to_number);
char *channel,*status;
channel = argv[1];
status = argv[2];
twilio_send_functionapi(channel,status); //function call
}
Don't know where I'm mistaken.
here is .conf file which needs to be read
account_sid : AC40cfb4f3e98b55b13a9b93527683171e
auth_token : 5f6906d7847ad1fc1fc1170ab60e40fd
from_number : 15867854760
to_number : 1212321123
Instead of fread(), fscanf(), use fgets() to read a line of the file into a string.
// 123456789 123456789 123456789 123456789
//account_sid : AC40cfb4f3e98b55b13a9b93527683171e
#define SID_LEN 34
struct credentials {
char account_sid[SID_LEN + 1]; // Use array here, not pointer.
// ... omitted for brevity
} c1;
#define LINE_SIZE 100
char line[LINE_SIZE];
if (fgets(line, sizeof line, fp)) {
if (sscanf(line, "account_sid : %34s", c1.account_sid) == 1) {
; // Success
} else {
; // Failed
}
Continue likewise for the other c1 members`.
Thank you everyone.
I resolve my problem.
char credential[4][100] ;
int main()
{
FILE *fp;
fp = fopen("data.config", "r");
if (fp == NULL)
{
printf("Error\n");
return -1;
}
printf("File is opened\n");
if ((fscanf(fp,"account_sid-%s\n",credential[0])!= 1))
{
printf("error reading account_sid value\n");
return -1;
}
fclose(fp);
}
i am trying to read from a text file and store it into an array character by character, ive tested it out by trying to print or check the ii count but it doesn't seem to be storing, any help would be muchly appreciated
char *readFile(char* filename)
{
FILE* f;
int ii = 0;
char* file = (char*)malloc(1000*sizeof(char));
char ch = '\0';
f = fopen(filename,"r");
if(f == NULL)
{
printf("Error opening file '%s'.\n", filename);
}
else
{
while ((ch = fgetc(f)) != EOF)
{
printf("%c",ch);
file[ii] = (char) ch;
ii++;
}
}
/* file[ii] = '\0'; setting last character as null*/
printf("\n");
fclose(f);
free(file);
return file;
}
I have commented out the line containing the code to free the character array before returning, which was basically making the pointer invalid. I have also changed the type of the variable "ch" to int as fgetc() returns integer.
#include <stdio.h>
#include <stdlib.h>
char *readFile(char* filename)
{
FILE* f;
int ii = 0;
char* file = (char*)malloc(1000*sizeof(char));
int ch; //changed to int from char.
f = fopen(filename,"r");
if(f == NULL)
{
printf("Error opening file '%s'.\n", filename);
}
else
{
while ((ch = fgetc(f)) != EOF)
{
// printf("%c",ch);
file[ii] = (char) ch;
ii++;
}
}
/* file[ii] = '\0'; setting last character as null*/
printf("\n");
fclose(f);
//free(file); //commented this line out
return file;
}
int main()
{
char *filename = "sample.txt";
char *file_arr = readFile(filename);
printf("%s \n",file_arr);
return 0;
}
What i need to do, is to take a file of n lines, and for every x lines, create a new file with the lines of the original file. An example would be this:
Original File:
stefano
angela
giuseppe
lucrezia
In this case, if x == 2, 3 file would be created, in order:
First file:
stefano
angela
Second FIle:
giuseppe
lucrezia
Third File:
lorenzo
What i've done so far is this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
int getlines(FILE *fp)
{
int c = 0;
int ch;
do{
ch = fgetc(fp);
if(ch == '\n')
{
c++;
}
}while(ch != EOF);
fseek(fp, 0 , SEEK_SET);
return c;
}
int ix = 0;
void Split(FILE *fp, FILE **fpo, int step, int lines, int *mem)
{
FILE **fpo2 = NULL;
char * filename = malloc(sizeof(char)*64);
char * ext = ".txt";
char number[2];
for(int i = ix; i < *mem; i++)
{
itoa(i+1, number,10);
strcpy(filename, "temp");
strcat(filename, number);
strcat(filename, ext);
if(!(fpo[i] = fopen(filename, "w")))
{
fprintf(stderr, "Error in writing\n");
exit(EXIT_FAILURE);
}
}
char ch;
int c = 0;
do{
ch = fgetc(fp);
printf("%c", ch);
if(ch == '\n')
{
c++;
}
if(c >= step)
{
c = 0;
ix++;
if(ix >= *mem && (ix*step) <= lines)
{
*mem = *mem + 1;
fpo2 = realloc(fpo, sizeof(FILE*)*(*mem));
Split(fp, fpo2, step, lines, mem);
}
}
putc(ch, fpo[ix]);
}while(ch != EOF);
}
int main()
{
FILE * fp;
if(!(fp = fopen("file.txt", "r")))
{
fprintf(stderr, "Error in opening file\n");
exit(EXIT_FAILURE);
}
int mem = N;
int lines = getlines(fp);
int step = lines/N;
FILE **fpo = malloc(sizeof(FILE *)*N);
Split(fp, fpo, step, lines, &mem);
exit(EXIT_SUCCESS);
}
I'm stack with segmentation error, i couldn't find the bug doing
gdb myprogram
run
bt
I really appreciate any help.
EDIT:
I've changed some things and now it works, but it creates an additional file that contains strange characters. I need to still adjust some things:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
int getlines(FILE *fp)
{
int c = 0;
int ch;
do{
ch = fgetc(fp);
if(ch == '\n')
{
c++;
}
}while(ch != EOF);
fseek(fp, 0 , SEEK_SET);
return c;
}
int ix = 0;
void Split(FILE *fp, FILE **fpo, int step, int lines, int *mem)
{
FILE **fpo2 = NULL;
char * ext = ".txt";
for(int i = ix; i < *mem; i++)
{
char * filename = malloc(sizeof(char)*64);
char * number = malloc(sizeof(char)*64);
itoa(i+1, number,10);
strcpy(filename, "temp");
strcat(filename, number);
strcat(filename, ext);
if(!(fpo[i] = fopen(filename, "w")))
{
fprintf(stderr, "Error in writing\n");
exit(EXIT_FAILURE);
}
free(number);
free(filename);
}
char ch;
int c = 0;
do{
ch = fgetc(fp);
printf("%c", ch);
if(ch == '\n')
{
c++;
}
if(c >= step)
{
c = 0;
ix++;
if(ix >= *mem && ((ix-1)*step) <= lines)
{
*mem = *mem + 1;
fpo2 = realloc(fpo, sizeof(FILE*)*(*mem));
Split(fp, fpo2, step, lines, mem);
}
}
putc(ch, fpo[ix]);
}while(ch != EOF);
}
int main()
{
FILE * fp;
if(!(fp = fopen("file.txt", "r")))
{
fprintf(stderr, "Error in opening file\n");
exit(EXIT_FAILURE);
}
int mem = N;
int lines = getlines(fp);
int step = lines/N;
FILE **fpo = malloc(sizeof(FILE *)*N);
Split(fp, fpo, step, lines, &mem);
exit(EXIT_SUCCESS);
}
There are a few problems in your code. But first I think you need to fix the most important thing
int step = lines/N;
Here step is 0 if your input file has less than N lines of text. This is because lines and N both are integer and integer division is rounding down.
I won't fix your code, but I'll help you with it. Some changes I
suggest:
Instead of getlines, use getline(3) from the standard
library.
fseek(fp, 0 , SEEK_SET) is pointless.
In char * filename = malloc(sizeof(char)*64), note that
both arguments to malloc are constant, and the size is arbitrary.
These days, it's safe to allocate filename buffers statically,
either on the stack or with static: char filename[PATH_MAX].
You'll want to use limits.h to get that constant.
Similarly you have no need to dynamically allocate your FILE
pointers.
Instead of
itoa(i+1, number,10);
strcpy(filename, "temp");
strcat(filename, number);
strcat(filename, ext);
use sprintf(filename, "temp%d%s", i+1, ext)
get familiar with err(3) and friends, for your own convenience.
Finally, your recursive Split is -- how shall we say it? -- a nightmare. Your whole program
should be something like:
open input
while getline input
if nlines % N == 0
create output filename with 1 + n/N
open output
write output
nlines++
I wanted to learn how to use getc function in C so I wrote a little program that is supposed to give the first letter of a text file as an output.
Here's how it looks:
int main()
{
int character;
FILE *file;
file = fopen("file.txt", "r");
if(file == NULL)
printf("can't open\n");
character = getc(file);
printf("%c", character);
fclose(file);
return 0;
}
It fails to open the file.txt file and I can't figure out why. file.txt is in the same folder as my program's .exe file. I'm using Windows Vista.
Thanks in advance
This extracts the program's location from argv[0]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MYFILE "plik.txt"
int main(int argc, char *argv[]) {
char fname[_MAX_PATH+1];
int znak;
FILE *plik;
char *ptr;
strcpy(fname, argv[0]);
ptr = strrchr(fname, '\\');
if(ptr == NULL) {
strcpy(fname, MYFILE);
}
else {
strcpy(ptr+1, MYFILE);
}
plik = fopen(fname, "r");
if(plik == NULL) {
printf("Can't open %s\n", fname);
}
else {
znak = getc(plik);
printf("First char of %s is %c\n", fname, znak);
fclose(plik);
}
getchar();
return 0;
}
Try
if (plik == NULL) { perror("plik.txt"); exit(EXIT_FAILURE); }
for a better understanding of the cause of error.
I'm trying to crypt a file using ceasarshift, a new file called .enc is being created but it's empty.
Here's my code :
#include <stdio.h>
#include <string.h>
char* getFileExtension(const char*);
int main(int argc, char *argv[])
{
const int shift = (int)argv[1];
int byte;
const char *fileName = (char*)argv[2];
char *fileExtension = getFileExtension(fileName);
char *newFileName = (char*)fileName;
FILE *f_in;
FILE *f_out;
f_in = fopen(fileName, "r");
if (strcmp(fileExtension, "enc") == 0)
{
// We want to decrypt the file
strcat(newFileName, ".dec");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in) != EOF))
{
fputc(byte - shift, f_out);
}
}
else
{
// We want to encrypt the file
strcat(newFileName, ".enc");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in) != EOF))
{
fputc(byte + shift, f_out);
}
}
fclose(f_in);
fclose(f_out);
return 0;
}
char* getFileExtension(const char *fileName)
{
char *extension;
int foundExtension = 0;
while (*fileName)
{
if (foundExtension == 1)
{
*extension++ = *fileName++;
}
if (*fileName == '.')
{
foundExtension = 1;
}
fileName++;
}
return extension;
}
I've made a txt file named CryptoFile which contains the following text :
This is a crypto test file !
This is the parameters I sent in the console when running the exe :
FileCaesarShift.exe 15 CryptoFile
So the shift is 15, the file to encrypt/decrypt is called "CryptoFile"
although a file called CryptoFile.enc is being created it's simply empty.
Can someone tell me what I did wrong ?
Ok I've found out that I need to pass CryptoFile.txt including the ".txt" but I wish to remove it from the name of the new files that will be created so instead of creating CryptoFile.txt.enc I want only CryptoFile.enc so I made a removeExtension function but my program crashes , here's the new code :
#include <stdio.h>
#include <string.h>
char* getFileExtension(const char*);
void removeFileExtension(char*);
int main(int argc, char *argv[])
{
const int shift = (int)argv[1];
int byte;
const char *fileName = (char*)argv[2];
char *fileExtension = getFileExtension(fileName);
char *newFileName = (char*)fileName;
removeFileExtension(newFileName);
printf("newfilename value is %s", *newFileName);
FILE *f_in;
FILE *f_out;
f_in = fopen(fileName, "r");
if (strcmp(fileExtension, "enc") == 0)
{
// We want to decrypt the file
strcat(newFileName, ".dec");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in)) != EOF)
{
fputc(byte - shift, f_out);
}
}
else
{
// We want to encrypt the file
strcat(newFileName, ".enc");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in)) != EOF)
{
printf("byte is %d\n", byte);
fputc(byte + shift, f_out);
}
}
fclose(f_in);
fclose(f_out);
return 0;
}
char* getFileExtension(const char *fileName)
{
char *extension;
int foundExtension = 0;
while (*fileName)
{
if (foundExtension == 1)
{
*extension++ = *fileName++;
}
if (*fileName == '.')
{
foundExtension = 1;
}
fileName++;
}
return extension;
}
void removeFileExtension(char *fileName)
{
while (*fileName)
{
if (*fileName == '.')
{
*fileName == '\0';
break;
}
fileName++;
}
}
LATEST EDIT :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void copyFileExtension(char*, char*);
int getFileNameLengthWithoutExtension(char*);
int getFileExtensionLength(char*);
void copyFileNameWithoutExtension(char*, char*);
int main(int argc, char *argv[])
{
int shift = atoi(argv[1]);
int byte;
char *fileName = (char*)argv[2];
char *fileExtension = malloc(getFileExtensionLength(fileName) + 1);
copyFileExtension(fileExtension, fileName);
char *newFileName = malloc(getFileNameLengthWithoutExtension(fileName) + 5);
copyFileNameWithoutExtension(newFileName, fileName);
FILE *f_in;
FILE *f_out;
f_in = fopen(fileName, "r");
if (strcmp(fileExtension, "enc") == 0)
{
// We want to decrypt the file
puts("dec");
strcat(newFileName, ".dec");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in)) != EOF)
{
fputc(byte - shift, f_out);
}
}
else
{
puts("enc");
// We want to encrypt the file
strcat(newFileName, ".enc");
f_out = fopen(newFileName, "w");
while ((byte = fgetc(f_in)) != EOF)
{
fputc(byte + shift, f_out);
}
}
fclose(f_in);
fclose(f_out);
return 0;
}
void copyFileExtension(char *fileExtension, char *fileName)
{
char *token = strtok(fileName, ".");
token = strtok(NULL, ".");
strcpy(fileExtension, token);
}
int getFileNameLengthWithoutExtension(char *fileName)
{
if (*fileName && *fileName != '.')
{
return 1 + getFileNameLengthWithoutExtension(++fileName);
}
return 0;
}
int getFileExtensionLength(char *fileName)
{
int foundExt = 0;
int len = 0;
while(*fileName)
{
if (foundExt == 1)
{
len++;
}
if (*fileName == '.')
{
foundExt = 1;
}
fileName++;
}
printf("ext len is %d\n", len);
return len;
}
void copyFileNameWithoutExtension(char* dest, char *source)
{
char *fileNameWithoutExtension = strtok(source, ".");
strcpy(dest, fileNameWithoutExtension);
}
Here are a few things one can notice at a quick glance:
const int shift = (int)argv[1] does not convert the input argument to the integer value 15. Rather it casts the char* pointer in argv[1] (that is the address) into an int and assigns that (typically quite large) value to shift. To actually convert the input argument into an int consider using atoi.
you are not allocating memory for newFileName, and later writing possibly past the allocated length of the "constant" input argv[2] which newFileName points to (which results in undefined behavior).
Assuming the program doesn't crash before that, the operator precedence rule between = and != makes your while loop arguments equivalent to byte = (fgetc(f_in) != EOF). So before you reach EOF, byte == 1. If you had a shift of 15 you wind up creating a file full of unreadable control characters (ascii character 16). Given the unpredictable shift from the first bullet, who knows what is actually going to be written to file.
Though these are probably not your specific errors, the following could also cause problem:
You are also not checking whether the files were opened successfully before using them
Have you consider what would happen for letters that are near the end of the valid characters?