How to open a file with a user inputted variable in C? - c

I'm writing a POS program as a school assignment. I'm using multiple txt files as a database. The program is suppose to allow the user to enter a SKU number (e.g. 123) then it will open a txt file in a database (e.g. database/123.txt). It then pull info from the txt file such as a price and allow the user to add multiple files and end with a total. The user can also add to the database by creating new SKUs. They are also able to view transaction history. The issue I am having is I can't seem to figure out how to record a number from a user and then use that number to open a text file beginning with that number. (e.g. use enters 123 then 123.txt is opened.)
Here is the section of my code that I need help with:
// Function to start a transaction
int transaction(void)
{
// Define Variables
char buf[1000], nDatabase[100];
float nPrice[500], nTotal;
// Instructions
printf("You have started a transaction.\n");
printf("Enter the SKU number below.\n");
printf("Enter 0 to complete the transaction.\n");
// Begin loop here
do
{
FILE *ptr_file;
// record SKU number
/*remove test tools later*/
printf("we r here\n");
scanf("Enter the SKU: %c\n", &nDatabase);
printf("now we r here\n");
// Open database file
/*Change location later*/
ptr_file = fopen("database/123.txt", "r");
// If file is not found return 1
if (!ptr_file)
{
printf("Could not match that SKU number.\n");
return 1;
}
while (fgets(buf, 1000, ptr_file) != NULL)
printf("%s\n", buf);
scanf("%s", &nPrice[0]);
// Close file
fclose(ptr_file);
while (nDatabase == 0);
nTotal = nPrice[0] + nPrice[1];
printf("Your total is: $%.2f\n", &nTotal);
return 0;
}
}

printf( "Enter the SKU: " ) ; // <-- scanf if only for input, the prompt must be output separately
scanf( "%s\n", nDatabase);
// ^ ^
// | |_No & here - nDatabase is an array
// |
// |_Accept a string not a character
Then you might form a complete file name with sprintf, e.g.
char filename[MAX_FNAME] ;
sprintf( filename, "database/%s,txt", nDatabase ) ;
Be aware that no error checking or overrun protection is performed by the above - you may want to consider adding some.

You need to concatenate the user input with you database path, and extension.
Check this post: C string append

Related

C Program to count keywords from a keyword text file in a fake resume and display the result

#EDIT: I think the problem is that I put my 2 text files on desktop. Then, I move them to the same place as the source file and it works. But the program cannot run this time, the line:
cok = 0;
shows "exception thrown".
// end EDIT
I have the assignment at school to write a C program to create 2 text files. 1 file stores 25 keywords, and 1 file stores the fake resume. The problem is, my program cannot read my keywords.txt file. Anyone can help me? Thank you so much.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//*****************************************************
// MAIN FUNCTION
int main()
{
//File pointer for resume.txt file declared
FILE *fpR;
//File pointer for keywords.txt file declared and open it in read mode
FILE* fpK = fopen("keywords.txt", "r");
//To store character extracted from keyword.txt file
char cK;
//To store character extracted from resume.txt file
char cR;
//To store word extracted from keyword.txt file
char wordK[50];
//To store word extracted from resume.txt file
char wordR[50];
//To store the keywords
char keywords[10][50];
//To store the keywords counter and initializes it to zero
int keywordsCount[10] = { 0, 0, 0, 0 };
int coK, coR, r, r1;
coK = coR = r = r1 = 0;
//Checks if file is unable to open then display error message
if (fpK == NULL)
{
printf("Could not open files");
exit(0);
}//End of if
//Extracts a character from keyword.txt file and stores it in cK variable and Loops till end of file
while ((cK = fgetc(fpK)) != EOF)
{
//Checks if the character is comma
if (cK != ',')
{
//Store the character in wordK coK index position
wordK[coK] = cK;
//Increase the counter coK by one
coK++;
}//End of if
//If it is comma
else
{
//Stores null character
wordK[coK] = '\0';
//Copies the wordK to the keywords r index position and increase the counter r by one
strcpy(keywords[r++], wordK);
//Re initializes the counter to zero for next word
coK = 0;
fpR = fopen("resume.txt", "r");
//Extracts a character from resume.txt file and stores it in cR variable and Loops till end of file
while ((cR = fgetc(fpR)) != EOF)
{
//Checks if the character is space
if (cR != ' ')
{
//Store the character in wordR coR index position
wordR[coR] = cR;
//Increase the counter coR by one
coR++;
}//End of if
else
{
//Stores null character
wordR[coR] = '\0';
//Re initializes the counter to zero for next word
coR = 0;
//Compares word generated from keyword.txt file and word generated from resume.txt file
if (strcmp(wordK, wordR) == 0)
{
//If both the words are same then increase the keywordCounter arrays r1 index position value by one
keywordsCount[r1] += 1;
}//End of if
}//End of else
}//End of inner while loop
//Increase the counter by one
r1++;
//Close the file for resume
fclose(fpR);
}//End of else
}//End of outer while loop
//Close the file for keyword
fclose(fpK);
//Display the result
printf("\n Result \n");
for (r = 0; r < r1; r++)
printf("\n Keyword: %s %d time available", keywords[r], keywordsCount[r]);
}//End of main
I think the problem is the text files, aren't they?
The name of my 1st test file is "keywords.txt", and its content is:
Java, CSS, HTML, XHTML, MySQL, College, University, Design, Development, Security, Skills, Tools, C, Programming, Linux, Scripting, Network, Windows, NT
The name of my 2nd test file is "resume.txt", and its content is:
Junior Web developer able to build a Web presence from the ground up -- from concept, navigation, layout, and programming to UX and SEO. Skilled at writing well-designed, testable, and efficient code using current best practices in Web development. Fast learner, hard worker, and team player who is proficient in an array of scripting languages and multimedia Web tools. (Something like this).
I don't see any problem with these 2 files. But my program still cannot open the file and the output keeps showing "Could not open files".
while ((cK = fgetc(fpK)) != EOF)
If you check the documentation, you can see that fgets returns an int. But since cK is a char, you force a conversion to char, which can change its value. You then compare the possibly changed value to EOF, which is not correct. You need to compare the value that fgets returns to EOF since fgetc returns an EOF on end of file.

Display record function to display Non-empty records not displaying records

Setting up a database which takes the input from a user(First name, last name, ID number , etc..) and inputs the information into a binary file, to update information , delete records, and update any information provided. All other functions seem to be functioning properly(Dont mind the bad code, im fairly new to programming) besides the function to display the non empty records. the information seems to be getting saved into the files because the other functions have access to it(all the same file pointer). I've checked to see if the file was being overwritten by the initialization of the empty file and that hasn't been the case to my understanding.
I've checked to see if the file was being overwritten by the initialization of the empty file and that hasn't been the case to my understanding. I've also tried updating the the if statement in the DisplayRecord function so that it would read all files and display only the ones that have an established ID number but it still shows null when the function is ran.
// fopen opens the file; exits if file cannot be opened
if ((cPtr = fopen("patient.dat", "rb")) == NULL) {
puts("File could not be opened.");
}//end If
else {
printf( "Patient ID\t Last Name\t first name\t DOB \tGender\t Doctor ID\t
Doctor last name\t Room Number\n" );
struct PatientData {
unsigned int Pat_ID; //ID number
char F_Name[25];//first name
char L_Name[25]; //last name
char Phone_num[20] ; //Phone number
char gender[2];
unsigned int doctor_ID;
char doc_LN[25];
unsigned int room_num;
char DoB[10];
};
//read all records until eof
while(!feof(cPtr)){
//create blank set to compare to data on file
struct PatientData Patient= { 0, "","","","",0,"", 0,"" };
int result=fread(&Patient,sizeof(struct PatientData), 1 , cPtr);
if(result!=0 && Patient.Pat_ID!=0){
printf("%-d%-15s%-15s%-10s%-12s%-15d%-15s%-10d\n",
Patient.Pat_ID,
Patient.L_Name,Patient.F_Name,Patient.DoB,Patient.gender,
Patient.doctor_ID, Patient.doc_LN,Patient.room_num);
}
fclose(cPtr); // fclose closes the file
Its suppose to display all records that have information in it. but the actual output is not showing any records.

C - fgets and fputs not editing file data

Full code: https://pastebin.com/NpspcJB8
I'm not sure if I'm using fgets() and fputs() correctly, but I need this or something similar in order to edit my file for the program. Within my program, I will have created a file, but when I generate the file contents in my program, I get this:
File output
Space: D44 Customer Name: empty Registration number: empty
Space: D45 Customer Name: empty Registration number: empty
Space: D46 Customer Name: empty Registration number: empty
Space: D47 Customer Name: empty Registration number: empty
Space: D48 Customer Name: empty Registration number: empty
Space: D49 Customer Name: empty Registration number: empty
Space: D50 Customer Name: empty Registration number: empty
empty
empty
empty
empty
empty
empty
empty
This happens when I add parking spaces in the program, and I believe that this merely shifts the array values. I need empty in the file output removed, which I attempted in a code using the functions I first mentioned, within a function I created:
int CheckExtraInput() {
fptr=fopen("parking_spaces.txt", "r+");
if (fptr==NULL) {
printf("Error! File does not exist");
return 1;
}
char extraInput[] = " empty\n";
// http://www.cplusplus.com/reference/cstdio/fgets/
// https://www.tutorialspoint.com/c_standard_library/c_function_strchr.htm
// char *s = strchr(extraInput, '\n');
// if(s) *s = '\0';
// fseek(fptr, 7, SEEK_SET);
while (fgets(extraInput, 8, fptr) != NULL) {
fputs(" aaa ", fptr);
}
}
I used " aaa " to test this code, to which it does not. I believe that I could use more in order to get this to work, but I'm not sure what; I used fseek() earlier on with similar results.
I just need to find out a way for the program to go to the end of the file, and if it starts to detect empty, it needs to remove it to save storage space.

What can be used to replace the if statement in this bit of code written in C?

The following is my attempt to scan a file to search and see if an entered username is taken already. The code doesn't work because of the if statement.
for (x = 0; x < 100; x++) {
/* for loop allows the user to keep entering usernames until they come up with an unused username. */
FILE *userlist; /*The userlist file holds all the taken usernames */
userlist = fopen("userlist.txt", "r");
fseek(userlist, x, SEEK_SET); /* This starts the search at the place x, which is incremented each time. */
fscanf(userlist, " %s", &username_ext); /* This scans the file contents after x and stores it in the username_ext variable */
if (strcmp(username, username_ext) == 0) { /* If the username entered and the strings after the x are the same, the loop terminates. */
printf("\nThe username is already taken.");
break;
}
fclose(userlist);
}
The code will never work, especially if each entry in the file is of variable length.
Instead you should open the file before the loop, skip the seeking (which will almost never work in a text file, and especially not the way you show it being used). Then you can read a string (using either fgets or fscanf) and compare to the username given.
Something like the following pseudo-ish code:
file = open_file()
while (fscanf("%s", username_ext) == 1)
{
if (strcmp(username, username_ext) == 0)
{
// Username found
}
}
To explain why the code, as shown in the question, will never work, the fseek call will set the position to the offset x in the file from the start. And that offset is in bytes, not in "records" or "elements".
And if the input file is a text file where each record is of different length, there is simply no way of seeking to a specific record without knowing its position beforehand.

Editing a line in a text file using temp file C

I am trying to edit a line in a textfile but i have an unexpected behavior while i am editing the file. What i want to do is adjust a specific line (points : 100) of a text that looks like. In the function i pass arguments by value the new coins to be adjusted and the offset of the file with ftell->user_point. What i get as an output is weird. I try to copy the rest of the file to a temp,with an edited line, and then copy it back to the original file from the point that i copied to temp.(thats the user_point offset with ftell).
Here is the original fie with entries like that:
...
_______________________________________
nickname : geo
password : cuvctq
Name : george
Surname : papas
points : 100
participated :
past draws : 0
Chosen No. :
future draws : 0
Registered : Sun Feb 05 19:23:50 2012
...
What i get after 2nd edit run is:
...
_______________________________________
nickname : geo
password : cuvctq
Name : george
Surname : papaspoints : 98
participated :
past draws : 0
Chosen No. :
future draws : 0
Registered : Sun Feb 05 19:23:50 2012
...
At the end of the text i get one extra \n after i edit the
file whch is something i dont want :/
and so further edit will spoil the text...
I also get an EXTRA \n at the end of the line which, at least what i think so, is due to "r+" mode which is something that i also dont want...
void coins_adjust(int coins_new,int user_point)
{
int lines,i,ln_point_copy;
char buffer[50],buff_copied[50];
FILE *lottary,*temp;
memset(buff_copied,'\0',sizeof(char)*50);
lottary=fopen("customers.txt","r");
temp=fopen("temp.txt","w");
fseek(lottary,user_point,SEEK_SET);
for (lines=0;lines<5;lines++)
{
memset(buffer,'\0',sizeof(char)*50);
if (lines==5)
ln_point_copy=ftell(lottary); //from TEMP to CUSTOMERS
fgets (buffer ,50 , lottary);
}
coins_new+=atoi(buffer+15);
strncpy(buff_copied,buffer,15); //copy 15 chars and fill with null
memset(buffer,'\0',sizeof(char)*50);
itoa (coins_new,buffer,10); //fix the new line to be entered
strcat(buff_copied,buffer); //the edited line is as it is supposed
strcat(buff_copied,"\n"); //to be with \n at the end.
puts(buff_copied);
printf("%s",buff_copied);fflush(stdout);
fprintf(temp,"%s",buff_copied);
for(i=getc(lottary); i!=EOF; i=getc(lottary)) //copy to temp
{
putc(i, temp);
}
fclose(lottary);
fclose(temp);
temp=fopen("temp.txt","r");
lottary=fopen("customers.txt","r+");
fseek(lottary,ln_point_copy,SEEK_SET);
for(i=getc(temp); i!=EOF; i=getc(temp)) //copy until eof
{
putc(i, lottary);
}
fclose(lottary);fclose(temp);
}
I have debugged the program and everything seems to work at least on what values are passed to the arrays where i store the line chars but i cant see why it ignores the \n of the previous line when i try to copy it back to the original... There seems to be a \r char that i cant get rid of while i copy back to the original...
Thanks in advance.
I was more thinking about something like this:
void change_points(int new_points)
{
FILE *input = fopen("customers.txt", "r");
FILE *output = fopen("temp.txt", "w");
char buffer[256];
while (fgets(buffer, sizeof(buffer), input))
{
/* Look for the correct line */
/* Can also use e.g. "if (strncmp(buffer, "points", 6) == 0)"
* if it's at the start of the line
*/
if (strstr(buffer, "points") != NULL)
{
int old_points;
sscanf(buffer, "%*s : %d ", &old_points);
/* Format how you like it */
fprintf(output, "%-13s: %d\n", "points", new_points + old_points);
}
else
fputs(buffer, output);
}
fclose(output);
fclose(input);
/* The file "temp.txt" now contains the modifeed text */
/* Copy either using "fgets"/"fputs", or using "fread"/"fwrite" */
input = fopen("temp.txt", "r");
output = fopen("customers.txt", "w");
while (fgets(buffer, sizeof(buffer), input))
fputs(buffer, output);
fclose(output);
fclose(input);
}
It's shorter, simpler, maybe more effective (looping over line-by-line instead of char-by-char), and the line you are looking for can be anywhere in the file without you knowing its exact position.

Resources