I was asked to make a C program that act as a 'price lookup' where a user enter a product name and the program will print it's name and price which is stored in a file. If the item is not present in the file, the program will let the user know. The program will keep looping as long as the user wants to search. I did the coding using Dev C++, however after i run the code, the program got stuck after a few loops, and it's random. Could you guys detect any problem with my coding, or is it just the problem with Dev C++? I include my code below. Your help is greatly appreciated.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<ctype.h>
int main()
{
FILE *items;
char *mode="r";
char pName[50];
float pPrice;
char p1Name[50];
int value=0;
char respond='Y';
char s[50];
items=fopen("Product_Name_Price.txt", mode);
if(items==NULL)
{
fprintf(stderr, "Can't open file Product_Name_Price.txt!\n");
exit(1);
}
printf("File has been successfully opened\n");
do
{
printf("Enter the name of the product you wish to look for\n");
scanf("%s", &p1Name);
while(strcmp(p1Name, pName) !=0)
{
fscanf(items,"%s %f", pName, &pPrice);
//printf("%s\t%.2f\n", pName, pPrice);
//value=strcmp(p1Name, pName);
if(strcmp(p1Name, pName) == 0)
{
printf("%s\t%.2f\n", pName, pPrice);
}
}
/*
else
{
printf("No data in system\n");
}
*/
printf("Do you wish to look up for more item? (Y/N)\n");
scanf("%s", &respond);
}while(respond=='Y'|| respond=='y');
printf("This program is closing\n");
fclose(items);
}
Your program has undefined behaviour because your scanf("%s", &response) reads into response as if it were an array of sufficient size for the string being read — that size is at least 2 (including null terminator), but response is just one character. You blew up your stack and corrupted memory and then all bets are off.
You could write scanf("%c", &response) instead to actually read a single character, though you'd be better off switching to modern, safer tools if you're writing a C++ program.
Related
My Program Works Mostly, except for When I try to read the Total Data that was Entered
#include <stdio.h>
#include <string.h>
#define bufferSize 300
char name[50], gift[50], list[300], end[50], *result;
int i;
int main()
{
FILE *appendPlace = fopen("NamesAndGifts.txt", "a");
FILE *readData = fopen("NamesAndGifts.txt", "r"); //my place for reading data
printf("This is a Gift Entering System for 3 People Only\nThe Name of the Person then their Gift Description will be taken\nThe Gift Description is Basically the Gift Name");
while (strcmp(end, "END") != 0) {
printf("\nEnter Name of Person %d or type 'END' to Exit Sequence\n", i + 1);
scanf("%s", &end);
if (strcmp(end, "END") != 0) {
strcpy(name, end);
printf("Now Enter Gift Description (Gift Name) of Person %d\n", i + 1);
scanf("%s", &gift);
strcat(list, "\n");
strcat(list, "Name: ");
strcat(list, name);
strcat(list, "\n");
strcat(list, "Gift: ");
strcat(list, gift);
strcat(list, "\n");
}
i++;
}
printf("The Gift Entering System (Names and their respective Gifts) is Below:\n");
printf("%s", list);
fputs(list, appendPlace);
fclose(appendPlace);
//below I attempt to read file Data to be able to print file's Data into running program
fscanf(readData, "%s", result);
printf("\n\n\n\n\n\n\nTotal Data in File Below:\n%s", result);
fclose(readData);
}
I tried out doing just file reading, and it seems that reading from the file like that can only read data that is not separated by (space bar) or (enter)
Is there a way to Solve this?
So there are 2 problems in your code.
result has no memory allocated to it. Since it is a global variable, it is initialized to 0, aka a NULL pointer. So your scanf() sees that and the reading fails and so does printf() and prints "(null)". The solution there is to allocate memory in result either by making it a static array or by using malloc().
Even if you fix the first problem, however, it will still not work as expected as fscanf() will stop reading input after the first whitespace is encountered. Since you want the whole (file) input to be read, you have four options:
Read character by character (not advisable for performance reasons but perhaps the easiest to implement)
read line by line (fairly a standard way)
read chunk by chunk given some pre-allocated buffer or
read the whole file at once (not advised for big files)
The functions to use are fgetc(), getline(), fread(). Additionally, you can find the size of the file by following this question
Program(A)-----> file.txt-----> Program(B)
^This is the format I am using, I currently don't have enough knowledge with file structures.
My text file is named myStudents.txt
EDIT: Program(A) writes the information properly. Program(B) needs to retrieve the information from the text file.
#include<stdio.h>
int main()
{
char studentName[50];
int grade=0;
printf("Which students grade would you like to retrieve?: ");
scanf("%s",&studentName);
FILE *fptr;
fptr = (fopen("myStudents.txt", "r"));
if(fptr == NULL)
{
printf("Error!");
exit(1);
}
printf("\nStudent details:\n");
fscanf(fptr,"%d %[^\n]s",grade,studentName);
printf("Name: %s\n",studentName);
printf("Grade: %d\n",grade);
fclose(fptr);
return 0;
}
I'm very confused on how to use program A's information in program B. Apologies if this is a repeat thread, I couldn't find any information here or anywhere else to solve my issue.
*Note(A solid explanation would be very helpful along with any constructive criticism)
Cheers! Have a good day!
Your program B does actually not search for any name, it just tries to print the first one. I won't write the complete code for you but here is a little help with what your program should do:
read in the file line by line. (functions fscanf, fgets or getline may be useful)
extract the name and grade out of the line. (sscanf and all string functions)
check if the name is the one you are looking for, if yes print it and stop.
This is of course only an example what the program could look like, but i suggest to start by implementing this steps.
Let's say I have a file name already created named "room.txt" and it contains the following:
20 10 5
Once I execute the code below, I will be asked to specify which variable to decrease its value by 1.For example: If I input "1" it will reduce the number "20" in "room.txt".However, it doesn't reduce the value.Instead, it deletes the contents of "room.txt" file.How do I make it so that it retains the values in the file when I enter my input from the program?Also, how do I reduce the values '20' '10' '5' respectively when I input '1' '2' '3' in my program?
#include<stdio.h>
char rooms[]={"rooms.txt"};
struct rooms {
int stdsuite;
int premsuite;
int deluxesuite;
};
int stdsuite;
int premsuite;
int deluxesuite;
void availablerooms ()
{
FILE*fp;
fp = fopen(rooms,"r");
fscanf(fp,"%d %d %d",&stdsuite,&premsuite,&deluxesuite);
system("cls");
system("cls");
printf("\n\n");
printf("\t\t-----------------------------------------------\n");
printf("\t\t Room Availability\n");
printf("\t\t-----------------------------------------------\n\n");
printf("--------------------------------------------------------------------------------\n\n");
printf("\t\t Standard Suite :\t%d / 20\n\n",stdsuite);
printf("\t\t Premium Suite :\t%d / 10\n\n",premsuite);
printf("\t\t Deluxe Suite :\t%d / 5\n\n",deluxesuite);
printf("--------------------------------------------------------------------------------\n\n");
fflush(stdin);
}
int main ()
{
int choice;
FILE*fp;
availablerooms();
printf("1. Standard Suite\n\n2. Premium Suite\n\n3. Deluxe Suite\n\n");
printf("Please enter the selected room value (1-3): ");
scanf("%d",&choice);
fflush(stdin);
if (choice == 1)
{
fp = fopen(rooms,"w");
stdsuite--;
}
else if (choice == 2)
{
fp = fopen(rooms,"w");
premsuite--;
}
else if (choice == 3)
{
fp = fopen(rooms,"w");
deluxesuite--;
}
else
printf("\nThe input is invalid!");
}
Any help would be greatly appreciated! :)
To accomplish what you're trying to do in standard C you must:
Open the file for reading "r".
Read its contents to your own datastructure.
Modify the data structure.
freopen the file for writing "w".†
Write back the modified data structure.
Close the file.
† This is necessary because there is no standard C way to truncate the file in "r+" mode.
availablerooms should fclose(fp) before returning. And fflush(stdout) instead of stdin.
Then, when trying to write the data back, you only fopen the file, but you don't write anything to it. There you have a major misconception of how the things work. in the 3 ifs, you decrement the relevant variables. But that are purely in-memory operations. opening the file before, doesn't change that. So, remove the three fopens and put a new one after the last if statement followed by a fprintf(fp, "%d %d %d", stdsuite, premsuite, deluxesuite); to do the actual writing. then finish with an fclose(fp) again
I'm fairly new to C. At the moment, I'm learning about file management.
To further my understanding of files I wanted to create a Employee Database System, where the user can Create, Delete, Update or Retrieve an Employee Record. First I created a struct which contains the employee's variables like ID, first name, last name and pay, then a function which creates the records, but the there is the problem. I know how to search from the file (using the ID number) but I don't know how to delete a particular record.
(I'm so sorry because I accidentally deleted my DeleteFunction so I cannot show that particular function in my code)
My code does run well as far as I know, but you will find any errors
So here is my code:
#include <stdio.h>
#include <string.h>
typedef struct employee{
int id;
char name[40];
float pay;
}EMP;
void CreateEmployee(struct employee [] );
void DisplayRecord();
int main() {
EMP e[20];
CreateEmployee(e);
//return 0;
DisplayRecord();
return 0;
}
void CreateEmployee(struct employee x[]){
char choice ='y';
int i=0;
//EMP employee[20];
FILE *fp;
fp = fopen("employee.txt","a");
if (fp==NULL){
printf("File not created");
}
while((choice == 'Y') || (choice =='y')){
printf("Enter the employee's id:");
scanf("%i",&x[i].id);
fprintf(fp,"%i\t",x[i].id);
printf("\nEnter the employee's name:");
scanf("%s",x[i].name);
fprintf(fp,"%s\t",x[i].name);
printf("\nEnter the employee's pay:");
scanf("%f",&x[i].pay);
fprintf(fp,"%.2f\t\n",x[i].pay);
printf("\nEnter another employee?\n");
printf("Y - Yes N - No:\n");
scanf("\n%c",&choice);
i++;
}
fclose(fp);
}
void DisplayRecord(){
EMP temp;
FILE *fp = fopen("employee.txt", "r");
if(fp != NULL)
{
while( !feof(fp) )
{
fscanf(fp, "%i %s %f", &temp.id, temp.name, &temp.pay);
printf("%i %s %f\n",temp.id, temp.name, temp.pay);
}
fclose(fp);
}
else
{
printf("An error occurred opening the file\n");
}
}
I don't know how to use random access file as yet; that's why I'm using sequential access at the moment.
To delete a record, you have several choices:
Prepare by having a deleted field in each record, and when reading records, skip those that have deleted == true. To actually delete a record, set its deleted flag to true and save it.
Read the data file and write all records to a temporary file, except the one you want to delete. Finally, rename the temporary file to employees.txt.
Switch to a real database for managing the records, since all the typical operations are fast and easy then.
By the way, you haven't said why you love C as a programming language. If it is because you can quickly get your things done, you will be disappointed as soon as your programs get a little larger, since you have to do the memory management and error handling explicitly in your code. And, C makes it very easy to shoot you in the foot (so your program crashes and just doesn't work), since it doesn't have built-in memory protection. Therefore, before totally falling in love with that language, look around a little bit too see whether you can find something better.
I'm having issues trying to read a white space character in C. What I want to do is read user input when asking for a first and last name.
So for example, I prompt the user to enter their name, they type in something like "Peter Smith". With that info, I want to write it to a file.
When it writes it to a file, the file only reads the last name "Smith". How can I read the whole string?
Here's how I asked:
printf("\nPlease enter your first and last name: \n");
scanf("%[^\n]", name);
fgets(name, sizeof(name), stdin);
I don't think your problem lies in the snippet you posted. Here's an example program I wrote on my Linux system to try and pinpoint the issue:
#include <stdio.h>
int main()
{
char name[128];
int num_scans = 0;
FILE *out = fopen("name.txt", "w");
if(out == NULL)
{
printf("Failed to open file for write.\n");
return 1;
}
printf("\nPlease enter your first and last name: \n");
num_scans = scanf("%127[^\n]", name);
if(num_scans < 1)
{
printf("Error reading name.\n");
return 2;
}
fprintf(out, "%s\n", name);
fclose(out);
return 0;
}
This appeared to work for me:
$cat name.txt
Peter Smith
If you post the code you used to write the name to a file, that might reveal the source of the error.
The code is working correctly. The fgets call replaces the value you read for the first name.
You should stick to one scheme of input. When you switch between input paradigms "strange" things happen. (Technically they are exactly what is supposed to happen, but typical users tend to not be too precise about exactly how each function works, and what state the input stream is left in.)