I have this function which is supposed to delete the recipe requested by the user. I've always deleted records in this way, but I don't know why this time it doesn't work in the right way. Sometimes it states that there's no match but it deletes the recipe or it deletes all the recipes inside the file and I don't get it why since I basically created a temp file in which writing all the records except for the one the user wants to delete and I used a function that worked for another record so I really don't get it. Is that because the length of ingredients and procedure is not the same for all the recipes?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int stringCmpi (char *s1,char *s2);
struct _recipe
{
char name[40];
int count_i;
char ingredients[20][40];
char diff[12];
int timr;
int calories;
int count_p;
char procedure[30][500];
} recipe;
int main()
{
FILE* fbr;
FILE* temp;
char ricetta_name[] = "ricette.bin";
char temp_name[] = "temp.bin";
fbr = fopen("ricette.bin", "rb");
temp = fopen("temp.bin", "wb");
int found = 0;
char name_t[40];
int i;
char space = '\n';
if(fbr == NULL)
{
printf("Couldn't open the file.\n");
exit(1);
}
if(fbr == NULL)
{
printf("Couldn't open the file.\n");
exit(1);
}
printf("Write the name of the recipe you want to delete:\n");
fgets(name_t,sizeof(name_t),stdin);
space = getchar();
while(fread(&recipe,sizeof(recipe),1,fbr) && found == 0)
{
if(stringCmpi(name_t,recipe.name) == 0)
{
found = 1;
printf("Match found. Recipe deleted.\n");
}
else
{
fwrite(&recipe,sizeof(recipe),1,temp);
}
if(!found)
{
printf("No match.\n");
}
}
fclose(fbr);
fclose(temp);
remove(ricetta_name);
rename(temp_name,ricetta_name);
system("PAUSE");
return 0;
}
int stringCmpi (char *s1,char *s2)
{
int i=0;
for(i=0; s1[i]!='\0'; i++)
{
if( toupper(s1[i])!=toupper(s2[i]) )
return 1;
}
return 0;
}
The problem is here:
while(fread(&recipe,sizeof(recipe),1,fbr) && found == 0)
Once you find a recipe, you exit the loop, so the remaining elements are not copied to the new file. I recommend you delete the && found == 0 clause.
Furthermore:
if(!found)
{
printf("No match.\n");
}
This is actually inside the while loop, so it will report No match multiple times. Please move it outside the loop.
Proper indentation would help you see the actual structure of the program. This is how the posted program looks with consistent indentation:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int stringCmpi (char *s1,char *s2);
struct _recipe
{
char name[40];
int count_i;
char ingredients[20][40];
char diff[12];
int timr;
int calories;
int count_p;
char procedure[30][500];
} recipe;
int main()
{
FILE* fbr;
FILE* temp;
char ricetta_name[] = "ricette.bin";
char temp_name[] = "temp.bin";
fbr = fopen("ricette.bin", "rb");
temp = fopen("temp.bin", "wb");
int found = 0;
char name_t[40];
int i;
char space = '\n';
if(fbr == NULL)
{
printf("Couldn't open the file.\n");
exit(1);
}
if(fbr == NULL)
{
printf("Couldn't open the file.\n");
exit(1);
}
printf("Write the name of the recipe you want to delete:\n");
fgets(name_t,sizeof(name_t),stdin);
space = getchar();
while(fread(&recipe,sizeof(recipe),1,fbr) && found == 0)
{
if(stringCmpi(name_t,recipe.name) == 0)
{
found = 1;
printf("Match found. Recipe deleted.\n");
}
else
{
fwrite(&recipe,sizeof(recipe),1,temp);
}
if(!found)
{
printf("No match.\n");
}
}
fclose(fbr);
fclose(temp);
remove(ricetta_name);
rename(temp_name,ricetta_name);
system("PAUSE");
return 0;
}
int stringCmpi (char *s1,char *s2)
{
int i=0;
for(i=0; s1[i]!='\0'; i++)
{
if( toupper(s1[i])!=toupper(s2[i]) )
return 1;
}
return 0;
}
The program is checking that fbr is not NULL twice. Probably the second check should be for temp.
The programs stops reading and copying when the recipe to be deleted is found; this means that the following records are not copied over.
The program complains that the recipe was not found for each recipe until the desired one is found.
Suggestions:
Modify the while loop condition eliminating the && ! found, so that all records are copied except those matching the given name.
Move the check for if (! found) outside the loop.
Bonus:
The function stringCmpi() stops comparing at the end of string s1; which means that "abc" and "abcdef" will compare equal. You probably want to change return 0 to return s1 [i] != s2 [i].
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _recipe
{
char name[40];
int count_i;
char ingredients[20][40];
char diff[12];
int timr;
int calories;
int count_p;
char procedure[30][500];
} recipe;
int main(int argc, char *argv[])
{
FILE* fbr;
FILE* temp;
char *ricetta_name = "recipe.bin";
char *temp_name = "temp.bin";
int found = 0;
char name_t[40];
// Use command line arguments if possible
if (argc == 2)
{
ricetta_name = argv[1];
}
if((fbr = fopen(ricetta_name, "rb")) == NULL)
{
printf("Couldn't open the file %s.\n", ricetta_name);
exit(1);
}
if((temp = fopen(temp_name, "wb")) == NULL)
{
printf("Couldn't open the file %s.\n", temp_name);
exit(1);
}
printf("Write the name of the recipe you want to delete:\n");
fgets(name_t, sizeof(name_t), stdin);
// Remove '\n'
if (name_t[strlen(name_t) - 1] == '\n')
name_t[strlen(name_t) - 1] = 0;
while(fread(&recipe,sizeof(recipe), 1, fbr))
{
// Use standard strcasecmp()
if(strcasecmp(name_t, recipe.name) == 0)
{
found = 1;
printf("Match found. Recipe deleted.\n");
}
else
{
fwrite(&recipe, sizeof(recipe), 1, temp);
}
}
if (!found)
{
printf("No match.\n");
}
fclose(fbr);
fclose(temp);
remove(ricetta_name);
rename(temp_name,ricetta_name);
return 0;
}
Please format your code: add space(' ') after comma(','). And use standard function if possible.
Related
So I'm working on a project, and I need to check whether or not a certain file contains the contents of another file.
I made a function in c (It's c not c++) to try and to it but it seems to get into an infinite loop and not work overall, I tried using the Visual Studio debugger, and it didn't give me more info.
Note: I am including stdlib.h
the code:
int findFileInFile(const char* wherePath, const char* whatPath)
{
FILE* fpBigger = fopen(wherePath, "r");
FILE* fpSmaller = fopen(whatPath, "r");
if (fpBigger != NULL && fpSmaller != NULL)
{
unsigned char cs = 0;
unsigned char cb = 0;
while ((cb = fgetc(fpBigger)) != EOF)
{
cs = fgetc(fpSmaller);
if (cs == EOF)
return 1;
if (cs != cb)
{
fseek(fpSmaller, 0L, SEEK_SET);
}
}
return 0;
}
else
{
printf("File names are wrong!\n");
exit(-1);
}
}
Thank you.
I guess this is what you're looking for:
#include <stdio.h>
#include <stdlib.h>
int findFileInFile(const char *wherePath, const char *whatPath)
{
FILE *fpBigger = fopen(wherePath, "rb");
FILE *fpSmaller = fopen(whatPath, "rb");
if (fpBigger != NULL && fpSmaller != NULL)
{
unsigned char cs = 0;
unsigned char cb = 0;
int s;
int b;
while (1)
{
b = fgetc(fpBigger);
s = fgetc(fpSmaller);
if (s == EOF && b == EOF) //if both return values from fgetc are EOF, it means you've reached the end of the file which wouldn't have been possible if both of the files weren't equal
{
return 1;
}
else if (s == EOF || b == EOF)
{
return 0;
}
cs=(unsigned char)s; //casting the int to unsigned char
cb=(unsigned char)b; //casting the int to unsigned char
if (cs != cb) //compare the characters gotten from the files, if not equal, return 0
{
return 0;
}
}
}
else
{
printf("File names are wrong!\n");
exit(-1);
}
}
int main()
{
printf("%d", findFileInFile("file1.txt", "file2.txt"));
}
Last but not the least, you can also use feof() to check if the end of file stream has been reached.
Edit: (this may not be the most optimal solution but it checks if the bigger file contains the smaller file)
#include <stdio.h>
#include <stdlib.h>
int findFileInFile(const char *wherePath, const char *whatPath)
{
FILE *fpBigger = fopen(wherePath, "rb");
FILE *fpSmaller = fopen(whatPath, "rb");
unsigned char cs = 0;
unsigned char cb = 0;
int s;
int b;
int loc;
if (fpBigger != NULL && fpSmaller != NULL)
{
s = fgetc(fpSmaller);
cs=(unsigned char)s;
while((b=fgetc(fpBigger))!=EOF){ //checks for the first instance of the first character of the smaller file in the bigger file
cb=(unsigned char)b;
if(cs==cb){
loc=ftell(fpBigger)-1; //set loc to the position where the first character of the smaller file is found in the bigger file
break;
}
}
if(b==EOF){ //if the character is not found, return 0
return 0;
}
fseek(fpBigger,loc,SEEK_SET);
rewind(fpSmaller);
while((b=fgetc(fpBigger))!=EOF){
if((s=fgetc(fpSmaller))==EOF){ //check if the end of smaller file is reached, and return 1 if true
return 1;
}
cs=(unsigned char)s;
cb=(unsigned char)b;
if(cs!=cb){
rewind(fpSmaller); //if the characters gotten from both the files are not equal, go to the very beginning of smaller file
loc++; //increase the position to start the search from in the bigger file by 1
fseek(fpBigger,loc,SEEK_SET);
}
}
if(b==EOF&&fgetc(fpSmaller)==EOF){
return 1;
}
return 0;
}
else
{
printf("File names are wrong!\n");
exit(-1);
}
}
int main()
{
printf("%d", findFileInFile("file1.txt", "file2.txt"));
}
I'm having a problem with this program. I'm trying to send the pointer to the beginning of a file. It usually works but, when I send the file from one function to another, then fgets gets and empty string rather than the first row in the file.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int checkf(FILE *file, char*id){
char row[255];
int line_num = 1;
int find_result = 0;
char temp[255];
while (fgets(temp, 255, file) != NULL){ // here i get an Empty 'temp'
// so the contition is always false
if((strstr(temp, id)) != NULL) {
rewind(file);
for (int i=1; i<(line_num-1); i++) {
fgets(row, 255, file);
}
for (int i=0; i<4; i++) {
fgets(row, 255, file);
choppy(row);
printf("%s",row);
if (i!=3) {
printf(" ");
}
}
find_result++;
}
line_num++;
}
return find_result;
}
void add(FILE *file, char fileName[20]){
int check;
char name[100], id[100] ;
scanf("%s",name);
scanf("%s",id);
check = checkf(file,id);
if(check==0){
fputs("\n",file);
fputs(name,file);
}
}
int main(int argc, char * argv[]) {
// insert code here...
FILE *file;
FILE *file_app;
file_app= fopen(argv[argc-1], "a");
file= fopen(argv[argc-1],"r");
//check the there is a file
if (file== NULL)
{
printf("Can't open file");
return 1;
}
else
{
int cmd= strcmp(argv[1],"add");
if (cmd==0) add(file_app,argv[2]);
fclose(file);
printf("\n");
return 0;
}
}
So in conclusion, I think that when I the function checkf() is called from function add(), the file pointer gets lost. But, when I use checks() directly it works. Any ideas?
I am implementing a program to read filenames with room names, connections, and room types. Ex:
ROOM NAME: chicago
CONNECTION 1: sarasota
CONNECTION 2: columbus
CONNECTION 3: miami
CONNECTION 4: boston
ROOM TYPE: END_ROOM
The program is designed to show the user the room they are starting in, ask for input from the user, check to see if the input is the end room or another connection. If it is another connection, the prompt will display again. If the user reaches the end room, the game ends. However, I am required to implement a mutex that, if the user enters "time", a file is created, the time is written to it, and it is displayed on the screen. After that, prompt is displayed again for the user. My code works fine when the mutex implementation is stripped out. Here is what I am seeing when the mutex is in the code. I appear to reach the time function and the program seems to recognize incorrect rooms but when a "correct" room is entered the cursor just returns and does nothing. Any clue on why I am getting this behavior only on mutex implementation?
The program is below, do you see anything that would cause this issue?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
//Read in the room data
//Perform the stat() function on the rooms directory in the same directory
//and open the file with the most recent st_mtime component of the returned stat struct
#define NUM_USED_ROOMS 7
char usedRooms[NUM_USED_ROOMS][256];
char roomFilePath[75];
char timeFilePath[75];
char* connections[NUM_USED_ROOMS];
int end = 0;
char input[20];
int numberOfSteps = -1;
char *steps[75];
int file_descriptor;
char timeText[100];
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
void * getTime() {
pthread_mutex_lock(&myMutex);
printf("You asked for the time!\n");
pthread_mutex_unlock(&myMutex);
return NULL;
}
//Check if the room number passed is the end
void isEnd(int roomNumber, char *dirName){
//Counting the number of steps for the end of the program
numberOfSteps++;
steps[numberOfSteps - 1] = usedRooms[roomNumber];
//Getting the name of the proper file
sprintf(roomFilePath, "%s/%s", dirName, usedRooms[roomNumber]);
char substring[20];
int numLine = 1;
FILE * filePointer;
filePointer = fopen(roomFilePath, "r");
int lines = 0;
char buffer[256];
while(fgets(buffer, sizeof(buffer), filePointer) != NULL){
lines = lines + 1;
}
fclose(filePointer);
//Opening the file to read to see if it is the end. If it is, assign end = 1.
filePointer = fopen(roomFilePath, "r");
while(fgets(buffer, sizeof(buffer), filePointer) != NULL) {
if (numLine == lines)
{
strcpy(substring, buffer+11);
}
numLine = numLine + 1;
}
if(strstr(substring, "END" ) != NULL) {
end = 1;
}
}
//Get the user input
void getInput() {
fflush(stdin);
scanf("%s", input);
fflush(stdin);
fflush(stdout);
}
void readFile(char *dirName){
DIR *dir;
struct dirent *ent;
int i = 0;
if ((dir = opendir (dirName)) != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL) {
if (strncmp(ent->d_name,".",sizeof(ent->d_name)) == 0 ||
strncmp(ent->d_name,"..",sizeof(ent->d_name)) == 0 )
{
} else {
strcpy(usedRooms[i],ent->d_name);
i++;
}
}
closedir (dir);
} else {
/* could not open directory */
perror ("");
}
}
void playGame(int roomNumber, char * dirName){
int i;
printf("usedRooms is %s", usedRooms[roomNumber]);
pthread_mutex_lock(&myMutex);
pthread_t secondThread;
pthread_create(&secondThread, NULL, getTime,NULL);
//Check if the user guessed the end room
if(end == 1) {
fflush(stdout);
return;
}
else{
isEnd(roomNumber, dirName);
if (end == 1)
{
fflush(stdout);
return;
}
}
int move = 1;
while(move == 1) {
//Open the file of the path of the room passed in
sprintf(roomFilePath, "%s/%s", dirName, usedRooms[roomNumber]);
FILE * filePointer;
filePointer = fopen(roomFilePath, "r");
int fileLines = 0;
char line[256];
//Count the lines in the file so I know how to traverse it
while(fgets(line, sizeof line, filePointer) != NULL) {
fileLines = fileLines + 1;
}
fclose(filePointer);
filePointer = fopen(roomFilePath, "r");
int currentLine = 0;
//Create the array for the rooms that can be navigated to
char gameRooms[6][30];
while(fgets(line, sizeof line, filePointer) != NULL) {
char *pos;
if((pos = strchr(line, '\n')) != NULL)
{
*pos = '\0';
}
//Print out the current room
if (currentLine == 0)
{
char substring[20];
strcpy(substring, line+11);
printf("CURRENT LOCATION: %s\n", substring);
}
//Print the first connection from this room
else if (currentLine == 1){
printf("POSSIBLE CONNECTIONS: ");
fflush(stdout);
char substring[20];
strcpy(substring, line+14);
printf("%s", substring);
fflush(stdout);
strcpy(gameRooms[currentLine - 1], substring);
}
//Print the rest of the connections, comma separated
else if (currentLine > 1 && currentLine < fileLines - 1) {
printf(",");
fflush(stdout);
char substring[20];
strcpy(substring, line+14);
printf("%s", substring);
fflush(stdout);
strcpy(gameRooms[currentLine - 1], substring);
//gameRooms[currentLine - 1] = substring;
}
else {
printf(".");
fflush(stdout);
}
currentLine = currentLine + 1;
}
fclose(filePointer);
printf("\nWHERE TO?>");
//Get the user input
getInput();
if(strcmp("time", input) == 0){
pthread_mutex_unlock(&myMutex);
pthread_join(secondThread, NULL);
pthread_mutex_lock(&myMutex);
pthread_create(&secondThread, NULL, getTime, NULL);
}
//Loop through the file to see if the input matches a room name in the array
for(i = 0; i < fileLines - 2; i++) {
if (strcmp(gameRooms[i], input) == 0)
{
int j;
for(j = 0; j < NUM_USED_ROOMS; j++) {
//If there is a match, play the game starting at the room entered
if(strcmp(usedRooms[j], input) == 0) {
printf("THE STRINGS MATCH usedRooms is %s "
"and input is %s\n",usedRooms[j],input);
playGame(j,dirName);
}
}
move = 0;
}
}
//If the user's input didn't match the list of rooms
if (move == 1) {
printf("\nHUH? I DON'T UNDERSTAND THAT ROOM. TRY AGAIN. \n\n");
fflush(stdout);
fflush(stdin);
}
}
}
int main() {
int newestDirTime = -1; // Modified timestamp of newest subdir examined
char targetDirPrefix[32] = "walterer.rooms."; // Prefix we're looking for
char newestDirName[256]; // Holds the name of the newest dir that contains prefix
memset(newestDirName, '\0', sizeof(newestDirName));
DIR* dirToCheck; // Holds the directory we're starting in
struct dirent *fileInDir; // Holds the current subdir of the starting dir
struct stat dirAttributes; // Holds information we've gained about subdir
dirToCheck = opendir("."); // Open up the directory this program was run in
if (dirToCheck > 0) // Make sure the current directory could be opened
{
while ((fileInDir = readdir(dirToCheck)) != NULL) // Check each entry in dir
{
if (strstr(fileInDir->d_name, targetDirPrefix) != NULL) // If entry has prefix
{
//printf("Found the prefex: %s\n", fileInDir->d_name);
stat(fileInDir->d_name, &dirAttributes); // Get attributes of the entry
if ((int)dirAttributes.st_mtime > newestDirTime) // If this time is bigger
{
newestDirTime = (int)dirAttributes.st_mtime;
memset(newestDirName, '\0', sizeof(newestDirName));
strcpy(newestDirName, fileInDir->d_name);
}
}
}
}
closedir(dirToCheck);
//Read the file at the specified directory
readFile(newestDirName);
int start;
int i;
for (i = 0; i < NUM_USED_ROOMS; i++)
{
memset(roomFilePath, '\0', sizeof(roomFilePath));
sprintf(roomFilePath,"%s/%s", newestDirName, usedRooms[i]);
char output[256];
memset(output, '\0', sizeof(output));
char* token;
char* connectRoom;
FILE *filePointer;
filePointer = fopen(roomFilePath,"r");
//Find the starting room and pass that into the playGame function
if (filePointer == NULL)
{
printf("Unable to open file!\n");
} else {
while(!feof(filePointer)) {
fgets(output, 256, filePointer);
token = strtok(output, "\n");
if(strstr(token, "START") != NULL){
start = i;
}
}
fclose(filePointer);
}
}
//Play the game with the starting room at the directory name
playGame(start, newestDirName);
printf("YOU HAVE FOUND THE END ROOM. CONGRATULATIONS!\n");
printf("YOU TOOK %d STEPS. YOUR PATH TO VICTORY WAS: \n", numberOfSteps);
for(i = 0; i < numberOfSteps; i++){
printf("%s\n", steps[i]);
}
return 0;
}
As a rule, you should lock a mutex for the shortest time possible. Violation of this rule is a severe anti-pattern called "asking for trouble" which is usually punished with deadlocks. Remove that anti-pattern from your code.
I must modify my program to accept input from
a file called anagrams.txt.This file should have two strings per line, separated by the # character. My program should read
each pair of strings and report back if each pair of strings is an anagram. For example consider the following content of anagrams.txt:
hello#elloh
man#nam
Astro#Oastrrasd
Your program should print out the following:
hello#elloh - Anagrams!
man#nam - Anagrams!
Astro#Oastrrasd- Not anagrams!
I should compile in g++
Here is the code to read from text:
int main()
{
char input[30];
if(access( "anagrams.txt", F_OK ) != -1) {
FILE *ptr_file;
char buf[1000];
ptr_file =fopen("anagrams.txt","r"); if (!ptr_file)
return 1;
while (fgets(buf,1000, ptr_file)!=NULL)
printf("%s",buf);
fclose(ptr_file);
printf("\n");
}
else{ //if file does not exist
printf("\nFile not found!\n");
}
return 0;
}
Code to find if the text are anagrams:
#include <stdio.h>
int find_anagram(char [], char []);
int main()
{
char array1[100], array2[100];
int flag;
printf("Enter the string\n");
gets(array1);
printf("Enter another string\n");
gets(array2);
flag = find_anagram(array1, array2);
if (flag == 1)
printf(" %s and %s are anagrams.\n", array1, array2);
else
printf("%s and %s are not anagrams.\n", array1, array2);
return 0;
}
int find_anagram(char array1[], char array2[])
{
int num1[26] = {0}, num2[26] = {0}, i = 0;
while (array1[i] != '\0')
{
num1[array1[i] - 'a']++;
i++;
}
i = 0;
while (array2[i] != '\0')
{
num2[array2[i] -'a']++;
i++;
}
for (i = 0; i < 26; i++)
{
if (num1[i] != num2[i])
return 0;
}
return 1;
}
You can try something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXLINE 1000
#define MAXLETTER 256
int is_anagram(char *word1, char *word2);
void check_lines(FILE *filename);
int cmpfunc(const void *a, const void *b);
void convert_to_lowercase(char *word);
int
main(int argc, char const *argv[]) {
FILE *filename;
if ((filename = fopen("anagram.txt", "r")) == NULL) {
fprintf(stderr, "Error opening file\n");
exit(EXIT_FAILURE);
}
check_lines(filename);
fclose(filename);
return 0;
}
void
check_lines(FILE *filename) {
char line[MAXLINE];
char *word1, *word2, *copy1, *copy2;
while (fgets(line, MAXLINE, filename) != NULL) {
word1 = strtok(line, "#");
word2 = strtok(NULL, "\n");
copy1 = strdup(word1);
copy2 = strdup(word2);
convert_to_lowercase(copy1);
convert_to_lowercase(copy2);
if (is_anagram(copy1, copy2)) {
printf("%s#%s - Anagrams!\n", word1, word2);
} else {
printf("%s#%s - Not Anagrams!\n", word1, word2);
}
}
}
void
convert_to_lowercase(char *word) {
int i;
for (i = 0; word[i] != '\0'; i++) {
word[i] = tolower(word[i]);
}
}
int
is_anagram(char *word1, char *word2) {
qsort(word1, strlen(word1), sizeof(*word1), cmpfunc);
qsort(word2, strlen(word2), sizeof(*word2), cmpfunc);
if (strcmp(word1, word2) == 0) {
return 1;
}
return 0;
}
int
cmpfunc(const void *a, const void *b) {
if ((*(char*)a) < (*(char*)b)) {
return -1;
}
if ((*(char*)a) > (*(char*)b)) {
return +1;
}
return 0;
}
Since this looks like a University question, I won't provide a full solution, only a hint.
All you have to do is replace the stdin input part of the anagram-finding file with the code you wrote to read from a file: it's as simple as changing
printf("Enter the string\n");
gets(array1);
printf("Enter another string\n");
gets(array2);
to
// before program:
#define SIZE 1000
// inside main
if (access("anagrams.txt", F_OK) == -1){
printf("\nFile not found!\n");
return 1; // Abort the program early if we can't find the file
}
FILE *ptr_file;
char buf[1000];
ptr_file = fopen("anagrams.txt","r");
if (!ptr_file)
return 1;
char array1[SIZE], array2[SIZE];
while (fgets(buf, 1000, ptr_file)!=NULL){
// do all your anagram stuff here!
// there is currently one line of the input file stored in buf
// Hint: You need to split buf into array_1 and array_2 using '#' to separate it.
}
fclose(ptr_file);
printf("\n");
Additional comments:
Don't ever ever ever use gets. gets doesn't check that the string it writes to can hold the data, which will cause your program to crash if it gets input bigger than the array size. Use fgets(buf, BUF_SIZE, stdin) instead.
Beautiful code is good code. People are more likely to help if they can read your code easily. (fix your brackets)
Just for interest, a more efficient algorithm for checking anagrams is to use qsort to sort both arrays, then a simple string matcher to compare them. This will have cost O(mnlog(m+n)), as opposed to O(m^2 n^2), awith the current algorithm
You need to split every line you read by fgets (as you did) in to two strings, and pass them to your find_anagram function. You can do that using strtok:
int main()
{
int flag;
char buf[1000];
FILE *ptr_file;
//Check file existence
//Open the file for reading
while (fgets (buf, 1000, ptr_file) != NULL)
{
char *array1 = strtok(buf, "#");
char *array2 = strtok(NULL, "\n");
flag = find_anagram (array1, array2);
//Check flag value to print your message
}
return 0;
}
//put your find_anagram function
Don't forget to #include <string.h> to use strtok().
Everytime I try to run the code it'll print out the contents of the file, however it will print out a garbage value at the end which I don't know how to get rid of. I am supposed to to store the contents of the file into an array, however I am a bit confused on how to do that???
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char filePrinter(char*arr)
int main (int argc, char**argv)
{
char fileArray[150];
if(argc !=2)
{
printf("Invalid Entry. Please Enter name of program followed by input filename\n");
}
filePrinter(fileArray);
return 0;
}
char filePrinter(char*arr)
{
int i;
FILE*file;
i=0;
file=fopen("assests/room.txt","r");
if(file == NULL)
{
printf("Could not open file\n");
exit(-1);
}
else
{
while(0 ==feof(file))
{
i=fgetc(file);
printf("%c", i);
}
}
fclose(file);
return i;
}
file content:
10x16 ds5 h6,5 g7,8 p3,3
10X16 de4 h5,7 g9,2
10X16 dw6,h2,3 m6,7
10X16 dn3,h2,4 p2,3
10X16 de2 h9,9 m4,5
10X16 dn8 h4,5 g1,1*/
feof returns true if the last call to a read operation hit EOF. You'd want to test it after the fgetc call. Or, even better, just check whether fgetc returned the special value EOF.
(A FILE * has an "end-of-file marker" that says whether some read operation has hit EOF. Read operations set the "end-of-file marker" upon hitting EOF. Before you've hit---meaning tried to read past---the end of the file, that "end-of-file marker" is clear.)
Timing is bad than look at the beginning of the loop by feof because EOF occur in fgetc.
replace to
while(EOF!=(i=fgetc(file))){
printf("%c", i);
}
int filePrinter(char*arr){
int i = 0, ch;
FILE*file;
file=fopen("assests/room.txt","r");
if(file == NULL) {
printf("Could not open file\n");
exit(-1);
} else {
while(EOF!=(ch=fgetc(file))) {
//printf("%c", ch);
arr[i] = ch; //*arr++ = ch;
++i;//i : range check
}
arr[i] = '\0';
}
fclose(file);
return i;
}
I think the code should be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void filePrinter(char*arr);
int main (int argc, char**argv)
{
char fileArray[150];
memset(fileArray, 0, sizeof(fileArray));
if(argc !=2)
{
printf("Invalid Entry. Please Enter name of program followed by input filename\n");
}
filePrinter(fileArray);
return 0;
}
void filePrinter(char *arr)
{
int c = 0, j = 0;
FILE* file = NULL;
file=fopen("assests/room.txt","r");
if(file == NULL)
{
printf("Could not open file\n");
exit(-1);
}
else
{
while (1)
{
c = fgetc(file);
if (c != EOF)
{
arr[j++] = c;
}
else
{
break;
}
}
}
fclose(file);
return;
}