I'm writing a program that allows multiple users to create, save, and load data to files. I'm running into an issue where I can't find seem to figure out a logic that doesn't allow users to create duplicate file names.
Here is the important working part of my code thus far, but where my issues are. The variable user is assigned at the launch of my program where the user must enter their username and password.
else if (selection == 6)
{
int i;
int d;
printf("Please enter a file name: ");
scanf("%s", filename);
newFile = fopen(filename, "a+");
Record = fopen("records.txt", "a+");
fprintf(Record, "%s %s\n", user, filename);
for (i = 0; i < icount; i++)
{
fprintf(newFile, "%d ", ints[i]);
}
for (d = 0; d < dcount; d++)
{
fprintf(newFile, "%lf ", doubles[d]);
}
fclose(Record);
fclose(newFile);
}
else if (selection == 7)
{
printf("Please enter a file name: ");
scanf("%s", filename);
Record = fopen("records.txt", "a+");
while (fscanf(Record, "%s %s", curuser, curfile) != EOF)
{
if (strcmp(user, curuser) == 0 && strcmp(filename, curfile) == 0)
{
int c;
//fopen(newFile, "a+");
newFile = fopen(filename, "a+");
if (newFile) {
while ((c = getc(newFile)) != EOF)
{
putchar(c);
}
fclose(newFile);
break;
}
}
else
{
printf("You don't have access to this file.\n");
break;
}
}
}
Somewhere in selection 6, I'm trying to say in code, "Okay user, enter a file, unless the name already exists." What I tried was
while (fscanf(Record, "%s %s", curuser, curfile) != EOF)
{
if (strcmp(curfile, filename) == 0)
{
break;
}
else
{
fprintf(Record, "%s %s\n", user, filename);
fclose(Record);
}
}
and I'm unable to figure out why this won't work. I tried placing this code right below Record file declaration.
I think the issue may be that when the record file is empty, the != EOF line is causing it to break, but I also can't figure out a way to initially get one user and filename in the record before probing the rest of the users for their filenames. Any guidance in the right direction would be appreciated!
I think you can solve your problem by cutting the while loop in several parts:
do the fscanf
check for end of file
check for "user found"
And finally,
write user if not previously in file.
I would have written something like:
int record_found = 0;
int scanf_res;
while (1)
{
/* do the fscanf */
scanf_res = fscanf(Record, "%s %s", curuser, curfile);
/* test for end of file */
if (EOF == scanf_res)
{
/* end of file reached */
break;
}
/* if fscanf has mado 2 conversion AND
filename is curfile */
if ((2 == scanf_res) && (strcmp(curfile, filename) == 0))
{
record_found = 1;
break;
}
}
if (!record_found)
{
/* add user if needed */
fprintf(Record, "%s %s\n", user, filename);
}
/* and close file in all cases */
fclose(Record);
Related
I can't get my delete record function to break out of the switch case or even give me an error when the record doesn't exist. Could someone please tell me why this is?
Any help is much appreciated!
I can't get my delete record function to break out of the switch case or even give me an error when the record doesn't exist. Could someone please tell me why this is?
Any help is much appreciated!
void delete_record();
void displayContent();
struct Update
{
char studentName[50];
char studentID [50];
char emailID[100];
char courseID[5];
char grade[50];
} update2;
int main ()
{
int num;
do
{
printf("1. Delete a record for the specific name\n");
printf("2. Display Content of File\n");
printf("6. Exit\n");
switch(num)
{
case 1:
printf("this is a test\n");
delete_record();
break;
//displayContent();
//printf("this is a test 2\n");
case 2:
printf("\n\nDiplaying Contents of File\n\n");
displayContent();
default:
printf("Give me a break!\n");
break;
}
scanf("%d", &num);
} while (num != 6);
return 0;
}
void delete_record()
{
FILE *fp;
FILE *fp_tmp;
fp = fopen ("BINARY_FILE.txt", "w");
char studentsID[20];
printf("enter studentID to delete:");
scanf("%s",studentsID);
printf("is this a test?\n");
while(fread(&update2,sizeof(update2),1,fp))
{
printf("this is another test\n");
if(strcmp(update2.studentID,studentsID) != 0)
{
//printf("testing\n");
fwrite(&update2,sizeof(update2),1,fp);
}
else
{
printf("No student with that student ID\n");
}
}
printf("more tests\n");
fclose(fp);
return;
}
void displayContent()
{
char c;
// Open file
FILE *fp;
fp = fopen ("BINARY_FILE.txt", "r");
if (fp == NULL)
{
printf("File Has No Content\n");
exit(0);
}
// Read contents from file
c = fgetc(fp);
while (c != EOF)
{
printf ("%c", c);
c = fgetc(fp);
}
fclose(fp);
//return 0;
}
When using scanf to read from the keyboard you must remember
that all characters that you enter are written to the in-buffer,
this means that if you type in
42ENTER
The ENTER will also be present in the in-buffer, so next time you call scanf ENTER will still be in the buffer and then scanf returns 0 since the format specificier "%d" doesn't match.
The easiest way to handle input from keyboard in C and to avoid the hassle of scanf in-buffer by using fgets() to read from the keyboard, then use sscanf() to cherry pick from the buffer:
// always check return value from all runtime functions when possible
char buffer[128];
if (fgets(buffer,sizeof(buffer), stdin) != NULL)
{
if (sscanf(buffer, "%d", &num) == 1)
{
}
else {...}
}
else {...}
I'm new to programming in c and I've come across a problem with my file system. The aim of this program is for a user to enter a message and that message gets stored in a text file. After the users message gets stored in a text file, they have the choice to 'read' a messaged their loved one has sent to them.
char SingleLine[150];
FILE * filePointer;
FILE * fpointer;
char mess[10];
char reply[100];
case 4:
printf("enter a message: ");
fscanf(stdin, "%s", mess);
filePointer = fopen("gift.txt", "w");
fprintf(filePointer, "%s \n", mess);
printf("you said %s \n", mess);
printf("they wrote something back?, would you like to read it? yes or no? \n ");
scanf("%s", &reply);
if ((toupper(reply[0]) == 'Y') && (toupper(reply[1]) == 'E') && (toupper(reply[2]) == 'S'))
{
printf("you said %s is that true???", &reply);
printf("ok loading...\n");
fpointer = fopen("luvtracey.txt", "r");
while (!feof(fpointer))
fgets(SingleLine, 150, fpointer);
puts(SingleLine);
}
else if ((toupper(reply[0]) == 'N') && (toupper(reply[1]) == 'O'))
{
printf("wow ignorant \n");
}
else
{
printf("your not having it anymore");
}
}
But when this code runs firstly, when a user enters a message with no spaces, it'll get stored. But when you add spaces, the message would get chopped in half and the first bit would get stored. Secondly, when you type 'yes' (when you want to see what your loved one has sent) it crashes completely but i don't understand why. Also its not retrieving the information in the 'luvtracey.txt' file which has words in it.
I accept feedback and i just want to say thank you to those in advance who help me solve these problems.
~Neamus
if ((toupper(reply[0]) == 'Y') && (toupper(reply[1]) == 'E') ...
You can convert the string to lowercase or uppercase and strcmp, rather than checking letters one by one.
while (!feof(fpointer))
fgets(SingleLine, 150, fpointer);
puts(SingleLine);
Don't use feof. Instead check if fgets succeeds. Presumably you want to print each line in the file, so don't print the line after the loop finishes. You also need error checks to make sure the file was opened successfully. Example:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
char buffer[150];
printf("enter a message: ");
fscanf(stdin, "%s", buffer);
printf("you said %s \n", buffer);
FILE *fp = fopen("gift.txt", "w");
fprintf(fp, "%s \n", buffer);
fclose(fp);
printf("yes or no? ");
scanf("%s", buffer);
for(int i = 0, len = strlen(buffer); i < len; i++)
buffer[i] = (char)tolower(buffer[i]);
if (strcmp(buffer, "yes") == 0)
{
fp = fopen("luvtracey.txt", "r");
if(!fp)
{
printf("can't open...\n");
}
else
{
while(fgets(buffer, sizeof(buffer), fp))
printf("%s", buffer);
fclose(fp);
}
}
return 0;
}
I am reading from a file, however if it doesn't exist is meant to print 'Read error' but for some reason it is printing read error twice and I don't know why
int loadFlights(char flightDatabase[50], int totalflights, flight_t f[MAX_NUM_FLIGHTS])
{
int counter;
FILE *fp;
fp = fopen("database.txt", "r");
if(fp == NULL) { /************************statement with problem*/
printf("Read error\n");
return 1;
}
fscanf(fp, "%d", &totalflights);
if (totalflights > 5) {
totalflights = 5;
}
for(counter = 0; counter <= totalflights-1; counter++)
{
fscanf(fp, "%s %d %d %d %d %s %d %d %d %d", f[counter].flightcode,
&f[counter].departure_dt.month, &f[counter].departure_dt.date,
&f[counter].departure_dt.hour, &f[counter].departure_dt.minute,
f[counter].arrival_citycode, &f[counter].arrival_dt.month,
&f[counter].arrival_dt.date, &f[counter].arrival_dt.hour,
&f[counter].arrival_dt.minute);
}
fclose(fp);
return totalflights;
}
I've tried putting an if statement around the Read Error if statement saying if its already been printed don't print again however it still seems to be printing.
int main(void)
{
flight_t f[MAX_NUM_FLIGHTS];
int totalflights = 0, menu;
char flightDatabase[50] = "database.txt";
while (menu != 5)
{
print_Menu();
scanf("%d", &menu);
while ((menu < 0) || (menu > 5)) {
printf("Invalid choice\n");
print_Menu();
scanf("%d", &menu);
}
if (menu == 1)
{
addFlight(f, totalflights);
totalflights++;
}
else if (menu == 2)
{
displayFlight(f, totalflights);
}
else if (menu == 3)
{
saveFlight(f, flightDatabase, totalflights);
}
else if (menu == 4)
{
loadFlights(flightDatabase, totalflights, f);
totalflights = loadFlights(flightDatabase, totalflights,f);
}
}
return 0;
}
This is the code where I call on the function.
This is where the problem is:
// Some code
else if (menu == 4)
{
loadFlights(flightDatabase, totalflights, f);
totalflights = loadFlights(flightDatabase, totalflights,f);
}
These are two consecutive calls to loadFlights while the first call doesn't catch the return value. You can get rid of the first one and it should behave the way you expect it to.
Additionally, I see a problem:
while (menu != 5)
At this point, menu is uninitialised, will hold a random value. You might want to either initialise it to zero or 5 or whatever is legal for that data type.
I've tried putting an if statement around the Read Error...
These are the patch works, that are really dangerous to have. Its usually expected to debug the code and find out whats the exact problem rather than adding a patch to cover up an existing bug.
The following function creates a new text file and allows the user to input text to be saved to the file. The main issues that I'm having troubles fixing is 1)allowing spaces between words 2)hitting enter saves the text, instead of going to a new line.
void new_file(void)
{
char c[10000];
char file[10000];
int words;
printf("Enter the name of the file\n");
scanf("%123s",file);
strcat(file,".txt");
FILE * pf;
pf = fopen(file, "w" );
if (!pf)
fprintf( stderr, "I couldn't open the file.\n" );
else
{
printf("Enter text to be saved\n");
scanf("%s", c);
fprintf(pf, "%s", c);
}
fclose(pf); // close file
printf("\n\nReturning to main menu...\n\n");
}
Use fgets() instead of scanf() to get the input text from the user.
To do so replace this line
scanf("%s", c);
with the following code:
if (NULL != fgets(c, sizeof(c), stdin))
{
fprintf(pf, "%s", c);
}
else
{
if (0 != ferror(stdin))
{
fprintf(stderr, "An error occured while reading from stdin\n");
}
else
{
fprintf(stderr, "EOF was reached while trying to read from stdin\n");
}
}
To allow the user to read in more then one line put a loop around the code above. Doing so you need to define a condition which tells the program to stop looping:
The following example stops reading in lines when entering a single dot "." and pressing return:
do
{
if (NULL != fgets(c, sizeof(c), stdin))
{
if (0 == strcmp(c, ".\n")) /* Might be necessary to use ".\r\n" if on windows. */
{
break;
}
fprintf(pf, "%s", c);
}
else
{
if (0 != ferror(stdin))
{
fprintf(stderr, "An error occured while reading from stdin\n");
}
else
{
fprintf(stderr, "EOF was reached while trying to read from stdin\n");
}
break;
}
} while (1);
I am working on a program to write user input to a file and then search for a specific record in the file and output it to the screen.
I tried using fgets and also fputs, but I haven't been successful. Here's what I have so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main ()
{
FILE *fileptr;
char id [30];
char name [47];
char amt[50];
fileptr = fopen("C:\\Users\\Andrea\\Documents\\Tester.txt", "w");
if (fileptr == NULL) {
printf("File couldn't be opened\n\a\a");
fclose(fileptr);
exit(0);
}
printf("Enter name: \n");
fscanf(fileptr, "%c", name);
fputs(name, fileptr);
fclose(fileptr);
printf("File write was successful\n");
return 0;
}
Use:
fscanf(stdin, "%s", name);
But better still, use scanf instead, as kol mentioned. This is because scanf() is designed to read the user response from the screen while fscanf() is for scanning from any input streams (which are usually files).
And the statement should be reading from the screen (stdin), not from the file (which was opened as "write" only).
Use scanf to read user input, and fprintf to write it to the file. Then use fscanf to read from the file, and printf to display what you have read. See cplusplus.com for the details and sample code.
EDIT:
Here is an example (please run the executable from the command line):
#include <stdio.h>
#include <string.h>
int main()
{
FILE *file;
int i;
char firstName[32];
char lastName[32];
int found = 0;
// Open the file for writing
file = fopen("records.txt", "wt");
if (!file)
{
printf("File could not be opened\n\a\a");
getchar();
return -1;
}
// Read and save data
for (i = 0; i < 3; ++i)
{
// Read data
printf("Record #%d\n", i + 1);
printf("Enter first name: "); scanf("%s", firstName);
printf("Enter last name: "); scanf("%s", lastName);
printf("\n");
// Save data
fprintf(file, "%s\t%s\n", firstName, lastName);
}
// Close the file
fclose(file);
// Open the file for reading
file = fopen("records.txt", "rt");
if (!file)
{
printf("File could not be opened\n\a\a");
return -1;
}
// Load and display data
i = 0;
while(!feof(file) && !found)
{
++i;
fscanf(file, "%s\t%s", firstName, lastName);
if (strcmp(firstName, "John") == 0 && strcmp(lastName, "Doe") == 0)
{
printf("Record found (#%d): %s %s\n", i, firstName, lastName);
found = 1;
}
}
if (!found)
printf("Record could not be found");
// Close the file
fclose(file);
return 0;
}