How can I print the binary code of a file in c? - c

So I want to make a checksum on windows but first I need to get one string with the information of the file in binary but my code show only the information in other formats, can anyone help me get this to show this information only with 0 and 1?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char linha[1024];
}linha;
int main() {
linha linha1;
char temp[1024];
FILE *arquivo;
if((arquivo = fopen("C:\\62-Q2.mp3","rb"))==NULL){
printf("Erro ao abrir o arquivo.");
exit(1);
}
fseek(arquivo, sizeof(linha), SEEK_SET);
while(!feof(arquivo)) {
fread(&linha1,sizeof(linha),1,arquivo);
strcpy(temp, linha1.linha);
printf("%u\n", temp);
}
fclose(arquivo);
return 0;
}

strcpy(temp, linha1.linha);
this line makes no sense at all as you do not read text file.
while(!feof(arquivo))
This is always wrong.
To dump file as bytes in bin:
void printByteAsBin(unsigned char ch)
{
unsigned char mask = 1 << (CHAR_BIT - 1);
for(; mask; mask >>= 1) printf("%c", (ch & mask) ? '1' : '0');
}
void dumpBin(FILE *fi, int linelen)
{
int ch = fgetc(fi);
int linepos = 0;
char str[linelen + 1];
while(ch != EOF)
{
printByteAsBin(ch);
str[linepos] = (isalpha(ch) || ch == ' ') ? ch : '.';
if(++linepos < linelen) printf(" ");
else {str[linepos] = 0; printf(" %s\n", str); linepos = 0;}
ch = fgetc(fi);
}
if(ch == EOF && linepos != linelen )
{
for(int x = 0; x < (linelen - linepos) * 9; x++, printf(" "));
str[linepos] = 0;
printf("%s\n", str);
}
}
You should add some error and parameter checking.
Demo:
https://godbolt.org/z/5nqeG3fE8
01001000 01100101 01101100 01101100 01101111 00100000 Hello
01010111 01101111 01110010 01101100 01100100 00001010 World.

Related

How to convert ascii string to binary?

I'm trying to convert an ascii string to a binary string in C. I found this example Converting Ascii to binary in C but I rather not use a recursive function. I tried to write an iterative function as opposed to a recursive function, but the binary string is missing the leading digit. I'm using itoa to convert the string, however itoa is a non standard function so I used the implementation from What is the proper way of implementing a good "itoa()" function? , the one provided by Minh Nguyen.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int32_t ascii_to_binary(char *input, char **out, uint64_t len)
{
uint32_t i;
uint32_t str_len = len * 8;
if(len == 0)
{
printf("Length argument is zero\n");
return (-1);
}
(*out) = malloc(str_len + 1);
if((*out) == NULL)
{
printf("Can't allocate binary string: %s\n", strerror(errno));
return (-1);
}
if(memset((*out), 0, (str_len)) == NULL)
{
printf("Can't initialize memory to zero: %s\n", strerror(errno));
return (-1);
}
for(i = 0; i < len; i++)
itoa((int32_t)input[i], &(*out)[(i * 8)], 2);
(*out)[str_len] = '\0';
return (str_len);
}
int main(void)
{
int32_t rtrn = 0;
char *buffer = NULL;
rtrn = ascii_to_binary("a", &buffer, 1);
if(rtrn < 0)
{
printf("Can't convert string\n");
return (-1);
}
printf("str: %s\n", buffer);
return (0);
}
I get 1100001 for ascii character a, but I should get 01100001, so how do I convert the ascii string to the whole binary string?
You could change the for loop to something like this:
for(i = 0; i < len; i++) {
unsigned char ch = input[i];
char *o = *out + 8 * i;
int b;
for (b = 7; b >= 0; b--)
*o++ = (ch & (1 << b)) ? '1' : '0';
}
or similar:
for(i = 0; i < len; i++) {
unsigned char ch = input[i];
char *o = &(*out)[8 * i];
unsigned char b;
for (b = 0x80; b; b >>= 1)
*o++ = ch & b ? '1' : '0';
}
This program gets and integer ( which contains 32 bits ) and converts it to binary, Work on it to get it work for ascii strings :
#include <stdio.h>
int main()
{
int n, c, k;
printf("Enter an integer in decimal number system\n");
scanf("%d", &n);
printf("%d in binary number system is:\n", n);
for (c = 31; c >= 0; c--)
{
k = n >> c;
if (k & 1)
printf("1");
else
printf("0");
}
printf("\n");
return 0;
}
Best just write a simple function to do this using bitwise operators...
#define ON_BIT = 0x01
char *strToBin(char c) {
static char strOutput[10];
int bit;
/*Shifting bits to the right, but don't want the output to be in reverse
* so indexing bytes with this...
*/
int byte;
/* Add a nul at byte 9 to terminate. */
strOutput[8] = '\0';
for (bit = 0, byte = 7; bit < 8; bit++, byte--) {
/* Shifting the bits in c to the right, each time and'ing it with
* 0x01 (00000001).
*/
if ((c >> bit) & BIT_ON)
/* We know this is a 1. */
strOutput[byte] = '1';
else
strOutput[byte] = '0';
}
return strOutput;
}
Something like that should work, there's loads of ways you can do it. Hope this helps.

Print statement changing char array output

I'm trying to convert some text (character by character) to its binary representation. For some reason the print statement printf("Hold is %d or %c: ", hold, hold); is changing the output of my function and I have no idea how to explain it. Any help would be greatly appreciated. The test file is just a text file with Hello, World! inside of it.
With it:
Hold is 72 or H: 01001000
Hold is 101 or e: 01100101
Hold is 108 or l: 01101100
Hold is 108 or l: 01101100
Hold is 111 or o: 01101111
Hold is 44 or ,: 00101100
Hold is 32 or : 00100000
Hold is 87 or W: 01010111
Hold is 111 or o: 01101111
Hold is 114 or r: 01110010
Hold is 108 or l: 01101100
Hold is 100 or d: 01100100
Hold is 33 or !: 00100001
Without it:
1000 �
0101 �
1100 �
1100 �
1111 �
1100 �
0000 �
0111 �
1111 �
0010 �
1100 �
0100 �
0001 �
Code
#include <stdio.h>
#include <string.h>
void decimal_to_binary(unsigned long num, FILE *out) {
int i = 255, a = 0;
char binarr[255];
for (i = 0; i < 255; i++) { binarr[i] = '0'; }
if (num != 0) {
while (num != 0) {
if (num % 2 == 0) {
binarr[i] = '0';
i--;
} else {
binarr[i] = '1';
i--;
}
num /= 2;
}
} else {
fprintf(out, "00000000");
}
fprintf(out, "%s ", binarr + strlen(binarr) - 8);
printf("%s\n", binarr + strlen(binarr) - 8);
memset(binarr, 0, sizeof(binarr));
}
int main(int argc, char *argv[]) {
int hold;
FILE *in = fopen(argv[1], "r");
FILE *out = fopen(argv[2], "w+");
while (!feof(in)) {
hold = fgetc(in);
if (hold > 0 && hold != 10){
printf("Hold is %d or %c: ", hold, hold);
decimal_to_binary(hold, out);
}
}
fclose(in);
fclose(out);
return 0;
}
Your decimal_to_binary function is incorrect:
you index beyond the end of the binarr array.
you do not null terminate this array to pass it to printf.
Here is a simpler and corrected version:
void decimal_to_binary(unsigned long num, FILE *out) {
int i = 256, a = 0;
char binarr[257];
memset(binarr, '0', sizeof(binarr) - 1);
binarr[i] = '\0';
while (num != 0) {
--i;
if (num % 2) {
binarr[i] = '1';
}
num /= 2;
}
if (i > 256 - 8) // print at least 8 bits
i = 256 - 8;
fprintf(out, "%s ", binarr + i);
printf("%s\n", binarr + i);
}
Your function main has problems too:
you test for end of file with feof(in). This is incorrect, you should instead check if hold is EOF.
hard coding the value of '\n' as 10 is bad practice.
Here is a correct version:
int main(int argc, char *argv[]) {
int hold;
FILE *in = fopen(argv[1], "r");
FILE *out = fopen(argv[2], "w+");
while ((hold = fgetc(in)) != EOF) {
if (hold != '\n') {
printf("Hold is %d or %c: ", hold, hold);
decimal_to_binary(hold, out);
}
}
fclose(in);
fclose(out);
return 0;
}
I decreased the extremely large array, made sure to terminate the string with a null character, zeroed the array, then printed it using fprintf. This solved the issue.
void decimal_to_binary(unsigned long num, FILE *out){
int i = 7, a = 0;
char binarr[9];
binarr[8]='\0';
for (a=7; a>=0; a--){ binarr[a] = '0'; }
if (num != 0) {
while (num!=0){
if (num%2 == 0){
binarr[i] = '0';
i--;
}
else { binarr[i] = '1'; i--; }
num /= 2;
}
} else { fprintf(out, "00000000"); }
fprintf(out, "%s ", binarr);
memset(binarr, 0, sizeof(binarr));
}
Your program has undefined behavior for couple of reasons.
You don't have a null terminated string. Calling strlen on such a string is cause for undefined behavior.
You are modifying binarr using an out of bounds index. That is also cause for undefined behavior.
I have my annotations to your function decimal_to_binary that point out where those errors are.
void decimal_to_binary(unsigned long num, FILE *out){
int i = 255, a = 0;
char binarr[255];
for (i=0; i<255; i++){ binarr[i] = '0'; }
// All the elements of binarr are set to '0'.
// It's not a null terminated string.
if (num != 0) {
while (num!=0){
// The value of i is 255 when this loop is
// entered the first time.
// Setting the value of binarr[255] is cause for
// undefined behavior.
if (num%2 == 0){
binarr[i] = '0';
i--;
}
else { binarr[i] = '1'; i--; }
num /= 2;
}
} else { fprintf(out, "00000000"); }
fprintf(out, "%s ", binarr + strlen(binarr) - 8);
printf("%s\n", binarr + strlen(binarr) - 8);
memset(binarr, 0, sizeof(binarr));
}
The fixes are simple.
Terminate string with the null character.
for (i=0; i<255; i++){ binarr[i] = '0'; }
i--;
binarr[i] = '\0';
Use the right index when modifying binarr in the while loop.
while (num!=0){
// Decrement the index before you assign to the next element.
// When the loop is entered the first time, i = 254, which
// is used to null terminate binarray.
// The next '1' or '0' needs to be placed at i = 253.
i--;
if (num%2 == 0){
binarr[i] = '0';
}
else {
binarr[i] = '1';
}
num /= 2;
}

Create method to iterate through array and format phone number in C

I am new to programming in C, and I'm working on a simple program to take the user input (a basic phone number, ie: (678)-653.7539), and will output it in standard format).
The approach I took was first taking out all periods, hyphens, and parenthesis.
Currently the program prints out just numbers, however the format I want is:
(xxx) xxx-xxxx
I'm thinking creating a method with an array, and then iterating through (similar to stack?) having it input "(" before i[0] and again after i[2], and so on.
Is this the right approach?
#include <stdio.h>
void removeHyphen( char s[], char x );
void removeLeftParen( char s[], char f );
void removeRightParen( char s[], char g );
void removePeriod( char s[], char h );
int main()
{
char s[50];
printf("Enter your phone number:\n");
scanf("%s", s);
printf( "Your phone number: %.13s\n", s );
removeHyphen( s, '-' );
removeLeftParen(s, '(');
removeRightParen(s, ')');
removePeriod(s, '.');
printf( "Formatted phone number: %.10s\n", s );
getchar();
return 0;
}
void removeHyphen(char s[], char x)
{
int i, j;
for (i = 0 ; s[i] != 0 ; ++i)
{
while(s[i]==x)
{
j=i;
while(s[j]!=0)
{
s[j]=s[j+1];
++j;
}
}
}
}
void removeLeftParen(char s[], char f)
{
int i, j;
for (i = 0 ; s[i] != 0 ; ++i)
{
while(s[i]==f)
{
j=i;
while(s[j]!=0)
{
s[j]=s[j+1];
++j;
}
}
}
}
void removeRightParen(char s[], char g)
{
int i, j;
for (i = 0 ; s[i] != 0 ; ++i)
{
while(s[i]==g)
{
j=i;
while(s[j]!=0)
{
s[j]=s[j+1];
++j;
}
}
}
}
void removePeriod(char s[], char h)
{
int i, j;
for (i = 0 ; s[i] != 0 ; ++i)
{
while(s[i]==h)
{
j=i;
while(s[j]!=0)
{
s[j]=s[j+1];
++j;
}
}
}
}
You know exactly what your end product should look like. It'll be char result[15]. So a simple brute force algorithm would look like:
//set the known characters in the output string
result[ 0 ] = '(';
result[ 4 ] = ')';
result[ 5 ] = ' ';
result[ 9 ] = '-';
result[ 14 ] = '/0'; //null terminator
int index = 0;
//pseudocode
foreach( character in input )
if character is a number
if index == 0, 4, 5, 9
++index;
if index == 14 //we're out of room
print result;
exit;
result[ index++ ] = character;
else
ignore character
Where "character is a number" would probably be the only function you'd need to write.
You may not need all the remove logic. You may just iterate over the input and copy the numeric characters.
Pseudo-code idea:
char output[50]; // better: char output[sizeof input];
// This is essentially processed/normalized input.
// In fact, since we know that it is a 10-digit
// phone number we can just do: char output[10];
// If you ever need to store the phone number for
// long term, the last option may be the best option.
const int n = actual length of input, e.g. strlen()
int j = 0;
for (int i = 0; i < n; ++i) {
if (isdigit((unsigned char) input[i]) {
output[j++] = input[i];
}
}
// Validate 'output', for e.g. check that it has 10 characters
// Print output in desired format
See manual page for isdigit().
A different program structure employing the same idea is the following. While accepting input, scan them as characters and ignore the non-digit characters.
I suggest the use of strtok.
The following is an example
#include <stdio.h>
#include <string.h>
int main(void){
char s[50], f[50];
char *part[3] = { NULL };
char *p;
int i;
printf("Enter your phone number:\n");
scanf("%49s", s);
printf( "Your phone number: %s\n", s );
p = strtok(s, "-().");
for(i=0; p!=NULL && i<3; ++i){
part[i] = p;//Better to add one of the check is made up of numbers.
p = strtok(NULL, "-().");
}
if(i==3){
sprintf(f, "(%s) %s-%s", part[0], part[1], part[2]);
printf( "Formatted phone number: %s\n", f );
} else {
printf("invalid format\n");
}
getchar();
return 0;
}
After you have removed all the unwanted characters you can do this
void printFormatted(char *s)
{
int i;
if (s == NULL)
return;
fputc('(', stdout);
for (i = 0 ; ((i < 3) && (s[i] != '\0')) ; ++i)
fputc(s[i], stdout);
fputc(')', stdout);
fputc(' ', stdout);
if (s[i] == '\0')
return;
for ( ; ((i < 6) && (s[i] != '\0')) ; ++i)
fputc(s[i], stdout);
fputc('-', stdout);
if (s[i] == '\0')
return;
for ( ; s[i] != '\0' ; ++i)
fputc(s[i], stdout);
fputc('\n', stdout);
}
Although you don't really need to remove anything if you are just interested in the output of the program, you could use this
#include <stdio.h>
#include <ctype.h>
void printFormatted(char *phone);
int main()
{
char phone[50];
printf("Enter your phone number: ");
if (scanf("%49s%*c", phone) == 1)
{
printf( "Your input : %s\n", phone);
printf("Formatted phone number : ");
printFormatted(phone);
printf("\n");
}
return 0;
}
int putdigit(char digit)
{
/* Print a charater if it's a digit (0-9) */
if (isdigit((int)digit) == 0)
return 0;
fputc(digit, stdout);
return 1;
}
void printFormatted(char *phone)
{
int i;
int j;
/* Always be safe */
if (phone == NULL)
return;
/* Output the `(' */
fputc('(', stdout);
/* Output 3 digits */
for (i = 0, j = 0 ; ((j < 3) && (phone[i] != '\0')) ; ++i)
j += putdigit(phone[i]);
/* Output the `)' and a space */
fputc(')', stdout);
fputc(' ', stdout);
/* Check if there are more characters */
if (phone[i] == '\0')
return;
/* Output 3 digits */
for (j = 0 ; ((j < 3) && (phone[i] != '\0')) ; ++i)
j += putdigit(phone[i]);
/* Output the hypen */
fputc('-', stdout);
/* Check if there are more characters */
if (phone[i] == '\0')
return;
/* Output the rest of the characters */
for ( ; phone[i] != '\0' ; ++i)
putdigit(phone[i]);
fputc('\n', stdout);
}
Another approach. Build the string per an interpreted format.
#include <ctype.h>
// 0: success, 1 fail
int FormatPhoneNumber(const char *format, char *dest, const char *src) {
int i;
for (i = 0; format[i]; i++) {
if (format[i] == 'x') {
while (!isdigit((unsigned char) *src)) {
if (*src++ == '\0') {
dest[i] = '\0';
return 1; // fail, missing digit
}
}
dest[i] = *src++;
} else {
dest[i] = format[i];
}
}
dest[i] = '\0';
while (*src && !isdigit((unsigned char) *src)) src++;
return *src ? 1 : 0;
}
#include <stdio.h>
int main(void) {
const char format[] = "(xxx) xxx-xxxx";
char buf[sizeof format];
int result = FormatPhoneNumber(format, buf, " (678)-653.7539),");
printf("%d '%s'\n", result, buf);
result = FormatPhoneNumber(format, buf, "Jenny: 111-867-5309");
printf("%d '%s'\n", result, buf);
return 0;
}
0 '(678) 653-7539'
0 '(111) 867-5309'

To print intermediate value of left or right shift in C

During left shift or right shift of a "decimal number", I want the result in binary format and not in decimal. I know how to convert decimal to binary. Is there any other way to capture intermediate binary values?
Here's how to print in hexadecimal, which you can pretty easily translate to binary in your head.
printf("0x%x\n", my_int);
Here's code to print a number in a binary format:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, char **argv)
{
char buf[65] = { 0 }, *endptr;
long my_int;
unsigned long tmp_int;
int i, j;
if (argc != 2 || (errno = 0, (my_int = strtol(argv[1], &endptr, 0)), errno) || *endptr)
exit((fprintf(stderr, "Usage: %s <number>\n", argv[0]), 1));
/* break my_int down into a binary character represenation */
tmp_int = my_int;
i = 0;
do
{
buf[i++] = ((tmp_int & 0x1) ? '1' : '0');
tmp_int >>= 1;
}
while (0 != tmp_int);
/* reverse buf for printing */
for (j = 0, --i; j < i; ++j, --i)
{
char c = buf[j];
buf[j] = buf[i];
buf[i] = c;
}
printf("%s\n", buf);
return 0;
}

Caesars Cipher in C

In this caesars cipher code how do i make it so that it reads in spaces, special characters (!##$*...), and numbers and keeps them as they are and prints them? Also i put an fprintf(file2,"\n") at the end of the fgets while loop and it does start a new line but it always prints a weird character at the end of the previous line.
#include <stdio.h>
int main (int argc, char *argv[]) {
char caesar[256];
int shift;
FILE *file1=fopen(argv[1],"r");
FILE *file2=fopen(argv[2],"w");
sscanf(argv[3], "%d", &shift);
while(fgets(caesar,sizeof(caesar),file1)!=NULL){
int i = 0;
while (caesar[i] != '\0') {
if (((caesar[i] + shift) >= 65 && (caesar[i] + shift) <= 90)||((caesar[i] + shift) >= 97 && (caesar[i] + shift) <= 122)) {
caesar[i] += (shift);
}
else {
caesar[i] += (shift - 26);
}
i++;
}
fprintf(file2,"%s", caesar);
fprintf(file2,"\n");
}
return 0;
}
#include <stdio.h>
#include <ctype.h>
int main (int argc, char *argv[]) {
char caesar[256];
int shift;
FILE *file1=fopen(argv[1],"r");
FILE *file2=fopen(argv[2],"w");
sscanf(argv[3], "%d", &shift);
while(fgets(caesar,sizeof(caesar), file1)!=NULL){
char ch;
int i = 0;
for(i = 0; (ch=caesar[i]) != '\0'; ++i) {
if (isalpha(ch)) {//Only alphabet
char a, z;
if(isupper(ch)){
a = 'A'; z = 'Z';
} else {
a = 'a'; z = 'z';
}
caesar[i] += shift;//this depend on the sequence of character codes.
if(caesar[i] > z){
caesar[i] = a + caesar[i] - z - 1;
}
}
}
fprintf(file2, "%s", caesar);
}
return 0;
}

Resources