Converting a binary to char [C] - c

a lot of times ago, i found an extract of C code, that could read the content of an executable file and that can store it as an array of char, in another file (ex: output.txt). It should work, but when i tried it, it corrupts the output, and it can't copy exactly the content of the exe as a char without damaging it. I don't know where could be the problem.
This is my extract of code in C
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main(int argc, char *argv[])
{
if(argc != 3)
{
fprintf(stderr, "Usage >NameProgram firstParam Executable.exe\n");
return -1;
}
FILE *output = fopen("output.txt", "a");
[..]
char* input_file = argv[2]; //the name of the exe
FILE* f_input = fopen(input_file, "rb");
fprintf(output,"char byn[] = {\n");
unsigned long n = 0;
while(!feof(f_input))
{
unsigned char c;
if(fread(&c, 1, 1, f) == 0)
break;
fprintf(output,"0x%.2X,", (int)c);
++n;
if(n % 10 == 0)
fprintf(output,"\n");
}
fclose(f_input);
fclose(output);
//truncating file
FILE *output = fopen("output.txt", "r+");
fseek(output, -1, SEEK_END);
fprintf(output,"};\n\n");
fclose(output);
[..]

using your posted code as a guide, I produced the following:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if(argc != 3)
{
fprintf( stderr, "USAGE: %s outFilename inFileName\n", argv[0] );
exit( EXIT_FAILURE );
}
FILE *fp_out = fopen( argv[1], "a");
FILE* fp_in = fopen( argv[2], "rb");
fprintf(fp_out, "char byn[] = {\n" );
unsigned long n = 0;
unsigned char c;
while(fread(&c, 1, 1, fp_in) == 1)
{
fprintf( fp_out,"0x%.2X,", (int)c);
++n;
if(n % 10 == 0)
fprintf( fp_out,"\n");
}
fprintf( fp_out, "};\n\n");
fclose(fp_in);
fclose(fp_out);
} // end function: main
which I ran on a few executable files
Note: I'm running Ubuntu Linux 14.04
It seems to work correctly.
As with your example, I skipped the error checking (which you should really include in your actual code.)

Related

Rename a file and save it as a another one

I'm trying to get a filename that exists at the beginning. After that I want to add _blabla.txt to the filename and create the another one.
Here the example. --> example.txt (what I get)
Here the what I want. --> example_blabla.txt (what I want to create)
I tried to use sprintf(filename, "%s%s", argv[1], "_blabla.txt") but the created file's name is example.txt_blabla.txt.
How can I remove extension of first filename from the filename that I created ?
Here is my code:
FILE *fp;
FILE *fp2;
char filename[300];
if (argc != 2 || argv[1] == NULL) {
printf(" You did not enter a file name! \n");
exit(-1);
}
sprintf(filename, "%s%s", argv[1], "_blabla.txt");
fp = fopen(argv[1], "r");
fp2 = fopen(filename, "w");
return 0;
Here are some suggestions:
to locate the last '.' in the string, you can use the function strrchr() from <string.h>.
to avoid undefined behavior on overlong strings, use snprintf instead of sprintf.
to copy a portion of a string with snprintf, use %.*s with an int argument before the string pointer.
Here is a modified version:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
FILE *fp;
FILE *fp2;
char filename[300];
char *p;
int pos;
if (argc != 2) {
printf(" You did not enter a file name!\n");
return -1;
}
p = strrchr(argv[1], '.');
if (p != NULL)
pos = p - argv[1];
else
pos = strlen(argv[1]);
// Using the %.*s precision field to limit the number of characters
// copied from `argv[1]`
snprintf(filename, sizeof filename, "%.*s_blabla.txt", pos, argv[1]);
fp = fopen(argv[1], "r");
if (fp == NULL)
return 1;
fp2 = fopen(filename, "w");
if (fp2 == NULL)
return 1;
/* copy the file */
fclose(fp);
fclose(fp2);
return 0;
}
Append the following statements before and after your sprintf() call as follows:
int i;
char *pChar = NULL;
for (i = strlen(argv[1]) - 1; i >= 0: i--) {
if (argv[1][i] == '.') {
pChar = &argv[1][i];
*pChar = '\0';
break;
}
}
sprintf(filename,"%s%s",argv[1],"_blabla.txt");
if (pChar != NULL)
*pChar = '.';
the following proposed code:
demonstrates a method to extract the root name from a filename then append a set of characters.
demonstrates how to inform the user when the command line parameter is missing.
does not perform a stat() to assure the source file actually exists, That is left to the OP to include.
properly checks for I/O errors
documents why each header file is included
suggest getting the length of the argv[1] parameter, add the length of blabla.txt, add 1, then use the VLA feature of C to appropriately size the array filename[]. Note: strlen() works well for obtaining the length of a NUL terminated char array
And now, the proposed code:
#include <stdio.h> // fopen(), fclose(), perror(), fprintf(), FILE
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <string.h> // strrchr(), strcat()
int main( int argc, char (argv[] )
{
FILE *fp;
FILE *fp2;
char filename[300];
if (argc != 2 )
{
fprintf( stderr, "USAGE: %s fileName\n", argv[0] );
exit( EXIT_FAILURE );
}
strcpy(filename, argv[1] );
char *ptr = strrchr( filename, '.' );
if( ptr )
{
*ptr = '\0';
}
strcat( filename, "_blabla.txt");
fp = fopen(argv[1], "r");
if( ! fp )
{
perror( "fopen for input file failed" );
exit( EXIT_FAILURE );
}
fp2 = fopen(filename, "w");
if( ! fp2 )
{
perror( "fopen for output file failed" );
fclose( fp1 );
exit( EXIT_FAILURE );
}
return 0;
}

Reading line by line from a file in C

What I am trying to do is print out the contents of a file line by line. I run the program in terminal by doing: ./test testText.txt. When I do this, random characters are printed out but not what is in the file. The text file is located in the same folder as the makefile. What's wrong?
#include <stdio.h>
FILE *fp;
int main(int argc, char *argv[])
{
char line[15];
fp = fopen(*argv, "r");
while((fgets(line, 15, fp)) != NULL)
{
printf(line);
printf("\n");
}
}
When I do this, random characters are printed out but not what is in the file
These characters are not random, and in fact they are coming from a file. It's not the file that you are trying to read, though - it's the executable file which you are running.
*argv represents the name of the executable; add this line to see what's in *argv:
printf("%s\n", *argv);
The actual command line arguments start at argv[1], so you need
fp = fopen(argv[1], "r");
The first argument passed on the command line is at argv[1], while *argv refers to argv[0]. argv[0] contains the filename of the executable - you are printing out the content of the executable.
The following code prints out the entire argv[] array, then reads your file and prints it.
#include <stdio.h>
int main( int argc, char *argv[] )
{
for( int i = 0; i < argc; i++ )
{
printf( "argv[%d] : %s\n", i, argv[i] ) ;
}
if( argc >= 2 )
{
FILE* fp = fopen( argv[1], "r" ) ;
if( fp != NULL )
{
char line[15];
while( fgets( line, sizeof(line), fp ) != NULL )
{
printf( "%s", line ) ;
}
}
}
return 0 ;
}
Note that fgets() will read an entire line including the , so there is no need to print '\n', especially because with only 15 characters, your line buffer may well not contain an entire line. Note also the tighter localisation of variables - your code needlessly made fp global.
Other refinements are the safe use of the array size rather than literal 15, and the use of a literal constant string for the format specifier. You should avoid passing a variable string for the printf() format string - if your input itself contains format specifiers, printf() will try to read data from arguments that do not exist with undefined results.
Q: What's wrong?
A humble critique:
#include <stdio.h>
FILE *fp; // Perhaps this should be declared inside main?
int main(int argc, char *argv[])
{
char line[15]; // Are the file lines all 14 characters or less? (seems small)
fp = fopen(*argv, "r"); // Opening the binary executable file (argv[0])? Intereting.
// Should check here to ensure that fopen() succeeded.
while((fgets(line, 15, fp)) != NULL)
OK... well, remember that this isn't a text file.. it's an executable (due to *argv). This will read some wacky (but not random) characters from the executable.
{
printf(line); // Bad practice. Should be: printf("%s", line);
Ok... now print the wacky characters?
printf("\n"); // Redundant. The '\n' characters will be supplied in 'line'.
}
// fclose() call missing.
// Integer return value for main() is missing.
}
Here is (perhaps) what was actually intended:
#include <stdio.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int rCode = 0;
FILE *fp = NULL;
char line[255+1];
if(argc != 2)
{
printf("Usage: %s {filepath}\n", *argv);
goto CLEANUP;
}
errno=0;
fp = fopen(argv[1], "r");
if(NULL == fp)
{
rCode=errno;
fprintf(stderr, "fopen() failed. errno:%d\n", rCode);
goto CLEANUP;
}
while(fgets(line, sizeof(line), fp)) /* --As per 'chux' comment */
printf("%s", line);
CLEANUP:
if(fp)
fclose(fp);
return(rCode);
}
Or, if the intent is truly to print the content of the executable, perhaps this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int rCode = 0;
FILE *fp = NULL;
off_t offset = 0;
errno=0;
fp = fopen(*argv, "r");
if(NULL == fp)
{
rCode=errno;
fprintf(stderr, "fopen() failed. errno:%d\n", rCode);
goto CLEANUP;
}
for(;;)
{
char line[16];
size_t bytesRead;
int index;
char ascii[16+1];
memset(ascii, 0, sizeof(ascii));
bytesRead = fread(line, 1, sizeof(line), fp);
if(0==bytesRead)
break;
printf(" %08zX | ", offset);
for(index=0; index < bytesRead; ++index)
{
printf("%02hhX%c", line[index], 7==index ? '-' : ' ');
ascii[index] = isprint(line[index]) ? line[index] : '.';
}
printf("%*s %s\n", (16 -index) * 3, "", ascii);
offset += bytesRead;
}
if(errno)
{
rCode=errno;
fprintf(stderr, "fgets() failed. errno:%d\n", errno);
}
CLEANUP:
if(fp)
fclose(fp);
return(rCode);
}
your file name found at index 1 of argv.
if (argc <= 1) {
printf("no file was given\n");
exit(-1);
}
// open file from argv[1]
// ...

Why wont the program read from the 2 argument file?

So the assignment is to implement a substring search program using an input file to be searched from and an input to be searched. I created the following code:
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *fp;
fp = fopen(argv[1],"r");
if (fp == NULL)
{
printf("Error");
return 0;
}
char* tmpp[100];
int count = 0;
char* nexts = argv[2];
char* tmp = fgets(tmpp,100,fp);
while(tmp = strstr(tmp,nexts))
{
count++;
tmp++;
}
printf("%d\n\n",count);
fclose(fp);
return 0;
}
The program compiles but when i go to implement it in the ubuntu terminal as:
echo "aabb" >beta
./a.out beta a
1
Why isnt the program using the first argument (argv[1]) as beta and the second argument (argv[2]) as a correctly?
You should open a file and then read bytes from that file into temporary buffer:
FILE *file = fopen("file", "r");
while (1) {
char buffer[BUFSIZ+1];
size_t nread = fread(buffer, 1, sizeof(buffer)-1, file);
if (nread == 0) break; // read error or EOF
buffer[nread] = 0;
// chunk with BUFSIZ amount of bytes is available via buffer (and is zero-terminated)
}
If you want to search for string/pattern in a file, be aware that looked pattern in file may cross your chunk-size boundary, for example: you look for "hello", and BUFSIZ is 512. File contains "hello" at byte 510. Obviously, if you read by 512, you will get the first chunk ending with "he", and the second chunk starting with "llo". Probability of this situation is nonzero for all chunk sizes (except SIZE_MAX, but that buffer size is impossible by other reasons). Dealing with borders may be very complicated.
Close...but this is closer:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc != 3)
{
fprintf(stderr, "Usage: %s file pattern\n", argv[0]);
return 1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL)
{
fprintf(stderr, "Error: failed to open file %s for reading\n", argv[1]);
return 1;
}
char tmpp[1000];
int count = 0;
char* nexts = argv[2];
while (fgets(tmpp, sizeof(tmpp), fp) != 0)
{
char *tmp = tmpp;
while ((tmp = strstr(tmp, nexts)) != 0)
{
count++;
tmp++;
}
}
printf("%d\n", count);
fclose(fp);
return 0;
}
The main difference is that this loops reading multiple lines from the input file. Yours would only work on files with a single line of input.

File manipulations in C

I am using a simple 'C' code to do the following:
1) Read from a .txt file.
2) Based on the string present in the .txt file, a directory will be created.
I am not able to perform step-2, as I am not clear with type conversions.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
int main()
{
char ch, file_name[25];
FILE *fp;
//printf("Enter the name of file you wish to see\n");
//gets(file_name);
fp = fopen("input.txt","r"); // read mode
if( fp == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
printf("The contents of %s file are :\n", file_name);
while( ( ch = fgetc(fp) ) != EOF )
printf("%c",ch);
if( _mkdir(ch ) == 0 )
{
printf( "Directory successfully created\n" );
printf("\n");
}
fclose(fp);
return 0;
}
Here is the error:
*error #2140: Type error in argument 1 to '_mkdir'; expected 'const char *' but found 'char'.*
YES, compiler is right.
You are passing a char c to _mkdir, instead of a string.
You should read the string from file and store it to file_name (I guess you forget) and then
_mkdir(file_name);
See below:
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
int main()
{
char file_name[25];
FILE *fp;
fp = fopen("input.txt", "r"); // read mode
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
fgets(file_name, 25, fp);
_mkdir(file_name);
fclose(fp);
return 0;
}
It's because you only have a single char (the c in fgetc stands for char) while _mkdir wants a string (i.e. char *).
You should probably use fgets instead to read the input.
If you dont want to use fgets , then you can use this.
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
int main()
{
char file_name[25];
String str;
FILE *fp;
char ch;
int i=0;
fp = fopen("input.txt", "r"); // read mode
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
while( ( ch = fgetc(fp) ) != EOF ){
printf("%c",ch);
file_name[i];
i++
}
str=file_name;
_mkdir(str);
fclose(fp);
return 0;
}

C regex performance

I'm writing a code in C to perform some regex in enwik8 and enwik9. I'm also creating the same algorithm in other languages for benchmark purposes. The issue is that I'm doing something wrong with my C code because it takes 40 seconds while python and others take just 10 seconds.
What am I forgetting?
#include <stdio.h>
#include <regex.h>
#define size 1024
int main(int argc, char **argv){
FILE *fp;
char line[size];
regex_t re;
int x;
const char *filename = "enwik8";
const char *strings[] = {"\bhome\b", "\bdear\b", "\bhouse\b", "\bdog\b", "\bcat\b", "\bblue\b", "\bred\b", "\bgreen\b", "\bbox\b", "\bwoman\b", "\bman\b", "\bwomen\b", "\bfull\b", "\bempty\b", "\bleft\b", "\bright\b", "\btop\b", "\bhelp\b", "\bneed\b", "\bwrite\b", "\bread\b", "\btalk\b", "\bgo\b", "\bstay\b", "\bupper\b", "\blower\b", "\bI\b", "\byou\b", "\bhe\b", "\bshe\b", "\bwe\b", "\bthey\b"};
for(x = 0; x < 33; x++){
if(regcomp(&re, strings[x], REG_EXTENDED) != 0){
printf("Failed to compile regex '%s'\n", strings[x]);
return -1;
}
fp = fopen(filename, "r");
if(fp == 0){
printf("Failed to open file %s\n", filename);
return -1;
}
while((fgets(line, size, fp)) != NULL){
regexec(&re, line, 0, NULL, 0);
}
}
return 0;
}
file access and compiling regexes is probably a culprit.
compile your regexs once and store them in an array
open the file
read a line
run each compiled regex over it
close the file.

Resources