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);
}
}
Related
void mergeFile(){
//allocate memory
char * firFile = (char*) malloc(MAX_SIZE);
char * secFile = (char*) malloc(MAX_SIZE);
char * conFile = (char*) malloc(MAX_SIZE);
char * buffer = (char*) malloc(MAX_SIZE);
char ch;
// get name of first file
printf("Enter name of first file: ");
__fpurge(stdin);
gets(buffer);
strcpy(firFile, FOLDER);
strcat(firFile, buffer);
//get name of second file
printf("Enter name of second file: ");
__fpurge(stdin);
gets(buffer);
strcpy(secFile, FOLDER);
strcat(secFile, buffer);
//get name of file will store
printf("Enter name of file which will store contents of two files : ");
__fpurge(stdin);
gets(buffer);
strcpy(conFile, FOLDER);
strcat(conFile, buffer);
//open 3 file with 'r' and 'w' mode
FILE * firPtr = fopen(firFile,"r");
FILE * secPtr = fopen(secFile, "r");
FILE * conPtr = fopen(conFile, "w");
//check 3 file NULL or not
if (firPtr == NULL) {
printf("Can not open %s file\n", firFile);
remove(conFile);
} else if (secPtr == NULL) {
printf("Can not open %s file\n", secFile);
remove(conFile);
} else if (conPtr == NULL){
printf("Can not open %s file\n",conFile);
}else{
// write all character in first file to file will store
// MAY NOT WORK
while ((ch = fgetc(firPtr)) != EOF)
fprintf(conPtr, "%c", ch);
// write all character in second file to file will store
// MAY NOT WORK
while ((ch = fgetc(secPtr)) != EOF)
fprintf(conPtr, "%c", ch);
printf("Two file were merged into %s file successfully\n!",conFile);
}
//clear all
free(buffer);
free(firFile);
free(secFile);
free(conFile);
fclose(firPtr);
fclose(secPtr);
fclose(conPtr);
}
I use fget to get character from file and write to another file, I work well when i use two file, one for read and one for store, But when i try to merge two file to another file, this code didn't work, no things in side contains file. I run this code in Netbeans 8.2, can you give me mistake from this code, thanks so much!
The following function is only used to display certain areas of a file. In this case I am trying to copy every line that has the word "EMPTY" from the main file to another file. Other than by opening a file to write to I use for char arrays to look for the proper string needed. At this point, I try to use the data from that file(In which the string was searched for) and try to copy it into another file. At this point some of the new file prints to the screen which is the first part at the top under where I created the file but when I try to add the string from the other file they do no print. Can you print certain string fro one file to another?
void emptySeats(void)
{
int position = 0;
int AvalabileOne = 0;
int countGone = 0;
int confirm = 0;
char testOne[] = "EMPTY";
char StrOne[10], StrTwo[10], StrThree[10], StrFour[10];
FILE *fEmptyseatArrangement;
fEmptyseatArrangement = fopen("airlineEmptySeatingArrangment.txt", "w+");
fprintf(fseatArrangement, "\t\t\tEcono-Airlines Passangers System\n\n\t Seat Number\t Seatavalability Last Name First Name\n");
do
{
fseatArrangement = fopen("airlineSeatingArrangment.txt", "r");
fseek(fseatArrangement, 102, SEEK_SET);
while (AvalabileOne < FULL)
{
fscanf(fseatArrangement, "%s%s%s%s\n", &StrOne, &StrTwo, &StrThree, &StrFour);
if (strcmp(StrThree, testOne))
{
fprintf(fEmptyseatArrangement, "\t\t%s\t\t%s\t\t%s\t\t%s\n", StrOne, StrTwo, StrThree, StrFour);
countGone = countGone + 1;
}
AvalabileOne = AvalabileOne + 1;
}
fclose(fEmptyseatArrangement);
fclose(fseatArrangement);
fEmptyseatArrangement = fopen("airlineEmptySeatingArrangment.txt", "r");
while (fgets(econoAirEmptySeatArrangement, 1000, fEmptyseatArrangement) != NULL)
printf("%s", econoAirEmptySeatArrangement);
fclose(fEmptyseatArrangement);
printf("There are %d seats vacant at the moment\n", FULL - countGone);
printf("Enter Zero(0) Key to return to menu at anytime.");
scanf(" %d", &position);
if (position == 0)
{
system("cls");
menu();
}
else
{
system("cls");
printf("INVALID INPUT! Please try again.\n");
}
} while (AvalabileOne != 0);
system("pause");
return;
}
I have a function for a pet store inventory program. So far, it will list the inventory, and add an item to the inventory. Now I'm trying to delete an item by its productNumber(first value store in csv text file). I changed my code around I just need a litte help with the condition. I need it to scanf the productNumber and delete the line by its product number.
QUESTION: how do I get the condition to look for the productNumber in the text file ,so I can delete that line in the text file.
I need some help please! I have a csv text file that is set up as the following structure:
struct inventory_s
{
int productNumber;
float mfrPrice;
float retailPrice;
int numInStock;
char liveInv;
char productName[PRODUCTNAME_SZ +1];
};
/*Originalfile I'm trying to copy and delete from looks 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
/*function looks like*/
int deleteProduct(void)
{
struct inventory_s newInventory;
char line[50];
//int del_line, temp = 1;
FILE* originalFile = fopen("inventory.txt", "r"); //opens and reads file
FILE* NewFile = fopen("inventoryCopy.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 delete:");
sscanf(line," %i", &newInventory.productNumber);
while(fgets(line, sizeof(line), originalFile) !=NULL)
{
if (!(&newInventory.productNumber))
{
fputs(line, NewFile);
}
}
fclose(originalFile);
fclose(NewFile);
return 0;
}
/*Input from user: 1000*/
/* What needs to happen in Newfile*/
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
fix like this
printf("Please enter the product number to delete:");
int productNumber;
scanf("%i", &productNumber);
while(fgets(line, sizeof(line), originalFile) != NULL)
{
sscanf(line, "%i", &newInventory.productNumber);
if (productNumber != newInventory.productNumber)
{
fputs(line, NewFile);
}
}
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
Trying to work with C I/O currently. I have a file that only holds integers and there is only one per line.. not commas, etc.. what is the best way to read them in:
//WHILE NOT EOF
// Read a number
// Add to collection
I am creating 2 files which is working fine.. but ultimately, I want to read them both in, join them into one collection, sort them and then print them out to a new file. There's no need for you to do all that for me, but please help with the above.. here is my effort so far:
void simpleCopyInputToOutput(void);
void getSortSave(void);
int main()
{
//simpleCopyInputToOutput();
getSortSave();
system("PAUSE");
return 0;
}
void getSortSave(void)
{
FILE *fp1;
FILE *fp2;
FILE *fpMerged;
printf("Welcome. You need to input 2 sets of numbers.\n");
printf("Please input the first sequence. Press 0 to stop.\n");
if ((fp1 = fopen("C:\\seq1.txt", "w")) == NULL)
{
printf("Cannot open or create first file!\n");
exit(1);
}
int num;
int i = 1;
while (num != 0)
{
printf("Please input value # %d\n", i);
scanf("%d", &num);
if (num == 0)
{
break;
}
fprintf(fp1, "%d\n", num);
i++;
}
printf("Please input the second sequence. Press 0 to stop.\n");
if ((fp2 = fopen("C:\\seq2.txt", "w")) == NULL)
{
printf("Cannot open or create second file!\n");
exit(1);
}
num = -1;
i = 1;
while (num != 0)
{
printf("Please input value # %d\n", i);
scanf("%d", &num);
if (num == 0)
{
break;
}
fprintf(fp2, "%d\n", num);
i++;
}
fclose(fp1);
fclose(fp2);
if ((fp1 = fopen("C:\\seq1.txt", "r")) == NULL)
{
printf("Cannot open first file!\n");
exit(1);
}
//WHILE NOT EOF
// Read a number
// Add to collection
//TODO: merge ints from both files, sort and output to new file
}
I would suggest you use fgets:
char buffer[16];
while (fgets(buffer, sizeof(buffer), fp1))
{
long value = strtol(buffer, NULL, 10);
/* Use the value... */
}
/* fgets failed ro read, check why */
if (!feof(fp1))
printf("Error: %s\n", strerror(errno));
Edit: How to get the number of entries in the file: If you don't keep track of it any other way (like e.g. having the number of items being the first line), the only solution may be to read the file twice. Once to count the number of lines, and once to read the actual numbers. Use fseek or rewind after the counting to "rewind" the read pointer to the beginning of the file.
I would personally put the counting in a separate function, and also the actual reading. This way you don't have to duplicate code if you want to read from multiple files.
Your problem can be divided into three different parts: reading in two files, sorting the data, and writing the output into a file. I am assuming here that the two input files are not already sorted. If they were, the problem would be greatly simplified (google for mergesort if that is the case).
If you want to open a file for reading, you have to use "r" instead of "w" as file open mode flag. In your example code the read/write parts are somehow reversed from what you describe above. Then you should use fscanf to read formatted input from a FILE*. scanf(...) is just short for fscanf(stdin, ...). You can access the files in the following way:
FILE *fin1 = fopen("seq1.txt", "r");
FILE *fin2 = fopen("seq2.txt", "r");
FILE *fout = fopen("out.txt", "w");
if (fin1 && fin2 && fout) {
// Do whatever needs to be done with the files.
}
if (fout)
fclose(fout);
if (fin2)
fclose(fin2);
if (fin1)
fclose(fin1);
Using dynamic memory to store the integers is difficult. You need to use realloc to grow a buffer as you write more and more data into it, and finally use qsort to sort the data. Someone else can hopefully give more insight into that if needed.