I'm writing a program that encodes a file using xor and print the encrypted text into another file. It technically works, however the output contains several symbols rather than only lowercase characters. How would I tell the program to only print lowercase letters, and be able to decode it back?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *args[]){
FILE *inFile, *outFile, *keyFile;
int key_count = 0;
int encrypt_byte;
char key[1000];
inFile = fopen("input.txt", "r");
outFile = fopen("output.txt", "w");
keyFile = fopen("key.txt", "r");
while((encrypt_byte = fgetc(inFile)) !=EOF)
{
fputc(encrypt_byte ^ key[key_count], outFile); //XORs
key_count++;
if(key_count == strlen(key)) //Reset the counter
key_count = 0;
}
printf("Complete!");
fclose(inFile);
fclose(outFile);
fclose(keyFile);
return(0);
}
Here is the output I get:
ÕââÐå朶è”ó
I just want it to only use lowercase letters
You can't. You either XOR all data of the file, or you don't. XOR-ing will result in non-printable characters.
What you can do though, is first XOR it and then encode it base64.
To get your original text/data back, do the reverse.
See also How do I base64 encode (decode) in C?
use the function tolower()
here there is an example:
#include<stdio.h>
#include<ctype.h>
int main()
{
int counter=0;
char mychar;
char str[]="TeSt THis seNTeNce.\n";
while (str[counter])
{
mychar=str[counter];
putchar (tolower(mychar));
counter++;
}
return 0;
}
Related
C.
bad file descriptor error by working on files.
This is an assignment for college. I need to compress file txt and then to uncompress it. The compress method working fine
and it compresses by the idea that the last binary digit (Msb) is zero always in any ASCII char.
Does anybody know why it happens?
The problem happens when I do fgetc(input_file_8to7) in the uncompress method
The mainly problem is that i get -1 from the 2 fgetc(input_file_8to7) in uncompresd method
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdint.h>
the input for the uncompress is the output of the compress , the input is txt file that conatain the next 2 lines:
A hex dump is a hexadecimal view of computer data, from memory or from a computer file.
***compres method***
void compress8to7(FILE *input,FILE* output8to7)
{
// 0x00 87 00 87 00 87 00 87 ll
uint64_t magic=0x87008700870087ll;
uint64_t inputsize=0;
fwrite(&magic,sizeof (magic),1,output8to7);
fwrite(&inputsize,sizeof(inputsize),1,output8to7);
unsigned char st;
unsigned char st2;
char check;
char check2;
char shift=7;
char shift_st=0;
unsigned char inbfile;
// will contain the resullt of the asked new binary lines comprees
int breakflag=0;
int breakflag2=0;
int cnt=-1;
//this parameter will help to know when we dont need to move 1 back in
the pointer of input file
while(1) {
cnt++;
if (ftell(input)>1 && cnt%7!=0) //
{
fseek(input,-1 ,SEEK_CUR) ;
}
check = fgetc(input);
st=check;
if(check2==EOF){breakflag2=1;}
check2 = fgetc(input);
> //if the length is odd number check2 will get the eof
st2=check2;
if(check==EOF){breakflag=1;}
st2=st2<<shift;
> //move the digit to the right position
bit manipulation
st=st>>shift_st;
shift_st++;
if(shift_st==7)
{shift_st=0;}
shift=shift-1;
if(shift==0)
shift=7;
if(breakflag2!=1)
{inbfile=st2|st;
}else{ inbfile=st; }
fwrite(&inbfile, sizeof(inbfile),1,output8to7);
write to the file
if(feof(input))
{
inputsize= ftell(input);
fseek(output8to7,8,SEEK_SET);
fwrite(&inputsize,sizeof (inputsize),1,output8to7);
// if(breakflag==1)
break;}
}
}
*** uncompress method***
the problem is in this method
void uncompress8to7 (FILE *input_file_8to7 ,FILE *output_file_txt){
char st;
char st2;
char check;
char check2;
char shift2 = 7;
char shift_st = 0;
char shift_helper=7;
char shift_helper2=6;
char sthelper;
char sthelper2;
char inbfile; // will contain the resullt of the asked new binary lines comprees
int breakflag = 0;
int breakflag2 = 0;
int cnt = -1;//this parameter will help to know when we dont need to move 1 back in the pointer of input file
rewind(input_file_8to7);
printf("%d",ftell(input_file_8to7));
fseek(input_file_8to7,16,SEEK_SET);
printf("\n%d",ftell(input_file_8to7));
int a=0;
while(1) {
cnt++;
if(cnt>1) //
{fseek(input_file_8to7,-1 ,SEEK_CUR);}
printf("\n%d",ftell(input_file_8to7));
from that fgetc i get the bad file descriptor erorr
check = fgetc(input_file_8to7);
if(ferror(input_file_8to7)){
perror("eror by perror");
printf("file erorr");}
// printf("\n%d",ftell(input_file_8to7));
st = check;
check2 = fgetc(input_file_8to7);
st2 = check2;
if(cnt<2)
fseek(input_file_8to7,0,SEEK_SET);
if(check2==EOF){
breakflag2 = 1;
}
sthelper2=st2;
sthelper2=sthelper2>>shift_helper2;
st2=st2<<shift2;
st2=st2>>shift2;
sthelper=st;
sthelper=sthelper>>shift_helper;
sthelper=shift_helper<<shift_helper-1;
st=st<<shift_st;// to make all zero after the msb
st=st>>shift_st;// to make all zero after the msb
shift_helper2--;
if(shift_helper==-1)
{shift_helper2=6;}
shift_helper--;
if(shift_helper==-1){
shift_helper=7;
}
shift_st++;
if(shift_st==7)
{shift_st=0;}
shift2=shift2-1;
if(shift2==0)
shift2=7;
if(breakflag2==1)
{break;}
if(cnt%7==0){
inbfile=st;
}else{
inbfile=sthelper|st2;
}
writing to the file
fwrite(&inbfile,sizeof(inbfile),1,output_file_txt);
break the loop when we got to the end of file
if(feof(input_file_8to7))
{ break;}
}
}
***main***
int main(int argc, char **argv) {
char* input=NULL;
char* output8to7=NULL;
input=argv[1];
output8to7=argv[2];
open files
FILE* inputfile = fopen(input, "r");
if(inputfile==NULL)
{
printf("couldnt open input file ");
exit(-1);
}
FILE* file8to7=fopen(output8to7, "wb");
if(file8to7==NULL)
{
printf("couldnt open output file");
printf(output8to7);
exit(-1);
}
compress
compress8to7(inputfile,file8to7);
FILE* file8to7input=fopen("exampleout.bin", "ab");
FILE* output_file=fopen("UNoutput_file2.txt", "wb");
if(output_file==NULL)
{printf("couldnt open output file");
exit(-1);
}
uncompress8to7(file8to7input,output_file);
fclose(output_file);
fclose(file8to7input);
fclose(inputfile);
fclose(file8to7);
return 0;
}
This is the code to open the file:
FILE* file8to7input=fopen("exampleout.bin", "ab");
This opens it as an output file in append mode. You're trying to read from it in the uncompress8to7() function. You need to open it as in input file in read mode. Change that line to:
FILE* file8to7input=fopen("exampleout.bin", "rb");
I'm writing a Caesar which takes in a file and an offset via STDIN, and outputs the encrypted file in STDOUT.
#include <stdio.h>
#include <stdlib.h>
char encrypt(int c, char d) {
if (c>=97&&c<=122) {
c=c-97;
c=c+d;
c=c%26;
c=c+97;
} else if (c>=65&&c<=90) {
c=c-65;
c=c+d;
c=c%26;
c=c+65;
}
return (c);
}
void print_file(FILE* fp, char d) {
char c;
c = getc(fp);
if (c==EOF) {
printf("\n");
exit(EXIT_SUCCESS);
}
c = encrypt(c, d);
printf("%c", c);
print_file(fp, d);
}
int main(int argc, char* argv[]) {
FILE* fp;
fp = fopen(argv[1],"r");
char c;
*argv[2]=*argv[2]+4; // Dunno why this makes it work but okay
print_file(fp, *argv[2]);
return 0;
}
The expected output from inputting a file with offset of 0 should print the contents of said file without any modification. Instead, the output is an offset of -4, making the input of 4 outputting the offset of 0. Moreover, any negative integer will output a fixed offset of -7.
I've added a a line of code to fix this issue, indicated by my comment. With this, the program works with positive integers, while any negative integer outputs with a fixed offset of -4.
I've tried isolating the individual functions. I cannot get this to reproduce.
On numerous sources, you can find a simple C program to count the number of lines in a file. I'm using one of these.
#include <stdio.h>
int main(int argc, char* argv[]) {
FILE *file;
long count_lines = 0;
char chr;
file = fopen(argv[1], "r");
while ((chr = fgetc(file)) != EOF)
{
count_lines += chr == '\n';
}
fclose(file); //close file.
printf("%ld %s\n", count_lines, argv[1]);
return 0;
}
However, it fails to count the num. of lines in Top2Billion-probable-v2.txt. It stops on the line
<F0><EE><E7><E0><EB><E8><FF>
and outputs
1367044 Top2Billion-probable-v2.txt
when it should output 1973218846 lines. wc -l somehow avoids the problem (and is amazingly faster).
Should I give up with a correct C implementation of counting the number of lines of a file or how should I space the special characters as wc does?
fgetc() returns the character read as an unsigned char cast to an int or EOF. Hence declaring chr as int instead of char should solve the issue.
#include<stdio.h>
#include<ctype.h>
int main(int argc, char *argv[]) {
int i = 0;
char in[100], mychar[100];
FILE *file;
file = fopen(argv[1], "r");
fgets(mychar, 100, file);
while (in[i]) {
mychar[i] = in[i];
putchar(toupper(mychar[i]));
i++;
}
return 0;
}
I have another file named file.c and I write 'abcd' inside it.
This program will read a file's content and change them to capital letters. I don't know why when I typed
./a.out file.c
Nothing come out. What is wrong? I think maybe When using fopen(arg[1],"r") and fgets will make mychar as a string not array? Please have a look.Thanks.
You read the contents of the file into mychar, but test for the uninitialized in char array. To fix this you can just switch the arrays
while (mychar[i]) {
in[i] = mychar[i];
putchar(toupper(in[i]));
i++;
}
But you can also skip the copying and print the contents of mychar directly
while (mychar[i]) {
putchar(toupper(mychar[i]));
i++;
}
fgets(in,sizeof(in),file);
while (in[i]){
mychar[i]=toupper(in[i]);
putchar (mychar[i]);
i am trying to read UTF8 text from a text file, and then print some of it to another file. I am using Linux and gcc compiler. This is the code i am using:
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fin;
FILE *fout;
int character;
fin=fopen("in.txt", "r");
fout=fopen("out.txt","w");
while((character=fgetc(fin))!=EOF){
putchar(character); // It displays the right character (UTF8) in the terminal
fprintf(fout,"%c ",character); // It displays weird characters in the file
}
fclose(fin);
fclose(fout);
printf("\nFile has been created...\n");
return 0;
}
It works for English characters for now.
Instead of
fprintf(fout,"%c ",character);
use
fprintf(fout,"%c",character);
The second fprintf() does not contain a space after %c which is what was causing out.txt to display weird characters. The reason is that fgetc() is retrieving a single byte (the same thing as an ASCII character), not a UTF-8 character. Since UTF-8 is also ASCII compatible, it will write English characters to the file just fine.
putchar(character) output the bytes sequentially without the extra space between every byte so the original UTF-8 sequence remained intact. To see what I'm talking about, try
while((character=fgetc(fin))!=EOF){
putchar(character);
printf(" "); // This mimics what you are doing when you write to out.txt
fprintf(fout,"%c ",character);
}
If you want to write UTF-8 characters with the space between them to out.txt, you would need to handle the variable length encoding of a UTF-8 character.
#include <stdio.h>
#include <stdlib.h>
/* The first byte of a UTF-8 character
* indicates how many bytes are in
* the character, so only check that
*/
int numberOfBytesInChar(unsigned char val) {
if (val < 128) {
return 1;
} else if (val < 224) {
return 2;
} else if (val < 240) {
return 3;
} else {
return 4;
}
}
int main(){
FILE *fin;
FILE *fout;
int character;
fin = fopen("in.txt", "r");
fout = fopen("out.txt","w");
while( (character = fgetc(fin)) != EOF) {
for (int i = 0; i < numberOfBytesInChar((unsigned char)character) - 1; i++) {
putchar(character);
fprintf(fout, "%c", character);
character = fgetc(fin);
}
putchar(character);
printf(" ");
fprintf(fout, "%c ", character);
}
fclose(fin);
fclose(fout);
printf("\nFile has been created...\n");
return 0;
}
This code worked for me:
/* fgetwc example */
#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <locale.h>
int main ()
{
setlocale(LC_ALL, "en_US.UTF-8");
FILE * fin;
FILE * fout;
wint_t wc;
fin=fopen ("in.txt","r");
fout=fopen("out.txt","w");
while((wc=fgetwc(fin))!=WEOF){
// work with: "wc"
}
fclose(fin);
fclose(fout);
printf("File has been created...\n");
return 0;
}
If you do not wish to use the wide options, experiment with the following:
Read and write bytes, not characters.
Also known as, use binary, not text.
fgetc effectively gets a byte from a file, but if the byte is greater than 127, try treating it as a int instead of a char.
fputc, on the other hand, silently ignores putting a char > 127. It will work if you use an int rather than char as the input.
Also, in the open mode, try using binary, so try rb & wb rather than r & w
The C-style solution is very insightful, but if you'd consider using C++ the task becomes much more high level and it does not require you to have so much knowledge about utf-8 encoding. Consider the following:
#include<iostream>
#include<fstream>
int main(){
wifstream input { "in.txt" }
wofstream output { "out.txt" }
// Look out - this part is not portable to windows
locale utf8 {"en_us.UTF-8"};
input.imbue(utf8);
output.imbue(utf8);
wcout.imbue(utf8);
wchar_t c;
while(input >> noskipws >> c) {
wcout << c;
output << c;
}
return 0;
}