Glad to ask you again!
I want to create a program that basically reads a file called message.txt which would have some texts with a message, let's say: ''Hello I am a program'' and then encrypts that message and puts it in a file called encryptMessage.txt, additionally it will save the key used for the user in the file key.txt. Now this is what I have done so far. I don't know how to make the program read the file message.txt, show it into the screen and then encrypt it into the file. Any piece of advice? Thank you!
I was planning to use fscanf, but I can't use it because it's a line, not just a single string.
Please, if possible write the code yourself so I can compare it to what I have written so far. I always appreciate your feedback, thanks!
#include <stdio.h>
#include <ctype.h>
#define MAXSIZE 100
int main(void)
{
FILE *message;
FILE *encryptMessage;
FILE *key;
message = fopen("message.txt", "r");
encryptMessage = fopen("encryptMessage.txt", "w");
key = fopen("key.txt", "w");
if ((encryptMessage == NULL) || (encryptMessage == NULL) || (encryptMessage == NULL))
{
printf("Error reading file!!!\n");
return 1;
}
int userKey;
char sentence[MAXSIZE];
char q[MAXSIZE];
int i = 0;
printf("Input the text that you want to encrypt:\n> "); // These two lines are a test to see if I was able to encrypt the message, but this is not necessary. It should directly read the file called message.txt.
fgets(sentence, 99, stdin);
// printf("\nThe string that you wrote is:\n%s\n\n", sentence);
printf("Input the key:\n");
scanf("%d", &userKey);
fprintf(key, "%d", userKey);
//printf("\nThe key that you selected is: %d\n\n", userKey);
for(i = 0; sentence[i] != '\0'; ++i)
{
if( ( isupper(sentence[i]) ) || ( islower(sentence[i]) ) )
{
q[i] = sentence[i] + (char)userKey;
}
else
{
q[i] = (sentence[i]);
}
}
q[i] = '\0';
printf("%s", q);
fprintf(encryptMessage, "%s", q);
fclose(encryptMessage);
return 0;
}
To read a line from message.txt you need to use fgets function.
fgets(sentence, 99, stdin);
The above fgets(which you have in your code) reads from the stdin which is normally the keyboard. To make it read from the text file,use
fgets(sentence, MAX_SIZE, message);
Note the change in the second argument too. If you want to display whatever was scanned,uncomment the below line which you have in your code
//printf("\nThe string that you wrote is:\n%s\n\n", sentence);
Don't forget to close(using fclose) all the FILE pointers which you had opened(using fopen) after its use.
Related
im trying to implement the number guessing game. The game itself works fine. But now I want to add a function which safes the score of the last game (Number of trys and guessed number) in the leaderboard.txt file.
I haven't finished the saveScore method yet, I don't need help with implementing the rest. I wan't to read the data from the file, add the new line and sort it from least to most trys. But I only wan't to save the top 10 of all time.
I need some help to get the following code running. One problem is the code doesn´t even terminate.
I think all the problems are within the saveScore method. (line 18 -25)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define max_length 300
void saveScore(int guess, int randNumber) {
FILE *datei;
datei = fopen("leaderboard.txt", "wb");
char lines[max_length];
char leaderboard[10][max_length];
int line = 0;
while (fgets(leaderboard[line], sizeof(lines), datei) != NULL){
line++;
}
leaderboard[line][max_length] = ("%d, %d", guess, randNumber);
fwrite(leaderboard, sizeof(char), sizeof(leaderboard), datei);
fclose(datei);
}
void startGame(){
int guess = 1;
int randNumber;
int uInput;
randNumber = (rand()%100)+1;
printf("%d", randNumber);
do {
printf("Guess the number between 1-100: \n");
scanf("%d", &uInput);
if (uInput < randNumber){
printf("the number you are looking for is higher.\n");
}
else if (uInput > randNumber){
printf("the number you are looking for is lower.\n");
}
else {
printf("Jackpot it was your %d. try.", guess);
}
guess++;
} while (randNumber != uInput);
saveScore(guess, randNumber);
char playAgain = 'j';
printf("Try Again (j/n): \n");
scanf(" %c", &playAgain);
if (playAgain == 'j') {
startGame();
}
printf("Thank you for playing.");
}
int main() {
srand(time(NULL));
startGame();
return 0;
}
I appreciate any help.
Best Enno
This loop has the problem of being able to overflow leaderboard if line ever reaches 10.
while (fgets(leaderboard[line], sizeof(lines), datei) != NULL){
line++;
}
This line
leaderboard[line][max_length] = ("%d, %d", guess, randNumber);
has a few problems. [max_length] would be one past the end of the buffer, but with that said, it is not needed and the assignment as a whole is incorrect. To perform string interpolation, use a function such as sprintf.
Aside from the fact that you only open the file for writing, the primary problem is that
fwrite(leaderboard, sizeof(char), sizeof(leaderboard), datei);
will write the entire contents of leaderboard to the file. This includes the garbage values that exist towards the end of each array, after each string. fgets will then read those garbage values later.
You should stick to reading and writing binary or text, but do not mix them. If you use fgets, use fputs (or similar) to write the text. Conversely, if you use fwrite, use fread to read the binary data.
Here is a basic, cursory snippet using text functions, where we:
open the file for reading
read our lines into the array
close the file
add our new score to the array
sort our array using qsort
open the file for writing
write our lines
close the file
The trick here is leaderboard has an additional slot, so that there is always room for our newest score. After sorting, we only write at most MAX_ENTRIES entries to the file, meaning if the array is full we ignore the worst score.
#define MAX_ENTRIES 10
#define MAX_LENGTH 300
#define SAVE_FILE "leaderboard.txt"
int compare(const void *ap, const void *bp) {
const char (*a)[MAX_LENGTH] = ap;
const char (*b)[MAX_LENGTH] = bp;
int av, bv;
sscanf(*a, "%d", &av);
sscanf(*b, "%d", &bv);
return (av > bv) - (av < bv);
}
void saveScore(int guess, int randNumber) {
char leaderboard[MAX_ENTRIES + 1][MAX_LENGTH] = { 0 };
size_t entries = 0;
FILE *file = fopen(SAVE_FILE, "r");
if (file) {
while (entries < MAX_ENTRIES &&
fgets(leaderboard[entries], sizeof *leaderboard, file))
entries++;
fclose(file);
}
sprintf(leaderboard[entries], "%d %d\n", guess, randNumber);
entries++;
qsort(leaderboard, entries, sizeof *leaderboard, compare);
file = fopen(SAVE_FILE, "w");
if (file) {
for (size_t i = 0; i < entries && i < MAX_ENTRIES; i++)
fputs(leaderboard[i], file);
fclose(file);
}
}
I am working on a assignment:
Open a text file and print its contents in command window, ask the user to
replace the text from the text file to be written and save the text
file.
When I set the maximum character size to 256,it works but when I give 20 it doesn't. Is there a way to overcome this problem by printing the characters beyond the defined limit?
I have used fgets() function.
#include <stdio.h>
#include <string.h>
#define MAX 20
int main(){
FILE *fptr1, *fptr2;
int lno, linectr = 1;
char str[MAX],fname[MAX];
char newln[MAX], temp[] = "temp.txt";
printf("\n\n Replace a specific line in a text file with a new text :\n");
printf(" Input the file name to be opened : ");
fgets(fname, MAX, stdin);
fname[strlen(fname) - 1] = '\0';
fptr1 = fopen(fname, "r");
if (!fptr1)
{
printf("Unable to open the input file!!\n");
return 0;
}
fptr2 = fopen(temp, "w");
if (!fptr2)
{
printf("Unable to open a temporary file to write!!\n");
fclose(fptr1);
return 0;
}
printf(" Input the content of the new line : ");
fgets(newln, MAX, stdin);
fgets(str, MAX, stdin);
printf(" Input the line no you want to replace : ");
scanf("%d", &lno);
lno++;
while (!feof(fptr1))
{
strcpy(str, "\0");
fgets(str, MAX, fptr1);
if (!feof(fptr1))
{
linectr++;
if (linectr != lno)
{
fprintf(fptr2, "%s", str);
}
else
{
fprintf(fptr2, "%s", newln);
}
}
}
fclose(fptr1);
fclose(fptr2);
remove(fname);
rename(temp, fname);
printf(" Replacement did successfully\n");
return 0;
}
I'm assuming you are asking how to read a 100 char long line into a 20 char sized buffer.
Well, obviously the whole line does not fit into the buffer. You need to read in chunks. You know you've read the last chunk when the buffer contains a newline (or EOF is reached)...
if (!fgets(str, MAX, fptr1)) /* EOF detected */;
//let's see if we got a partial line
size_t len = strlen(str); // note: len != 0 for text files
if (str[len - 1] == '\n') {
// full line
// do the comparison or whatever
} else {
// fgets got first chunk
// read rest of line and ignore it
for (;;) {
int ch = fgetc(fptr1);
if (ch == EOF) /* EOF detected */;
if (ch == '\n') break; // full line read, ready for next one
}
}
I'm trying to get better at coding in general and C in particular, and am coding a small text adventure game. I read a string input by the user i.e LOOK room and compare it to a txt file with the list of commands for that particular section.
As I am reading from the text file I have a counter which keeps track of which line is being read, when the match is made I convert the line number to a character and concatenate it to "outside.txt" so that when the correct command is input it will read from the correct file i.e LOOK room would load text from 1outside.txt etc.
However, when inputting anything it just loops on "I dont understand" forever. Any explanation as to why or constructive comments on my code are appreciated, especially if I am misunderstanding how files and/or strings in c.
int mansionOutside(void)
{
int stop = 1;
char choice[25];
char word_match[25];
char text_line[73];
char line1[25];
char temp[2];
int counter;
FILE *fptr;
fptr = fopen("mansion_commands.txt", "r");
if (fptr == NULL)
{
printf("ERROR!");
}
else
{
while (stop == 1)
{
printf("\n");
fgets(choice, sizeof choice, stdin);
while (fgets (line1, 25, fptr)!= NULL)
{
if (strcmp(line1, choice) == 0)
{
printf("%s\n", line1);
stop = 0;
break;
}
else
{
counter++;
printf("%s + %s\n", line1, choice);
}
}
if (stop == 1)
{
printf("I dont understand\n");
counter = 1;
}
}
fclose(fptr);
counter = counter + '0';
temp[0] = counter;
temp[1] = '\0';
strncat(word_match, temp , 1);
strcat(word_match, ".txt");
fptr = fopen(word_match, "r");
if (fptr == NULL)
{
printf("ERROR!\n");
}
else
{
printf("Debugging : File opened Successfully\n");
while (fgets (text_line, 72, fptr) != NULL)
{
printf("%s", text_line);
//delay(2);
}
}
}
}
EDIT : Took in suggestions for improvements to avoid Buffer overflows such as using > fgets , but I think there is something I have missed. Now If I input anything contained in the file, it works fine. If however I input something wrong, then something correct on re-prompt, It skips the inner while loop all together and goes straight to "I don't understand".
The following is what happens when my input is LOOK room, and then LOOK mansion.
this is a program that is giving me many headaches, but I am tackling it!
I want to create a program that basically reads a file called message.txt which would have some texts with a message, let's say: ''Hello I am a program'' and then encrypts that message and puts it in a file called encryptMessage.txt, additionally it will save the key used for the user in the file key.txt. Now this is what I have done so far.
That part is already finished. There's only one last thing that I need to do.
The file message.txt has more than one line. For example:
hello I like programming
this is a test
to see if this program
can read and encrypt many lines
I want the program to read all those lines and then encrypt them and save them in encryptMessage.txt, such as this (let's suppose the key is 3):
khoor L olnh surjudpplqj
wklv lv d whvw
wr vhh wklv surjudp
fdq uhdg dqg hgfu|sw pdq| olqhv
However, I do not know how to make it work. I know I need to use a loop and !feof function or something like that. But I sincerely do not know how to implement, do you have any idea? Thank you very much!
#include <stdio.h>
#include <ctype.h>
#define MAXSIZE 100
int main(void)
{
FILE *message;
FILE *encryptMessage;
FILE *key;
message = fopen("message.txt", "r");
encryptMessage = fopen("encryptMessage.txt", "w");
key = fopen("key.txt", "w");
if ((message == NULL) || (encryptMessage == NULL) || (key == NULL))
{
printf("Error reading file!!!\n");
return 1;
}
int userKey;
char sentence[MAXSIZE];
char q[MAXSIZE];
int i = 0;
printf("Input the text that you want to encrypt:\n> ");
fgets(sentence, 99, message);
// printf("\nThe string that you wrote is:\n%s\n\n", sentence);
printf("Input the key:\n");
scanf("%d", &userKey);
fprintf(key, "%d", userKey);
//printf("\nThe key that you selected is: %d\n\n", userKey);
for(i = 0; sentence[i] != '\0'; ++i)
{
if( ( isupper(sentence[i]) ) || ( islower(sentence[i]) ) )
{
q[i] = sentence[i] + (char)userKey;
}
else
{
q[i] = (sentence[i]);
}
}
q[i] = '\0';
printf("%s", q);
fprintf(encryptMessage, "%s", q);
fclose(encryptMessage);
fclose(key);
fclose(message);
return 0;
}
Here's how you can read entire file:
while(fgets(sentence, MAXSIZE - 1, message)) {
// do something with sentence
}
Here is modified source code: http://pastebin.com/KxAe9KcS
So i've been given an exercise to work on: Have the user input a number and the program will display the line of text associated with that line for example
Password
abcdefg
Star_wars
jedi
Weapon
Planet
long
nail
car
fast
cover
machine
My_little
Alone
Love
Ghast
Input 3: Output: Star_wars
Now i have been given a program to solve this, however it uses the function getline() , which doesn't complie on DEV C++.
#include <stdio.h>
int main(void)
{
int end = 1, bytes = 512, loop = 0, line = 0;
char *str = NULL;
FILE *fd = fopen("Student passwords.txt", "r");
if (fd == NULL) {
printf("Failed to open file\n");
return -1;
}
printf("Enter the line number to read : ");
scanf("%d", &line);
do {
getline(&str, &bytes, fd);
loop++;
if (loop == line)
end = 0;
}while(end);
printf("\nLine-%d: %s\n", line, str);
fclose(fd);
}
All i need is to know how to do this, in a simple program without the use of getline()
Thanks
Edit: I also don't want to download software to make this work
use fgets instead of getline.
#include <stdio.h>
int main(void){
int end, loop, line;
char str[512];
FILE *fd = fopen("data.txt", "r");
if (fd == NULL) {
printf("Failed to open file\n");
return -1;
}
printf("Enter the line number to read : ");
scanf("%d", &line);
for(end = loop = 0;loop<line;++loop){
if(0==fgets(str, sizeof(str), fd)){//include '\n'
end = 1;//can't input (EOF)
break;
}
}
if(!end)
printf("\nLine-%d: %s\n", line, str);
fclose(fd);
return 0;
}
You have wrote:
char *str = NULL;
and you used it without initializing:
getline(&str, &bytes, fd);
first you must initialize it:
char *str=(char*)malloc(SIZEOFSTR);
you can add this part in your program instead of your do-while loop. You will be using fscanf() whose arguments are the file pointer, specifier of data type and the variable you want to store.
printf("Enter the line number to read : ");
scanf("%d", &line);
while(line--) {
fscanf(fd,"%s",str);
}
printf("\nLine-%d:%s\n",line,str);