Error while trying to read from file C - file

I have a file and i need to read data from it. I have to read 2 int and 1 c string.
This is my struct
typedef struct seats
{
int number, reserved;
char * name;
} seats;
This is my main
FILE *data;
seats input;
data = fopen("data.txt", "r+");
while(fscanf(data,"%s %d %d", input.name, &input.number, &input.reserved) != EOF)
{
printf("%s %d %d", input.name, input.number, input.reserved);
}
Every time when i compile and run this software it crashes for some reason. Is there any solution?

You haven't assigned any value to input.name, but you pass its garbage value to fscanf. You need to assign a variable a value before you attempt to use that value.

Change your struct to something like this:
typedef struct seats{
int number, reserved;
char name[1000];
} seats;
and put a fflush(stdin), after printf(...)

Related

Is this a correct usage of struct?

#include <stdio.h>
int main()
{
struct database
{
char name[10];
int number;
int roll;
};
struct database s1,s2;
printf("enter name, number , roll: ");
scanf("%c%d%d",&s1.name,&s1.number,&s1.roll);
scanf("%c%d%d",&s2.name,&s2.number,&s2.roll);
printf("Entered value is :");
printf("%c%d%d",s1.name,s1.number,s1.roll);
printf("%c%d%d",s2.name,s2.number,s2.roll);
}
I've been trying to get output but I don't know if this correct Or should I access them individually? Help would be very much appreciated! thanks :)
If you need the specific struct only within the function body, then your declaration will suffice. But, note that if you want a struct to be used throughout the program, then it needs to be defined like this:
struct database {
...
};
int main(void) {
struct database s1, s2;
...
}
Also, you're trying to accept a single char value:
scanf("%c%d%d", &name, ...);
// --^^--
Here, you are expected to get a char from the user:
scanf("%9s%d%d", name, ...);
Note: The %9s is specifically given to prevent input buffer overflow.
A nicely structured program would look like (notice comments):
#include <stdio.h>
// Don't use magical numbers for constants in the program
// The use macros for this will suffice and look a ton cleaner
#define MAX_LENGTH 64
#define FMT_LENGTH "%63s"
// Our structure
struct database {
char name[MAX_LENGTH];
int number;
int roll;
};
int main(void) {
// You are here only creating single instances of struct
struct database s1, s2;
printf("Enter name, number and roll: ");
// Always check if the values are correctly assigned to their respective
// variables, if not, print error and exit (in this context)
if (scanf(FMT_LENGTH " %d %d", s1.name, &s1.number, &s1.roll) != 3) {
printf("error: One of the values are incorrectly assigned.\n");
return 1; // Exit Failure
}
// Same with s2
printf("Name: %s | Number: %d | Roll: %d\n", s1.name, s1.number, s1.roll);
return 0;
}

How can I build a function that stores data in a structure when taken from a file (pointer)?

In an assignment I'm working on, I need to read data from a file and then convert that data into a form that can be stored in a structure. The structure stores information on the person the line in the file represents. The issue that I'm having is that I cannot find a way to build a function that will allow me to take this data and store it in the structure. This is the relevant code to getting the file:
FILE* ifp;
char file_name[150], early_type[5], name_holder[LENGTH];
double early_registration, indi_registration, team_registration, amount_holder;
int num_early_regist, age_holder, type_holder;
// get file name and set it up as a pointer
printf("Please enter the name of your file.\n");
scanf("%s", file_name);
ifp = fopen(file_name, "r");
The code then goes to scanning the file for the data:
fscanf(ifp, "%s %s %d %d %lf", early_type, name_holder, &age_holder, &type_holder, &amount_holder);
// if the line shows an individual registering early
if (strcmp(early_type, "INDV")==0){
person_early(struct person* person, &name_holder, &age_holder, &type_holder, &amount_holder);
}
Finally, this is the prototype of the function that I am building:
void person_early(struct person* person, char* name[LENGTH], int* age, int* event_type, double* donation_amount);
The issue that I'm having is that I'm not sure how to put the data into this structure:
struct person {
char name[LENGTH];
int number;
int age;
int event;
float money;
float time;
};
Should I build a function to store this data, as there are several people to log from the file? Do I need to be using pass by value or pass by reference? Thanks for any help.
Edit:
The full function that I have written is this:
void person_early(struct person* person, char* name[LENGTH], int* age, int* event_type, double* donation_amount) {
// the name of the variable should be the name that is taken from the file
struct person (*name[LENGTH]);
(*name).name = *name_holder;
(*name).age = *age_holder;
(*name).event = *type_holder;
(*name).money = *donation_amount;
return;
}
regarding:
(*name).name = *name_holder;
This is not what you want. The passed in struct pointer person is the receiver of all the data. suggest:
void person_early( struct person* person, char name[], int age, int event_type, double donation_amount)
{
strcpy( person->name, name );
person->age = age;
person->event = event_type;
person->money = donation_amount;
}
Note: no return needed on a void function, unless exiting before the end of the function

Learning to process files. Trying to think of a method for maintaining file pointer position

I am working on a program to store data from a text file within a structure. The goal is to perform the file processing completely within the function outside of the main. The function opens and closes the file, and when it is called by the main function it is to populate the particular structure array element is supposed to be performed upon. The test file I am using is just a text file containing 3 lines:
Gates M 60
Jobs M 55
Jane F 45
These should be populated into an array of structures when called by the function. However, when I call the function it only populates the same first line to all array elements, I believe because the file pointer resets everytime I call the function. How can I remedy this? My code is below!
#include <stdio.h>
struct Individual
{
char LastName[30];
char gender;
unsigned int age;
};
int function(struct Individual *person)
{
FILE *cfPtr;
char holder[100];
cfPtr = fopen("C:\\Users\\Nick\\Desktop\\myfile","r");
fscanf(cfPtr, "%10s %c %3d", &person->LastName, &person->gender, &person->age);
fclose(cfPtr);
}
int main(void)
{
struct Individual person[3];
function(&person[0]);
function(&person[1]);
printf("%s %c %d", person[0].LastName, person[0].gender, person[0].age);
printf("%s %c %d", person[1].LastName, person[1].gender, person[1].age);
return 0;
}
FILE already tracks position for you; you don't need to do it yourself. The problem is that you keep re-opening the file, which resets the location back to the beginning of the file each time.
Open it once, read multiple times, then close it. Make your function take a FILE * parameter.
#include <stdio.h>
struct Individual
{
char LastName[30];
char gender;
unsigned int age;
};
int function(FILE *cfPtr, struct Individual *person)
{
fscanf(cfPtr, "%10s %c %3d", &person->LastName, &person->gender, &person->age);
// TODO: Check for failure
// TODO: Return appropriate value
}
int main(void)
{
struct Individual person[3];
FILE *cfPtr;
cfPtr = fopen("C:\\Users\\Nick\\Desktop\\myfile","r");
// TODO: Check for failure
function(cfPtr, &person[0]);
function(cfPtr, &person[1]);
fclose(cfPtr);
printf("%s %c %d", person[0].LastName, person[0].gender, person[0].age);
printf("%s %c %d", person[1].LastName, person[1].gender, person[1].age);
return 0;
}

filling array of pointers from file in c

I want to read data which is written in fprintf(fp,"%s %s %s\n", p->name,p->surname,p->tc); format. I created struct patients **p in with
struct patients **create_array(struct patients **ptr,int length){
int i;
ptr=(struct patients **)malloc(length*sizeof(struct patients));
return ptr;
}
function above create array of pointers and give it to main. Main calls read_file() function to read data from file which is written in known format. But my data is not filled when i try to print them in main it prints meaningless things. I thought problem in reading data that's why i put only reading function. What is my problem? All suggestons are welcome.
#include<stdio.h>
struct patients
{
int importance;
char name[10], surname[10], tc[11];
};
FILE *file_opening(char x[])
{
return (fopen(x,"w+"));
}
writing_file (FILE *fp, struct patients *p)
{
fprintf(fp,"%s %s %s\n", p->name,p->surname,p->tc);
}
struct patients **read_file (FILE *fp,struct patients **p)
{
int i=-1;
do{
i++;
}while(fscanf(fp,"%s %s %s",p[i]->name,p[i]->surname,p[i]->tc) !=EOF);
return p;
}
void show_all_patients(struct patients **p, int start_index, int length){
int i;
for(i=start_index;i<length;i++)
printf("%s %s %s",p[i]->name,p[i]->surname,p[i]->tc);
}
struct patients **create_array(int length){
return (struct patients **)malloc(length*sizeof(struct patients));
}
int menu(void){
int choice;
printf("1)take patient\n2)show all patients\n3)exit");
scanf("%d",&choice);
return choice;
}
main(){
int i=0,j,choice,cured_patient=0,length=1;
FILE *fp;
struct patients **ptr;
char file_name[40]="patient_list.txt";
ptr=create_array(length);
fp=file_opening(file_name);
ptr=read_file(fp,ptr);
do{
choice=menu();
if(choice==1){
printf("%s %s %s\n",ptr[i]->name,ptr[i]->surname,ptr[i]->tc);
i++;
}
else if(choice==2){
show_all_patients(ptr,i,length);
}
}while(choice!=3);
for(j=i;j<length;j++)
writing_file(fp,ptr[j]);
fclose(fp);
}
Problems with the code:
There is no return value of writing_file. Add void as the return type.
void writing_file (FILE *fp, struct patients *p)
{
fprintf(fp,"%s %s %s\n", p->name,p->surname,p->tc);
}
You need #include <stdlib.h>.
Without that the return value of malloc is assumed to be an int, which can result in strange problems.
Syntax errors:
Given your definition of ptr, the lines
ptr=create_array(length);
and
ptr=read_file(fp,ptr);
are syntactically invalid. I get the following errors with gcc:
soc.c: In function ‘main’:
soc.c:58:7: error: assignment to expression with array type
ptr=create_array(length);
^
soc.c:60:7: error: assignment to expression with array type
ptr=read_file(fp,ptr);
If your compiler does not report errors on those two lines, it's time to use a different compiler.
Reading and writing to the same file
You are using the same FILE* to read from and write to. It's not clear whether you meant to do that or it was an error on your part.
When you open the file using:
return (fopen(x,"w+"));
the contents of the file are truncated. See http://en.cppreference.com/w/c/io/fopen for more info. Pay special attention to the table under Parameters. It says:
"w+" | write extended | Create a file for read/write | destroy contents | create new
If you want to just read the data from the file, use
return (fopen(x,"r"));
If you want to read the data from the file and write back the data to it, read it first using the above mode, close the file, then reopen it using:
return (fopen(x,"w"));
Handling the array of patients
I think you should use:
FILE* fp = NULL;
int length=10;
struct patients *ptr = NULL;
ptr=create_array(length);
fp=file_opening(file_name);
read_file(fp, ptr, length);
Adjust the rest of your code appropriately.
Add code to deallocate memory
Every call to malloc should have a corresponding call to free. I would add
void delete_array(struct patients *ptr)
{
free(ptr);
}
and call it from main before the end of the function.
Things that I would change.
Return value and input arguments of create_array.
The function can also be simplified to:
struct patients* create_array(int length)
{
return malloc(length*sizeof(struct patients));
}
Return value and arguments to read_file
struct patients* read_file (FILE *fp ,struct patients *p)
{
int i=-1;
do
{
i++;
} while(fscanf(fp, "%s %s %s",p[i].name, p[i].surname, p[i].tc) != EOF);
return p;
}
Make sure that you provide the maximum number of characters to be read. Otherwise, you might end up reading more than the array are capable of holding.
Change
} while(fscanf(fp, "%s %s %s",p[i].name, p[i].surname, p[i].tc) != EOF);
to (given the size of the arrays in your struct)
} while(fscanf(fp, "%9s %9s %10s",p[i].name, p[i].surname, p[i].tc) != EOF);

Problem with structs in c

Hi guys i've got a problem here with structs, the thing is, i've created a struct and then created a function that captures the employee details referenced from that struct. Now the problem comes when i try to call the function in the main. please give me some pointers as to how to call the function. the code is as follows:
typedef struct employeeType
{
char name;
int employeeNumber;
float salary;
float taxPercentage;
}EMPLOYEE;
void enterDetails(EMPLOYEE details)
{
FILE *file;
file = fopen("employees.txt","w");
if(file == NULL)
{
printf("File error!!!");
exit(0);
}
else
{
fprintf(file,"%s",details);
}
fclose(file);
}
void main()
{
enterDetails();
}
I don't know what parameters to pass to the function in the main
I've annotated your code with some other issues to consider
typedef struct employeeType
{
/* THIS IS ONLY ONE CHARACTER... SEEMS WRONG */
/* should be 'char name[someMaxSize]', or 'char *name' */
char name;
int employeeNumber;
float salary;
float taxPercentage;
}EMPLOYEE;
/* As pointed out by 'Cody Gray', this function is called 'enterDetails'
* does it really need to have a parameter at all, or should it be responsible
* for taking the details from the user? Is it an appropriately
* named method for the task it's actually performing
* (would saveDetails be better for example)?
*/
void enterDetails(EMPLOYEE details)
{
FILE *file;
file = fopen("employees.txt","w");
if(file == NULL)
{
printf("File error!!!");
exit(0);
}
else
{
/* THIS IS PASSING A STRUCTURE AS A STRING */
/* You probably want to write out the individual fields instead */
/* fprintf(file, "%s,%d", details.name, details.employeeNumber); etc */
fprintf(file,"%s",details);
}
fclose(file);
}
void main()
{
EMPLOYEE details;
/* populate details somehow then pass it in to the function*/
enterDetails(details);
}
You may also want to consider passing details into the function as a pointer, although that would change your function signature, it would mean that you're not pushing as much information onto the stack.
If you go with the pointer version then:
void enterDetails(EMPLOYEE details)
would become
void enterDetails(EMPLOYEE *details)
and the main would become:
void main()
{
EMPLOYEE details;
/* populate details somehow then pass it in to the function as pointer */
enterDetails(&details);
}
You would also need to change the way you use details within your function, but as I've already said, I believe your fprintf call is broken already.
You can pass the pointer of the struct
void main()
{
EMPLOYEE employee;
.....
enterDetails(&employee);
}
void enterDetails(EMPLOYEE *details)
{
}
You need to pass a reference, not a value... If you pass EMPLOYEE value as in the previous post, it will be copied, the copy will be modified, not the original
void enterDetails(EMPLOYEE* emp) {
// do stuffs
}
void main() {
EMPLOYEE emp;
enterDetails(&emp);
}
void main()
{
EMPLOYEE details;
// get the value of element of struct from scanf or from other way
printf("Enter Name : ");
scanf("%s", details.name); // same for others, change the format specifier according to their data type
enterDetails(details);
}
And struct should be like
typedef struct employeeType
{
char name[]; // should be an array or pointer, to store name
int employeeNumber;
float salary;
float taxPercentage;
}EMPLOYEE;
The first problem is that your structure isn't correct. You can't store the employee's name on the name field since it's only one byte. You have to make it an array (it's simpler on this case) or a pointer to allocated memory.
If you want to make it an array, then you should define the maximum size of the array. In our example we will just make it 100 bytes, it will be more than enough to store any name.
#define MAX_NAME 100
typedef struct employeeType
{
char name[MAX_NAME];
int employeeNumber;
float salary;
float taxPercentage;
}EMPLOYEE;
Second, you're function naming is confusing. enterDetails should just populate the structure you passed. Third, your enter Details should accept a pointer to the EMPLOYEE structure. If you want to pass any value to a function that's going to change it's content, then you can only do that using pointers (or references if you're using C++ but that's basically a pointer). So enterDetails should be,
void enterDetails(EMPLOYEE *details)
{
printf("\nEnter the employee's name ");
scanf("%s", details->name); // this isn't secure since it doesn't perform bound checking.
printf("\nEnter employee number ");
scanf("%d", &details->employeeNumber);
printf("\nEnter employee salary ");
scanf("%f", &details->salary);
printf("\nEnter tax percentage ");
scanf("%f", &details->taxPercentage);
}
And finally, if you want to store the contents of the structure to a file that you want humans to read, then you should format the contents of the structure and dump it onto a file.
int writeToFile(EMPLOYEE *details) /* accepting the structure will work as well but it's faster and efficient to pass the structure's pointer */
{
FILE *file;
file = fopen("employees.txt","w");
if(file == NULL) {
printf("File error!!!");
return 0;
}
fprintf(file, "\nEmployee Name: %s", details->name);
fprintf(file, "\nEmployee Number: %d", details->employeeNumber);
fprintf(file, "\nSalary: %f", details->salary);
fprintf(file, "\nTax Percentage: %f", details->taxPercentage);
fclose(file)
return 1;
}
And main
int main(void)
{
EMPLOYEE details;
enterDetails(&details); // passing the pointer here is a must
if (!writeToFile(&details)) { // passing the pointer since it's faster
printf("\nError writing to file");
return 1;
} else {
printf("\nSuccess!");
return 0;
}
}
And in your case, you don't need to pass any parameters to main. But if you want to know how to pass parameters, then here is a quick example.
int main(int argc, char **argv)
{
int i;
for (i = 0; i < argc; i++)
printf("\n%s", argv[i]);
return 0;
}

Resources