How do I search a record using an integer from a file? - c

Currently, I can only search using a string but I don't know how to search a record when the user inputs a 12 digit number (long long data type). I tried to write if(identityC == line) where the original if(strcmp(....) code was at but I didn't get it to work. Any solutions?
char line[255], name[30];
long long identityC;
FILE* fpointer = fopen("123 Hotel Customer.txt", "r");
//printf("\nPlease Enter Your Identity Card Number: ");
//scanf("%lld", &identityC);
printf("\nPlease Enter your Name to Search your Room Booking: ");
scanf("%s", &name);
while (!feof(fpointer))
{
fgets(line, 255, fpointer);
if (strncmp(name, line, strlen(name)) == 0)
printf("%s", line);
}
fclose(fpointer);
return;

Note: The purpose is to show a way to get started with working with files.
Assuming you store information in your file in this format,
roomno,Hotel Name,Customer name,isOccupied
datatype: int, string, string, bool
you can do this-
FILE* file = fopen("filename.txt","w");
char buffer[512];
while(fgets(buffer, 512, file)!=NULL){
int roomNo = strtok(buffer, "\n,");
char* hotel_name = strtok(NULL, "\n,");
char* customer_name = strtok(NULL, "\n,");
bool isOccupied = strtok(NULL, "\n,");
// Now you are done extracting values from file. Now do any work with them.
}
Here is information on strtok() and fgets().
Also, from Steve Summit, Why is while (!feof (file) ) always wrong?

Related

scan a line with numbers and words and just keep the words in c

I have a text file that has listed albums and songs.
eg:
Pink Floyd : Dark Side of the Moon
0:01:30 - Speak to Me
0:02:43 - Breathe
0:03:36 - On the Run
0:04:36 - The Great Gig in the Sky
I am using sscanf to get the duration of each song. When I am trying to get the name of the song im just getting a blank page. How can I just discard all the other characters I don't want. So far for the duration I use this:
int temp1,temp2,temp3;
char str[100];
char symbol[2]="-";
FILE *fp;
fp = fopen("albums.txt","r");
if (fp == NULL) {
printf("Error: unable to open ‘albums.txt’Report error.in mode ’r’\n");
exit(EXIT_FAILURE);
}
while (fgets(str, 100, fp) != NULL)
{
if(strstr(str,symbol))
{
sscanf(str,"%d:%d:%d",&temp1,&temp2,&temp3);
getHour(temp1,temp2,temp3); //temp1:hours, temp2:minutes, temp3:seconds
}
}
fclose(fp);
Test the return value of sscanf() for success. Use "%*d" to scan an int, yet not save. Use "%[^\n]" to scan and save all non-'\n' characters.
Code can consume the ''-'` as part of the scan.
while (fgets(str, sizeof str, fp) != NULL) {
char title[sizeof str]; // Wide enough for anything from `str`.
if (sscanf(str, "%*d :%*d :%*d - %[^\n]", title) == 1) {
// success
printf("<%s>\n", title);
}
}

Two words in a string from text file

I'm trying to get two words in a string and I don't know how I can do it. I tried but if in a text file I have 'name Penny Marie' it gives me :name Penny. How can I get Penny Marie in s1? Thank you
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Hello world!\n");
char s[50];
char s1[20];
FILE* fp = fopen("file.txt", "rt");
if (fp == NULL)
return 0;
fscanf(fp,"%s %s",s,s1);
{
printf("%s\n",s);
printf("%s",s1);
}
fclose(fp);
return 0;
}
Change the fscanf format, just tell it to not stop reading until new line:
fscanf(fp,"%s %[^\n]s",s,s1);
You shall use fgets.
Or you can try to do this :
fscanf(fp,"%s %s %s", s0, s, s1);
{
printf("%s\n",s);
printf("%s",s1);
}
and declare s0 as a void*
The other answers address adjustments to your fscanf call specific to your stated need. (Although fscanf() is not generally the best way to do what you are asking.) Your question is specific about getting 2 words, Penny & Marie, from a line in a file that contains: name Penny Marie. And as asked in comments, what if the file contains more than 1 line that needs to be parsed, or the name strings contain a variable number of names. Generally, the following functions and techniques are more suitable and are more commonly used to read content from a file and parse its content into strings:
fopen() and its arguments.
fgets()
strtok() (or strtok_r())
How to determine count of lines in a file (useful for creating an array of strings)
How to read lines of file into array of strings.
Deploying these techniques and functions can be adapted in many ways to parse content from files. To illustrate, a small example using these techniques is implemented below that will handle your stated needs, including multiple lines per file and variable numbers of names in each line.
Given File: names.txt in local directory:
name Penny Marie
name Jerry Smith
name Anthony James
name William Begoin
name Billy Jay Smith
name Jill Garner
name Cyndi Elm
name Bill Jones
name Ella Fitz Bella Jay
name Jerry
The following reads a file to characterize its contents in terms of number of lines, and longest line, creates an array of strings then populates each string in the array with names in the file, regardless the number of parts of the name.
int main(void)
{
// get count of lines in file:
int longest=0, i;
int count = count_of_lines(".\\names.txt", &longest);
// create array of strings with information from above
char names[count][longest+2]; // +2 - newline and NULL
char temp[longest+2];
char *tok;
FILE *fp = fopen(".\\names.txt", "r");
if(fp)
{
for(i=0;i<count;i++)
{
if(fgets(temp, longest+2, fp))// read next line
{
tok = strtok(temp, " \n"); // throw away "name" and space
if(tok)
{
tok = strtok(NULL, " \n");//capture first name of line.
if(tok)
{
strcpy(names[i], tok); // write first name element to string.
tok = strtok(NULL, " \n");
while(tok) // continue until all name elements in line are read
{ //concatenate remaining name elements
strcat(names[i], " ");// add space between name elements
strcat(names[i], tok);// next name element
tok = strtok(NULL, " \n");
}
}
}
}
}
}
return 0;
}
// returns count, and passes back longest
int count_of_lines(char *filename, int *longest)
{
int count = 0;
int len=0, lenKeep=0;
int c;
FILE *fp = fopen(filename, "r");
if(fp)
{
c = getc(fp);
while(c != EOF)
{
if(c != '\n')
{
len++;
}
else
{
lenKeep = (len < lenKeep) ? lenKeep : len;
len = 0;
count++;
}
c = getc(fp);
}
fclose(fp);
*longest = lenKeep;
}
return count;
}
Change your fscanf line to fscanf(fp, "%s %s %s", s, s1, s2).
Then you can printf your s1 and s2 variables to get "Penny" and "Marie".
Try the function fgets
fp = fopen("file.txt" , "r");
if(fp == NULL) {
perror("Error opening file");
return(-1);
}
if( fgets (str, 60, fp)!=NULL ) {
/* writing content to stdout */
puts(str);
}
fclose(fp);
In the above piece of code it will write out the content with the maximum of 60 characters. You can make that part dynamic with str(len) if I'm not mistaken.

Editing a specific value in a csv text file through C programming

I'm trying to make a function that updates my csv text file.
The text file I have already has data inside it. I just want to change one of the values in one of the selected lines of data. I kind of confused on what to do here. When I try to print out the newInventory.numInstock it gives me the memory address. How can I get it to show me the text file values? I know I need to read the old file then copy what I need to a new file. Can someone help me out with this please.
My question is how do I get it to modify the numInStock? I want to be able to change that with this function.
/*here's my structure*/
struct inventory_s
{
int productNumber;
float mfrPrice;
float retailPrice;
int numInStock;// 4th column
char liveInv;
char productName[PRODUCTNAME_SZ +1];
};
/* My text file looks something like: */
1000,1.49,3.79,10,0,Fish Food
2000,0.29,1.59,100,1,AngelFish
2001,0.09,0.79,200,1,Guppy
5000,2.40,5.95,10,0,Dog Collar Large
6000,49.99,129.99,3,1,Dalmation Puppy
/*Here's my function so far*/
int updateStock(void)
{
struct inventory_s newInventory;
int productNumber;
char line[50];
FILE* originalFile = fopen("stuff.txt", "r"); //opens and reads file
FILE* NewFile = fopen("stuffCopy.txt", "w"); //opens and writes file
if(originalFile == NULL || NewFile == NULL)
{
printf("Could not open data file\n");
return -1;
}
printf(" Please enter the product number to modify:");
scanf(" %i", &productNumber);
printf("Current value is %i; please enter new value:", &newInventory.numInStock );
while(fgets(line, sizeof(line), originalFile) != NULL)
{
sscanf(line, "%d,%*f,%*f,%i", &newInventory.productNumber, &newInventory.mfrPrice, &newInventory.retailPrice, &newInventory.numInStock);
if (productNumber == newInventory.productNumber)
{
fputs(line, NewFile);
//fscanf(NewFile, "%s", &newInventory.productName);
printf(" %i",newInventory.numInStock);
}
}
fclose(originalFile);
fclose(NewFile);
// remove("stuff.txt");
//rename("stuffCopy.txt", "inventory.txt");
return 0;
}
So far I get it to print out the line that I'm trying to access. I need it to just access one of the values in the structure and show that one only. Then I need to change it to a new value from the user.
fix like this ( it will be your help.)
printf("Please enter the product number to modify:");
scanf("%i", &productNumber);
while(fgets(line, sizeof(line), originalFile) != NULL)
{
sscanf(line, "%i", &newInventory.productNumber);
if (productNumber == newInventory.productNumber)
{
sscanf(line, "%i,%f,%f,%i,%c,%[^\n]", &newInventory.productNumber,
&newInventory.mfrPrice,
&newInventory.retailPrice,
&newInventory.numInStock,
&newInventory.liveInv,
newInventory.productName);
printf("Current value is %i; please enter new value:", newInventory.numInStock );
scanf("%i", &newInventory.numInStock );
fprintf(NewFile, "%i,%f,%f,%i,%c,%s\n",newInventory.productNumber,
newInventory.mfrPrice,
newInventory.retailPrice,
newInventory.numInStock,
newInventory.liveInv,
newInventory.productName);
}
else
{
fputs(line, NewFile);
}
}

Get one string with space first and get another after tabs

I want to get strings from a .txt file, reading lines that each has name and phone number. and two \t characters are between names and phone numbers.
Example:
name\t\t\tphone#
thomas jefferson\t\t054-892-5882
bill clinton\t\t054-518-6974
The code is like this;
FILE *f;
errno_t err;
treeNode *tree = NULL, temp;
char input, fileName[100];
//get file name
while (1){
printf("Enter input file name: ");
scanf_s("%s", fileName, 100);
//f = fopen(fileName, "r");
if(err = fopen_s(&f, fileName, "r"))
printf("Cannot find file!\n");
//if (f == NULL)
// printf("Cannot find file!\n");
else
break;
}
//save info into BST
fscanf_s(f, " NAME Phone #\n", 20);
while (fscanf_s(f, "%[^\t]s\t\t%[^\n]s",
temp.name, temp.phoneNo, 50, 30) != EOF)
bstInsert(tree, temp.name, temp.phoneNo);
fclose(f);
treeNode is a binary search tree struct, and bstInsert is a function to add a struct containing 2nd and 3rd parameters to a binary search tree.
after I get the name of the file with scanf_s, code stops at the fscanf_s statement, showing below on the debugger;
temp.name: invalid characters in string.
temp.phoneNo: ""
I don't know how [^\t] or [^\n] works exactly. Can anyone let me know how I can deal with this problem? Thanks in advance!
"Can anyone let me know how can I deal with this problem?" I am no fan of scanf and family, so I deal with the problem by using different methods. Following your lead of using fopen_s and scanf_s I have used the "safer" version of strtok which is strtok_s.
#include <stdio.h>
#include <string.h>
int main (void) {
FILE *f;
errno_t err;
char *pName, *pPhone;
char input[100], fileName[100];
char *next_token = NULL;
// get file name
do{
printf("Enter input file name: ");
scanf_s("%s", fileName, 100);
if(err = fopen_s(&f, fileName, "r"))
printf("Cannot find file!\n");
} while (err);
// read and process each line of the file
while(NULL != fgets(input, 100, f)) { // has trailing newline
// isolate name
pName = strtok_s(input, "\t\r\n", &next_token); // strip newline too
if (pName == NULL) // garbage trap
pName = "(Error)";
printf ("%-30s", pName);
// isolate phone number
pPhone = strtok_s(NULL, "\t\r\n", &next_token); // arg is NULL after initial call
if (pPhone == NULL)
pPhone = "(Error)";
printf ("%s", pPhone);
printf ("\n");
}
fclose(f);
return 0;
}
Program output using a file with your example data:
Enter input file name: test.txt
name phone#
thomas jefferson 054-892-5882
bill clinton 054-518-6974

How to store data from files to an array in C

So, basically this code below need the user to login first, then after the user login it will show the user details like the one stored in the user.txt. after that i dunno how to retrieve back the files from the files then return it as an array, so that i can update e.g change the name of the user, or delete the user details by taking the array index
here is my code
#include <stdio.h>
#include <string.h>
typedef struct {
char fullname[30];
char dob [10];
int contactNo;
int postcode;
}userDetails;
int main ()
{
char username [15];
char pwd [20];
char user_pass [30];
char userfile [100];
FILE *user;
FILE *admin;
userDetails myUser;
admin = fopen ("admin.txt","r");
printf("Please enter your Username\n");
scanf("%s",username);
printf("Please enter your Password\n");
scanf("%s",pwd);
user_pass[strlen(username) + strlen(pwd) + 2];
sprintf(user_pass, "%s;%s", username, pwd);
while (fgets(userfile, 100, admin) != NULL) {
if (strcmp(userfile, user_pass) == 0) {
printf("Authentication as %s successful\n", username);
size_t nread; // Printing the user information
user = fopen("user.txt", "r");
printf("\nHere is the registered user:\n");
if (user) {
while ((nread = fread(myUser.fullname, 1, sizeof myUser.fullname, user)) > 0)
fwrite(myUser.fullname, 1, nread, stdout);
if (ferror(user)) {
}
fclose(user);
}
}
else{
printf("Please enter correct username and password\n");
}
}
}
and let say in the user.txt the file is stored in a format like this
john;12/12/1990;+6017012682;57115
paul;12/12/1221;+60190002122;100022
max;12/11/1990;+60198454430;900000
jamie;12/05/2000;+60190001231;18000
Thank you
how do you read a data from a files and store it to an array, then read specific stored data in the array to be edited?
Steps to store data:
1) - Declare the type(s) of storage variables needed to support your concept. Array of struct perhaps.
2) - Open file ( FILE *fp = fopen("file path", "r"); )
3) - Loop on fgets() to read each line (record) of file
4) - Parse lines, perhaps using strtok and place elements of each line into storage variable you created above.
5) - close file ( fclose(fp); )
The get record part can be done by selecting a record, and returning a re-concatenated string composed of each field of the original record. The prototype could look like this:
void GetRecord(RECORD *pRec, int rec, char *recordStr);
Where storage would be created as an array of struct, and the struct would accommodate the 4 fields you cited, eg:
John;12/12/1990;+6017012682;57115 //example record with 4 fields
#define MAX_RECORDS 10 //arbitrary value, change as needed
typdef struct {
char name[260];
char date[11];
char num1;
char num2;
} RECORD;
RECORD record[MAX_RECORDS];//change size to what you need, 10 is arbitrary for illustration
Code Example to read data into records , and retrieve a record, could look like this:
(example only, very little error checking)
void GetRecord(RECORD *pRec, int rec, char *record);
int main(void)
{
FILE *fp = {0};
char recStr[260];
char *buf;
char line[260];
int i;
char strArray[3][7];//simple array, 3 string of 7 char each (enough for NULL terminator)
i = -1;
fp = fopen ("admin.txt", "r");
if(fp)
{
while (fgets (line, 260, fp))//will continue to loop as long as there is a new line
{
i++;
if(i >= MAX_RECORDS) break;//reached maximum records defined, time to leave
buf = strtok(line, ";");
if(buf)
{
strcpy(record[i].name, buf);
buf = strtok(NULL, ";");
if(buf)
{
strcpy(record[i].date, buf);
buf = strtok(NULL, ";");
if(buf)
{
record[i].num1 = atoi(buf);
buf = strtok(NULL, ";");
if(buf)
{
record[i].num2 = atoi(buf);
}
}
}
}
}
}
fclose(fp);
// 2nd argument valid values range from 1 - n (not 0 - n)
GetRecord(record, 3, recStr); //read third record into string "rec"
return 0;
}
void GetRecord(RECORD *pRec, int rec, char *record)
{
int r = rec - 1;//adjust for zero indexed arrays
if((r >= MAX_RECORDS) || (r < 0))
{
strcpy(record, "index error");
return;
}
sprintf(record, "%s;%s;%d;%d", pRec[r].name, pRec[r].date, pRec[r].num1, pRec[r].num2);
}
Note: "coz [you were] rushing and just copy the code, and accidentaly delete the important things",
I have not adhered strictly to your variable names. Adjust what I have done to meet your needs.
Results with your input file look like this:

Resources