Read from a text file shift cipher in C - c

I'm working on Shift cipher, I am having problems with encryption. It has no errors or trouble compiling but after I run it the output file is empty. i think reading the file but not encrypted out.txt file is empty. i didn't solve it. Thank you.
int main
{
file_in = fopen("/Users/mathmoiselle/Desktop/lucky.txt", "r");
if( file_in == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
file_out = fopen("/Users/mathmoiselle/Desktop/out.txt","r");
return 0;
}

Following on from my comments. You need to rewind the file pointer for file_in and also your includes were poorly formatted at the top. Not sure whether this makes a difference (beginner myself, but certainly stuck out when I read it):
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int encode (int, int);
int encode(int ch, int key) {
if (islower(ch)) {
ch = (ch-'a' + key) % 26 + 'a';
ch += (ch < 'a') ? 26 : 0;
}
else if (isupper(ch)) {
ch = (ch-'A' + key) % 26 + 'A';
ch += (ch < 'A') ? 26 : 0;
}
return ch;
}
int main (void)
{
FILE *file_in;
FILE *file_out;
char ch;
char text[300];
int key;
// gets(text); // Removed in question
file_in = fopen("shift_cipher.c", "r");
if( file_in == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
printf("\n The contents of the file are : \n");
while( ( ch = fgetc(file_in) ) != EOF )
{
printf("%c",ch);
}
rewind(file_in);
// while (fgets(line, MAXLINE, f1)) {
// printf("%s", line);
// }
// gets(text); // Removed in question
file_out = fopen("out.txt","w");
printf("\n Enter the alphabetic offset key you would like to use:");
scanf("%d", &key);
while( ( ch = fgetc(file_in) ) != EOF )
{
printf("%c", ch);
ch=encode(ch, key);
fprintf(file_out, "%c", ch);
}
printf("file has been encoded");
fclose(file_out);
fclose(file_in);
return 0;
}

Related

How to clear blank lines in files using c?

I am working on a management system project and want to clear the file before adding data to it. I am using this code as a reference. I have rewritten the code from the reference and instead of writing the data from the temporary file(tmp) back to the original(FILE_NAME), I have printed it out to the terminal.
When I compile and run the program, it prints all the content and a few more lines after the end of the file. After this it stops and doesn't finish execution. I have added to comments to help understand my thought process better.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define BUFFER_SIZE 1000
#define FILE_NAME "data.csv"
int main()
{
FILE* file;
char buffer[BUFFER_SIZE];
// Opening file
if(file = fopen(FILE_NAME, "r+"))
{
char c; // To get character from buffer
int i = 0; // Index for the buffer character
int isEmpty = 1; // If the line is empty
FILE* tmp;
if(tmp = tmpfile())
{
while(1)
{
buffer[i++] = c;
if(c != '\n') // Checking for blank lines
{
isEmpty = 0;
}
else
{
if(c == '\n' && isEmpty == 0) // Read a word; Print to tmp file
{
buffer[i] = '\0';
fprintf(tmp, "%s", buffer);
i = 0;
isEmpty = 1;
}
else if(c == '\n' && isEmpty == 1) // NOT SURE WHY THIS IS IMPORTANT
{
buffer[i] = '\0';
i = 0;
isEmpty = 1;
}
}
if(c == EOF)
{ break; }
while(1) // Loop to print contents of tmp file onto terminal
{
c = getc(tmp);
printf("c: %c", c);
if(c == EOF)
{ break; }
}
}
}
else
{
printf("Unable to open temporary file\n");
}
fclose(file);
}
else
{
printf("Unable to open file.");
}
getchar();
return 0;
}
UPDATE:
I've modified a few lines and have got it working.
I'd forgotten to assign c in the above program. Also #Barmar won't char c work just as well as int c. Characters can be integers as well right?
Why would large indentations lead to bugs? I find the blocks of code to be more differetiated.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define BUFFER_SIZE 1000
#define FILE_NAME "data.csv"
int main()
{
// Variable Declaration
FILE* file;
char buffer[BUFFER_SIZE];
// Opening file
if( file = fopen(FILE_NAME, "r+") )
{
char c; // Reading characters from the file
int i; // Index of the characters
int isEmpty = 1; // 1-> character is empty; 0-> character is not empty
FILE* tmp;
if( tmp = fopen("tmp.csv", "a+") )
{
char c; // Reading characters from files
int i = 0; // Index
int isEmpty = 1; // 1->previous word is empty; 0->previous word is not empty
while( (c = getc(file)) != EOF)
{
if( c != '\n' && c != ' ' && c != '\0' && c != ',')
{
isEmpty = 0;
buffer[i++] = c;
}
else
{
if( c == '\n' && isEmpty == 0 )
{
buffer[i] = '\0';
fprintf(tmp, "%s", buffer);
i = 0;
isEmpty = 1;
}
else if( c == '\n' && isEmpty == 1 )
{
buffer[i] = '\0';
i = 0;
}
}
}
fclose(tmp);
}
else
{
printf("Unable to open temporary file\n");
}
fclose(file);
}
else
{
printf("Unable to open file\n");
}
return 0;
}
Are there are ways to simplify the program and make it more compact or less error prone?

How to check if there is no content inside a file, and how to avoid reading the last character from a file?

I have used comma as a separator after every string
fp=fopen("log.dat","ab");
fprintf(fp,"%s%c",enteredUsername,',');
fclose(fp);
Reading from file:
fp=fopen("log.dat","rb");
int c;
while ((c = fgetc(fp)) != EOF)
printf("%c", c);
How can I:
1.Avoid reading the final character inside the file,
2.Check if file is empty?
You can use a one-character buffer like this:
#include <stdio.h>
int main(void)
{
FILE *fp = fopen("log.dat", "rb");
if(fp == NULL) return;
int prev = -1000;
int c;
while ((c = fgetc(fp)) != EOF) {
if(prev >= 0) {
printf("%c", prev);
}
prev = c;
}
fclose(fp);
return 0;
}
Input log.dat
one,two,three,
Output
one,two,three
Why you want to avoid reading the final character? You can use the EOF in order to check if a file is empty.
if( (c= fgetc(fp)) == EOF){
//do stuff
}
else{
printf("File is empty\n")
return 0;
}
That worked for me.
#include <stdio.h>
int main(void) {
unsigned counter;
for( counter=0; 1; counter++) {
int ch;
char lastchar;
ch = getc(stdin);
if (ch == EOF) break;
if (counter) putc( lastchar, stdout);
lastchar = ch;
}
if (!counter) fprintf(stderr,"File was empty\n" );
else fprintf(stderr,"Read %u characters.\n", counter );
return 0;
}
// Test it with:
// echo -n "a,b,c," >bagger
// ./a.out <bagger

Most common letter on a file (C programming)

I need to create a function that finds the most common letter in a file using C.
Can't figure out my problem, for some reason it always returns [.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char commonestLetter(char* filename);
void main()
{
char str[101], ch;
FILE *fout;
fout = fopen("text.txt", "w");
if (fout == NULL)
{
printf("Can't open file\nIt's probably your fault, worked perfectly on my PC ;)\n");
fclose(fout);
}
printf("Enter string (to be written on file)\n");
gets(str);
fputs(str, fout);
ch = commonestLetter("text.txt");
printf("The most common letter is %c\n", ch);
fclose(fout);
}
char commonestLetter(char* filename)
{
char ch;
int i, count[26];
int max = 0, location;
FILE *f = fopen(filename, "r");
if (f == NULL)
{
printf("file is not open\n");
return;
}
for (i = 0; i < 26; i++)
count[i] = 0;
while ((ch = fgetc(f)) != EOF)
{
if (isalpha(ch))
count[toupper(ch) - 'A']++;
}
for (i = 0; i < 26; i++)
{
if (count[i] >= max)
{
max = count[i];
location = i + 1;
}
}
return location + 'A';
}
Do
location=i;
No need of i+1
As you are doing location+'A';
Suppose the location count[25] has the highest count, so the location becomes 25+1=26.
Now the return will be 26+65=91 which is of '['
The code of yours is slightly modified but the logic of your is kept
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char commonestLetter(char* filename);
int main()
{
char str[101], ch;
FILE *fout;
fout = fopen("text.txt", "w");
if (fout == NULL)
{
printf("Can't open file\nIt's probably your fault, worked perfectly on my PC ;)\n");
return 0;
}
printf("Enter string (to be written on file): ");
fgets(str,sizeof(str),stdin);
fputs(str, fout);
fclose(fout);
ch = commonestLetter("text.txt");
printf("The most common letter is %c\n", ch);
return 0;
}
char commonestLetter(char* filename)
{
char ch;
int i, count[26];
int max = 0, location;
FILE *f = fopen(filename, "r");
if (f == NULL)
{
printf("file is not open\n");
return;
}
memset(&count,0,sizeof(count));
while ((ch = fgetc(f)) != EOF)
{
if (isalpha(ch))
count[toupper(ch) - 'A']++;
}
for (i = 0; i < 26; i++)
{
if (count[i] >= max)
{
max = count[i];
location = i;
}
}
fclose(f);
return location + 'A';
}
Input & Output:
Enter string (to be written on file): Gil this is a testing
The most common letter is I
The problem here is, in your code,
location = i + 1;
location is i+1 at the end, and you're returning location + 'A'; which is (because of your input, probably) (25+1) + 'A' , i.e., 26 + 'A' which is [.

Reading a file word by word with no ending chars

I have this small program in C that reads through a file a compares word by word,
how can I assure that words like "this," won't be read as a word? I would like it to read as "this"
int main(int argc, char *argv[]) {
if(argc != 3)
{
printf("Usage: ./sw <word> <filename> \n");
exit(1);
}
char* word = argv[1];
const char* filename = argv[2];
FILE* file = fopen(filename, "r");
if(file == NULL)
{
printf("Could not open file\n");
exit(1);
}
//Assuming one word can not have more than 250 chars
char w[250], check_eof;
do
{
check_eof = fscanf(file, "%s", w);
if(strcmp(word, w) == 0)
{
printf("W : %s \n", w);
}
} while(check_eof != EOF);
fclose(file);
return 0;
}
You can check if a char belongs to a word like this
int c = fgetc(file);
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
// c belongs to a word
word[n++] = c;
} else {
// end of word
if (strncmp(word, w, n) == 0) {
// word and w match!
}
}
If you #include <ctype.h>, then you can call isalpha(c) instead to test it.
In the code below, I use isalpha() and I copy the result string in a new buffer named res. However, this procedure can be done in-place, but I'll leave now for the sake of simplicity.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> // for isalpha()
int main(int argc, char *argv[]) {
char* word = "this";
const char* filename = "test.txt";
FILE* file = fopen(filename, "r");
if(file == NULL)
{
printf("Could not open file\n");
exit(1);
}
//Assuming one word can not have more than 250 chars
// ATTENTION, it is 249 chars, do NOT forget of the null terminator
char w[250], res[250];
int check_eof; // should be of type int, for EOF checking
do
{
check_eof = fscanf(file, "%s", w);
// what if 'word' appears as the last word
// in the file? You should check for eof
// right after fscanf()
if(check_eof == EOF)
break;
int i = 0, j = 0;
while (w[i]) // parse what we read
{
if (isalpha(w[i]))
res[j++] = w[i]; // keep only the alphabetic chars
i++;
}
res[j] = '\0'; // it should be a null terminated string
if(strcmp(word, res) == 0) // compare to 'res' now
{
printf("W : %s \n", res);
}
} while(1); // the terminating step is inside the body now
fclose(file);
return 0;
}

How to convert binary to sentence

I've created a simple Program to store and Retrieve the Passwords whenever I want.For example, I have one password which is Pass so its binary will be 01010000011000010111001101110011. I've created a program that will convert it to binary and will store it in the file. The Program is as given Below:
#include<stdio.h>
#include<conio.h>
#include<string.h>
main()
{
FILE *fptr;
char wname[100];
char uname[100];
char pass[100];
char str[50];
char bin[7];
int c2n,i,ii;
clrscr();
printf("\nEnter website name: ");
fflush(stdin);
gets(wname);
printf("\nEnter the username: ");
fflush(stdin);
gets(uname);
printf("\nEnter password: ");
fflush(stdin);
gets(pass);
fptr=fopen("DND","a");
printf("Binary of entered string is : ");
fprintf(fptr,"\n");
for(i=0;i<=strlen(wname)-1;i++)
{
c2n=wname[i];
for(ii=7;ii>=0;ii--)
{
bin[ii]=c2n%2;
c2n=c2n/2;
}
for(ii=0;ii<=7;ii++)
{
printf("%d",bin[ii]);
fprintf(fptr,"%d",bin[ii]);
}
}
printf(":");
fprintf(fptr,":");
for(i=0;i<=strlen(uname)-1;i++)
{
c2n=uname[i];
for(ii=7;ii>=0;ii--)
{
bin[ii]=c2n%2;
c2n=c2n/2;
}
for(ii=0;ii<=7;ii++)
{
printf("%d",bin[ii]);
fprintf(fptr,"%d",bin[ii]);
}
}
printf(":");
fprintf(fptr,":");
for(i=0;i<=strlen(pass)-1;i++)
{
c2n=pass[i];
for(ii=7;ii>=0;ii--)
{
bin[ii]=c2n%2;
c2n=c2n/2;
}
for(ii=0;ii<=7;ii++)
{
printf("%d",bin[ii]);
fprintf(fptr,"%d",bin[ii]);
}
}
fclose(fptr);
printf("\n Your website name,user name and password are protected in binary....\nPress any key to close coder......");
getch();
return 0;
}
Now, I want to create Decoder for this.I want a program to convert all the binary to one sentence. For example.
01010000011000010111001101110011=Pass
I have no Idea how to create it.
Here's something that works for me.
#include <stdio.h>
int main(int argc, char** argv)
{
int ch1 = 0;
int ch2 = 0;
int count = 0;
// Pass the binary file to be read from as the first argument.
char* file = argv[1];
FILE* in = fopen(file, "r");
if ( in == NULL )
{
printf("Unable to open file %s\n", file);
return 1;
}
while ( (ch1 = fgetc(in)) != EOF )
{
if ( ch1 == '\n' )
{
// Reset counters.
ch2 = 0;
count = 0;
fputc(ch1, stdout);
}
else if ( ch1 == ':' )
{
// Skip it for computing characters.
fputc(ch1, stdout);
}
else
{
ch2 <<= 1;
if ( ch1 == '1' )
{
ch2 += 1;
}
count++;
if ( count == 8 )
{
fputc(ch2, stdout);
count = 0;
}
}
}
fputc('\n', stdout);
fclose(in);
return 0;
}
I think a good way to do this is to make use of the bitwise operations provided by the language. Check out this bit of code:
#include <stdio.h>
int main(){
char buf = 0;
int bufi = 0;
int bit;
FILE *fp;
fp = fopen("bin", "r");
if (!fp){
printf("%s","input file failed to open\n");
return -1;
}
while ((bit = getc(fp)) != EOF){
if (bit == '0')
bit = 0;
else
bit = 1;
buf = buf | (bit << (7 - bufi));
bufi++;
if (bufi == 8){
printf("%c", buf);
bufi = buf = 0;
int i;
}
}
printf("%s","\n");
return 0;
}
Hope this helps. Also check this out for more about bitwise operations:
http://en.wikipedia.org/wiki/Bitwise_operation
Everything inside your computer is already binary. There is usually no reason to convert the binary to strings. If you want to print in binary format, something simple as this will do:
void putc_bin (char ch)
{
for(uint8_t i=0; i<8; i++)
{
printf("%d", (ch & 0x80) ? '1' : '0');
ch <<= 1;
}
}

Resources