I'm creating a program that asks the user to input a word. The word is then compared with a word in a text file. If correct, I want the user to input another word which should correspond with the next word in the text file and this should loop until the end of the file. I'm having trouble with the loop to the end of the file. Could someone please review my code and give me a few pointers? thanks so much
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
//Step 1: open file and declare variables//
FILE *fp;
fp = fopen("secretwords.txt","r");
char guess[20];
char secret[20];
int i, count;
//Step 2: Check that file opened correctly, terminate if not//
if (fp == NULL)
{
printf("Error reading file\n");
exit (0);
fclose(fp);
}
//Step 3: Create loop to run for each word to run to end of file//
fscanf(fp,"%s", secret);
//Need to create a loop here that will read the text file 20 times,
// each time reading the next word//
for (i=0; i < 3; i++)
{
printf("Please guess the word: \n");
scanf("%s", guess);
if (strcmp(secret,guess)==0)
{
printf("Your guess was correct\n");
return 0; //This return will terminate the program.
// I need to restart loop from here
}
else
{
printf("Your guess was incorrect. Please try again\n");
}
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
FILE *fp = fopen("secretwords.txt", "r");
if (fp == NULL)
{
printf("Error reading file\n");
return 1;
}
char guess[20] = {0};
char secret[20] = {0};
while(fscanf(fp, "%s", secret) != EOF) // i would suggest you use 'fscanf_s("%s", guess);' instead if available
{
printf("Please guess the word: \n");
scanf("%s", guess); // i would suggest you use 'scanf_s("%s", guess);' instead if available
if (!strncmp(secret, guess, sizeof(guess)))
{
printf("Your guess was correct. Continue ...\n");
}
else
{
printf("Your guess was incorrect. Good bye.\n");
break;
}
}
fclose(fp);
return 0;
}
i made some suggestions about scanf_s and fscanf_s, if they are available, use them. But still, i am wondering why they are still teaching bad code in schools? I would not suggest to use *scanf* functions at all. Further reading: uncontrolled format string
Move the fscanf call that reads from the file to a function that returns the next word
loop for user input, only calling the function outlined above when you need to advance to the next word in the file (when the user inputs the correct thing)
Related
i'm new here and i'm trying to solve a FILE problem in c. Basically i have to create a program that lets the user input how many lines he wants to write in a file, create a new file, write those lines and the reading it and establish how many lines where written and print the number of lines.
int main() {
int x, lc=0;
char str[100];
FILE *fp=fopen("test.txt","w");
if (fp==NULL) {
printf("\nOpening failed");
}else{
printf("\nOpened correctly");
}
printf("\nStrings to write:\n");
scanf("%d",&x);
for (int i = 0; i < x; i++) {
fgets(str, sizeof str, stdin);
fputs(str,fp);
}
fclose(fp);
FILE *fr=fopen("test.txt", "r");
while (fgets(str, 100, fr)!=NULL) {
lc++;
}
fclose(fr);
printf("\nThere are %d lines",lc);
return 0;
}
If i leave the code like this it messes up with my for cycle and it only lets me write 3 lines because it does put a free line at the start of the file. Can you explain how do i solve that? or if it's just how fgets and fputs behave and i have to remember that blank line at the start. Thank you in advance. (i'll leave a file output as follows with numbers for the lines)
1)
2)it seems to work
3)dhdhdh dhdh
4)random things
As you can tell from the comments, there are a lot of ways to approach this task. The usage of "scanf" and "fgets" can get complex especially if mixed within the same reading task. But, just to give you one option as to deriving a solution, following is a snippet of code to offer one of many possible routes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int x, lc=0;
char str[101];
FILE *fp=fopen("test.txt","w");
if (fp==NULL)
{
printf("Opening failed\n");
}
else
{
printf("Opened correctly\n");
}
printf("Strings to write: ");
scanf("%d",&x);
for (int i = 0; i < x; i++)
{
printf("Enter string: ");
scanf("%s", str);
fprintf(fp, "%s\n", str);
}
fclose(fp);
FILE *fr=fopen("test.txt", "r");
while (fgets(str, 100, fr)!=NULL)
{
lc++;
}
fclose(fr);
printf("\nThere are %d lines\n",lc);
return 0;
}
You will note that both "scanf" and "fgets" are being used in this example, but not in reference to the same file. For user input, "scanf" is getting used. Once the file is closed and then reopened for reading, "fgets" is being used for that portion of the task.
Testing this program snippet out resulted in matching up the same quantity of lines read from the file as were entered.
#Una:~/C_Programs/Console/FileWrite/bin/Release$ ./FileWrite
Opened correctly
Strings to write: 4
Enter string: Welcome
Enter string: to
Enter string: Stack
Enter string: Overflow
There are 4 lines
Give it a try and see if it meets the spirit of your project.
I'm trying to write a program that asks for input of the name of a file and a char to be counted inside the file. But whenever I input the proper name of a file (like, "file.txt") it jumps right to the end of the program with a output like this:
"Name of the file: file.txt
Character to be counted:
The char occurs 0 times in the file "
...but I couldn't even type the char to be counted.
I know it's not an issue with the name of the file, because if I put the wrong name, it goes for the output I programmed for.
Would anyone care to explain me what's happening?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char filename[128];
printf("Name of the file: ");
scanf("%s", filename);
FILE * test = fopen(filename, "r");
if (test == NULL) {
printf("Error!!\n");
exit(1);
}
char inpt;
printf("Character to be counted:\n");
scanf("%c", &inpt); //gets the character to be counted
int count = 0;
char search = fgetc(test);
while(search != EOF) {
if (search == inpt) count++;
search = fgetc(test);
}
printf("The char occurs %d times in the file\n", count);
return 0;
}
after tirelessly looking for an explanation I've decided to ask the greats at stackoverflow. So I'm currently trying to read each input line by line from a file called data.txt. The program works perfectly fine using simple scanf and such, but when I want to read input values from a file the program only reads the first 3 lines of the txt and it keeps repeating in an infinite loop. My code is shown below. I kept out the majority of my code in case others may be tempted to use it. Program will just read 1, 12, 0 infinitely. sample data.txt file is shown below
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
// Global variables
char *Hstring = NULL;
int maxLength, parity;
char *temp = NULL;
int userChoice = 0;
void option1() {
// User inputs length and even or odd parity bit
printf("\n*** Maximum Code Length: %d", maxLength);
//scanf("%d",&maxLength);
printf("\n*** Parity: %d", parity);
//scanf("%d",&parity);
// allocate memory for hamming string based on maximum length and
//size of character element
Hstring = (char *)malloc(maxLength * sizeof(char));
return;
}
void option2() {
/* declare local vars */
int aLength, k, parBits, parValue, errorPos, i, j;
/* prompt for hamming code as a "string"*/
printf("\nEnter the Hamming Code: ");
scanf("%s", Hstring);
temp = Hstring;
aLength = strlen(Hstring);
parBits = ceil(log(aLength) / log(2));
}
int main() {
FILE *fp;
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("ERROR OPENING THE FILE\n");
}
fscanf(fp, "%d %d %d", &userChoice, &maxLength, &parity);
//end file open
while (userChoice != 3) {
printf("\nEnter Selection: %d", userChoice);
//scanf("%d",&userChoice);
switch (userChoice) {
case 1:option1();
break;
case 2:option2();
break;
case 3:
printf("\n*** Program Terminated Normally\n");
break;
default: printf("invalid input please input another number\n\n");
break;
}
}
/* print out menu, prompt for choice, and call appropriate procedure
until user quits */
return 1;
}
SAMPLE data.txt
1
12
0
2
1000
1
Code starts to loop when it reads the third integer(parity) in option1()
Any help would be appreciated. Thank you!
You never modify userChoice in your while loop, so it's gonna loop forever.
Anyways, even if you were using fscanf in the while loop, and therefore reading the whole file until you find userChoice == 3, it's a bad idea to have your loop termination condition only depending on the content of a file, you should also check the result of fscanf for termination of the file. Your example data would still loop forever because it contains no 3.
The answer here https://stackoverflow.com/a/53475412/4386427 is correctly describing the problem, i.e. that you have an endless loop because userChoice is only read once.
Here is a suggestion for a fix.
int main() {
FILE *fp;
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("ERROR OPENING THE FILE\n");
}
while (userChoice != 3) {
// Check that exactly 3 items are read from the file.
// If not terminate the program
if (fscanf(fp, "%d %d %d", &userChoice, &maxLength, &parity) != 3) {
printf("Illegal input from file or EOF. Terminating program\n");
break;
}
switch (userChoice) {
case 1:option1();
break;
case 2:option2();
break;
case 3:
printf("\n*** Program Terminated Normally\n");
break;
default: printf("invalid input please input another number\n\n");
break;
}
}
return 1;
}
I'm writing a spellchecking program that will compare a user's text file with a dictionary to see if the words they entered are in the dictionary. If not, an error message is printed to tell the user that the specific word is wrong. I've tried a number of variations of the code below but not getting the desired results. It's something in the nested while loop that's throwing it out. This code is in draft stage I have to make it more memory efficient etc and tidy it up. I'm just interested in getting it working first. Thanks!
EDIT: Have altered the code slightly as per the tips below. It now reads the first word and says that it is in the dictionary. It then displays the second word but the dictionary scanning loop doesn't run and the program hangs. I know its the nested while loop causing the issue I just can't get my head around it!
/*Spellcheck program*/
/*Author: */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
/*Open files and test that they open*/
FILE *fp1;
FILE *fp2;
char fname[20];
char wordcheck[45];/*The longest word in the English Language is 45 letters long*/
char worddict[45];
char dummy;
int i;
int dictcount = 0;
fp1 = fopen("dictionary.txt","r");
if (fp1 == NULL)
{
printf("The dictionary file did not open.");
exit(0);
}
printf("Please enter the path of the file you wish to check:\n");
scanf("%s", fname);
scanf("%c", &dummy);
fp2 = fopen(fname, "r");
if (fp2 == NULL)
{
printf("Your file did not open, please check your filepath and try again.\n");
printf("Please enter path of file you wish to check: \n");
scanf("%20s",fname);
fp2 = fopen(fname, "r");
}
else
{
printf("Your file opened correctly\n");
}
/*When files are open, read each word from the text file into an array:*/
while(fscanf(fp2,"%s", wordcheck)!=EOF)//Reads word from text file into array//
{
for (i=0; wordcheck[i]; i++)
{
wordcheck[i] = tolower(wordcheck[i]);//makes all characters lower case//
}
printf("%s", wordcheck);
while(dictcount >= 0)//reads dictionary word into array//
{
dictcount = 0;
fscanf(fp1,"%s", worddict);
if(strcmp(wordcheck, worddict)==0)//compare strings//
{
printf("This word: %s is in the dictionary\n", wordcheck);
break;
}
else
{
dictcount++;
}
if(worddict == NULL)
{
printf("Your word: %s is not in the dictionary\n", wordcheck);
}
}
dictcount++;
}
fclose(fp1);
fclose(fp2);
return 0;
}
The usual way of solving this is to first read the dictionary and build a hash table. You'd then read one word at a time from the input file and flag an error if the word doesn't exist on the hash table.
This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Compare two text files - spellchecking program in C
I am making a spellcheck program and have an operational code that works but really needs refinement.
Problem 1: I only want to read alphanumeric characters into the wordcheck array before comparing the strings. I want to get rid of all special characters. I think isalphnum would be the best option but not sure how to implement it.
Problem 2: Program is very slow and wasting a lot of memory. I don't know how else to do it though. Could anyone give me some pointers? I'm lost with using binary functions and that's what I'm sure I should be doing! Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
/*Open files and test that they open*/
FILE *fp1;
FILE *fp2;
char fname[20];
char wordcheck[45];/*The longest word in the English Language is 45 letters long*/
char worddict[45];
char dummy;
int i;
int notfound;
fp1 = fopen("dictionary.txt","r");
if (fp1 == NULL)
{
printf("The dictionary file did not open.");
exit(0);
}
printf("Please enter the path of the file you wish to check:\n");
scanf("%s", fname);
scanf("%c", &dummy);
fp2 = fopen(fname, "r");
if (fp2 == NULL)
{
printf("Your file did not open, please check your filepath and try again.\n");
printf("Please enter path of file you wish to check: \n");
scanf("%20s",fname);
fp2 = fopen(fname, "r");
}
else
{
printf("Your file opened correctly\n");
}
/*When files are open, read each word from the text file into an array:*/
while(fscanf(fp2,"%s", wordcheck)!=EOF)//Reads word from text file into array//
{
for (i=0; wordcheck[i]; i++)
{
wordcheck[i] = tolower(wordcheck[i]);//makes all characters lower case//
}
fseek(fp1,0,SEEK_SET);
/*printf("%s", wordcheck);//debugger*/
while(fscanf(fp1,"%s", worddict)!=EOF)
{
notfound = 1;
if(strcmp(wordcheck, worddict)==0)//compare strings//
{
printf("This word: %s is in the dictionary\n", wordcheck);//debugger//
notfound = 0;
break;
}
}
if(notfound == 1)
{
printf("%s is not in dictionary\n", wordcheck);
}
}
printf("Your file has been checked. Please check any errors found");
fclose(fp1);
fclose(fp2);
return 0;
}
You're reading the dictionary once for each input word! If your input file is long then load the dictionary first into memory and then check each word in the file. If the dictionary is long you may need to store it into a hash table or a trie. But even a simple array of dictionary words should give you an improved run time.