scanf doesn't store proper information in structure - c

I have a problem with scanf. scanf doesn't store proper information in structure. Part of code is:
if( figure->pro.p_category == 'C' || figure->pro.p_category == 'c' ){
printf("Enter data line> ");
result += scanf("%s %d%c %d %d %d%c", (figure->pro.name), &temp,\
&figure->pro.money, &figure->exp.month, &figure->exp.year,\
&figure->ais.aisle_num, &figure->ais.aisle_side);
if ( figure->pro.money == 'C')
figure->pro.cents = temp;
else if( figure->pro.money == 'D')
figure->pro.dollars = temp;
}
figure->pro.name and figure->exp.month store different values.
My structures are:
typedef struct {
char name[20];
char p_category,
sub_p_category,
money;
int cents,
dollars;
}product_t;
typedef struct {
int aisle_num;
char aisle_side;
}aisle_t;
typedef struct {
int day,
month,
year;
}experiment_t;
typedef struct {
int day,
month,
year;
}packaging_t;
typedef union {
product_t pro;
experiment_t exp;
packaging_t pack;
aisle_t ais;
}figure_t;
For instance;
input> corn 89C 11 2010 11B
This piece of code from output function:
printf("The %s costs %d cents, expires in ",my_figure.pro.name, my_figure.pro.cents);
print_exp_month(my_figure);
printf("of %d, and is displayed in %d%c", my_figure.exp.year, my_figure.ais.aisle_num,\
my_figure.ais.aisle_side);
its output:
The
costs 89 Dollar, expires in of 2000, and is displayed in 12B
The proper output:
The corn costs 89 cents, expires in November of 2000, and is displayed in 12B

If you store your data in a union
typedef union {
product_t pro;
experiment_t exp;
packaging_t pack;
aisle_t ais;
} figure_t;
only one set of data is stored at each time. When you read into, for example, figure->pro.money and figure->exp.month the data will be stored in the same place and overwrite each other.
So when you try to print it, it is not there anymore!

Related

I want to store the сustomer information in an array of customers

this for adding new costumer.
typedef struct date{
int d,m,y;
}date;
typedef struct client{
int *id;
char *nom [30];
char *prenom [30];
date date;
char *adresse[30] ;
char *tel [30];
}client;
client cl;
void ajouter (){
int age;
printf("give first name:\n");
scanf("%s",&cl.nom);
printf("give last name:\n");
scanf("%s",&cl.prenom);
printf("give adresse:\n");
scanf("%s",&cl.adresse);
printf("give tel num:\n");
scanf("%s",&cl.tel);
printf("give date of birth :\n");
scanf("%d %d %d",&cl.date.d, &cl.date.m, &cl.date.y);
cl.id=1;
if(2019-cl.date.y<18)
printf("refuse");
else
printf(" succes\n");
printf("your informations:\n");
printf(" first name: %s \n last name: %s \n adresse: %s \n tel num: %s \n date of birth : %d/%d/%d \n ID: 0000000%d",cl.nom,cl.prenom,cl.adresse,cl.tel,cl.date.d,cl.date.m,cl.date.y,cl.id);
cl.id++;
}
the problem is when i add the 1st costumer i dont know how to store the informations
i want to save it without using files.
i am beginner and i know maybe its wrong what am doing
but am trying to do my best to make this code
int main()
{
int a,age;
char t[100];
printf("----------- menu ------------\n");
printf("add customer : 1\n");
printf("remove customer : 2\n");
printf("search for customer : 3\n");
scanf("%d",&a);
switch(a){
case(1):ajouter(a);break;
}
return 0;
}
i didnt finish it yet
Salut,
If I understood well, you wish to store a client's data in an array in RAM.
I believe you are using C, hence vectors are not really an option.
So instead, you have either the option of having an array of fixed size, which could be useful in certain situations but generally not, or having a dynamic array, which can be kind of hard to understand when begginning but you shouldn't have much trouble.
In the case a fixed-size array works for you, here's an example of how you'd do it:
//Declaring the client array
#define nClientsTableau 100
int nClients = 0;
client clients[nClientsTableau];
...
//Adding a new client, keep in mind it's just an example
ajouter();
clients[nClients] = cl;
nClients++;
if(nClients == nClientsTableau) printf("Max amount of clients reached");
Then for the second option, building a dynamic array. Different ways of doing it exist, here is a simple way to perform it for your code:
//Declaring the client array
client* clients = NULL;
client* clients2 = NULL;
int nClients = 0
//Adding a new client
ajouter();
nClients++;
clients2 = (client*)realloc(clients, nClients * sizeof(client));
clients = clients2; //NOTE: You should probably check for clients2 not being NULL first
clients[nClients - 1] = cl;
//Ending the program
free(clients);
I sincerely hope this helps. Apart from that, I'd like to tell you that your code is excellent for a beginner, just try having some naming conventions.

Read from a text file to fill a structure type

[The code is working now, Thanks for the help.]
I can get the program to print the first set of struct auto_t. When I try to print the other sets nothing happens or I get an error.
This is what I have to do.
Define a structure type auto_t to represent an automobile. Include components
for the make and model (strings), the odometer reading, the manufacture
and purchase dates (use another user-defined type called date_t ),
and the gas tank (use a user-defined type tank_t with components for tank
capacity and current fuel level, giving both in gallons). Write I/O functions
scan_date , scan_tank , scan_auto , print_date , print_tank , and
print_auto , and also write a driver function that repeatedly fills and displays
an auto structure variable until EOF is encountered in the input file.
Here is a small data set to try :
Mercury Sable 99842 1 18 2001 5 30 1991 16 12.5
Mazda Navajo 123961 2 20 1993 6 15 1993 19.3 16.7
Here is the code that works:
[If you see any thing wrong with the code that I missed I don't mind the feed back]
#include <stdio.h>
#define SIZE 20
// the structures
typedef struct //struct for date
{
int month,day,year;
} date_t;
typedef struct //struct for the tank info
{
double capacity;
double curent_Fuel;
} tank_t;
typedef struct //the struct for the automobie
{
char make[SIZE];
char model[SIZE];
int odometer;
date_t manufact;
date_t purchase;
tank_t tank;
} auto_t;
//the function
void print_date(date_t da);
void print_tank(tank_t ta);
void print_auto(auto_t au);
int scan_date(date_t *date);
int scan_tank(tank_t *tank);
int scan_automobile(auto_t *automo);
//Start of program
int main (void)
{
auto_t car;
int stat = 1;
FILE *Car_data; //file used
Car_data = fopen("car.txt", "r");// has the date for the cars like make, model ect.
if (Car_data==NULL){
printf("ERROR: File failed to open");
getch();
exit(1);
fclose(Car_data);}
else
while(stat>0)
{
stat=fscanf(Car_data, "%s %s %d %d %d %d %d %d %d %lf %lf", &car.make,
&car.model,
&car.odometer,
&car.manufact.month,
&car.manufact.day,
&car.manufact.year,
&car.purchase.month,
&car.purchase.day,
&car.purchase.year,
&car.tank.capacity,
&car.tank.curent_Fuel);
if (stat==11)
{
print_auto(car);
printf("Maufactured date:");
print_date(car.manufact);
printf("\nPurchased date:");
print_date(car.purchase);
printf("\nTank capacity and current fuel");
print_tank(car.tank);
}
}
getch(); // Just used to keep the data on the sreen for testing pupose
return(0);
}
int scan_date(date_t *date)
{
int res;
res=scanf("%d %d %d", &(*date).month, &(*date).day, &(*date).year);
if(res==3)
res=1;
else if(res !=EOF)
res=0;
return(res);
}
int scan_tank(tank_t *tank)
{
int res;
res=scanf("%lf %lf", &(*tank).capacity, &(*tank).curent_Fuel);
if(res==2)
res=1;
else if(res !=EOF)
res=0;
return(res);
}
int scan_automobile(auto_t *automo)
{
int res;
res=scanf("%s %s %d %d %d %d %d %d %d %lf %lf", &(*automo).make,
&(*automo).model,
&(*automo).odometer,
&(*automo).manufact.month,
&(*automo).manufact.day,
&(*automo).manufact.year,
&(*automo).purchase.month,
&(*automo).purchase.day,
&(*automo).purchase.year,
&(*automo).tank.capacity,
&(*automo).tank.curent_Fuel);
if(res==11)
res=1;
else if(res !=EOF)
res=0;
return(res);
}
void print_date(date_t da)
{
printf("\n%d-%d-%d", da.month, da.day, da.year);
}
void print_tank(tank_t ta)
{
printf("\n%2.2lf %2.2lf\n", ta.capacity, ta.curent_Fuel);
}
void print_auto(auto_t au)
{
printf("\nVehicle \n%s %s %d %d %d %d %d %d %d %lf %lf\n", au.make,
au.model,
au.odometer,
au.manufact.month,
au.manufact.day,
au.manufact.year,
au.purchase.month,
au.purchase.day,
au.purchase.year,
au.tank.capacity,
au.tank.curent_Fuel);
}
There are a couple of things I don't understand in your code which might get you in trouble :
if (Car_data==NULL){
printf("ERROR: File failed to open");
getch();
exit(0);
fclose(Car_data);}
Why are you using exit(0) when dealing with an error ? May be check this.
if(stat==11)
print_auto(car);
// rest of the code
Aside from indentation, I am not sure you get that here, if (stat == 11), only print_auto(car) will be executed.
You need to do this if you want conditions and loops to embrace more that one line of code :
if(condition)
{
// code
}
else
{
// code
}
loop()
{
// code
}
I think there is a high pourcentage of chance that your errors come from this.
This is not really an answer but the way you format your code is very error prone:
For example this piece of code:
res=scanf("%lf %lf", &(*tank).capacity, &(*tank).curent_Fuel);
if(res==2)
res=1;
else if(res !=EOF)
res=0;
return(res);
should rather be formatted like this:
res=scanf("%lf %lf", &(*tank).capacity, &(*tank).curent_Fuel);
if(res==2)
res=1;
else if(res !=EOF)
res=0;
return(res);

Using malloc to create a pointer to multiple struct items

For a c programming class, I have been told to create the following structs with typedefs, in that order:
//STRUCTS
struct time {
unsigned int hour;
unsigned int minute;
unsigned int second;
};//end struct time
struct date {
unsigned int month;
unsigned int day;
unsigned int year;
};//end struct Date
struct event {
char name[20];
struct time* time;
struct date* date;
};//end struct event
//TYPEDEFS
typedef struct time Time;
typedef struct date Date;
typedef struct event Event;
From there I'm supposed to ask for the max number of events to create, then allocate a pointer with enough memory for that many Events. Part of my work is:
Event *events;
//Ask for max number of events and allocate memory
printf("Number of events to add: ");
scanf("%d", &numEvents);
events = (Event*) malloc(sizeof(Event) * numEvents);
However, from there I'm unsure of what to do to traverse the pointer to view a specific event. I know it isn't just an array, so events[i] won't work. but beyond that, I'm lost. My (broken)function for getting an event is:
void getEvent(Event *events, int index){
//variables
char title[20];
unsigned int day, month, year, hour, minute, second;
Event tempEvent;
//Ask for input
printf("Input title, date, and time.\n");
if(index == 0)
printf("example -> title: dd/mm/yy hh:mm:ss\n");
//Take input
scanf("%20[^:]: %u/%u/%u %u:%u:%u", title, &day, &month, &year, &hour, &minute, &second);
tempEvent = (Event) {*title, { hour, minute, second }, { month, day, year } };
events[index] = tempEvent;
}
I know that it isn't right, and I got a segmentation fault on testing.
When I compile, I get these warnings (and some repeats about similar things):
Lab4.c: In function ‘getEvent’: Lab4.c:82:2: warning: braces around scalar initializer
tempEvent = (Event) {*title, { hour, minute, second }, { month, day, year } };
^ Lab4.c:82:2: note: (near initialization for ‘(anonymous).name[1]’)
Lab4.c:82:39: warning: excess elements in scalar initializer
tempEvent = (Event) {*title, { hour, minute, second }, { month, day, year } }
The compiler is telling you that line 82 is a mess.
tempEvent = (Event) {*title, { hour, minute, second }, { month, day, year } };
In particular, the first member of the event structure is an array char name[20], but you attempt to initialize it with a single character *title. But the bigger problem is that time and date (in the event structure) are pointers, and you haven't allocated any memory for those pointers.
One solution is to allocate memory, and then have scanf fill in the values, like this:
void getEvent( Event *events, int n )
{
// allocate memory
events[n].time = malloc(sizeof(Time));
events[n].date = malloc(sizeof(Date));
if ( events[n].time == NULL || events[n].date == NULL )
{ /* TODO: handle the error */ }
//Ask for input
printf("Input title, date, and time.\n");
if ( n == 0 )
printf("example -> title: dd/mm/yy hh:mm:ss\n");
//Take input
int count = scanf( "%20[^:]:%u/%u/%u%u:%u:%u", events[n].name,
&events[n].date->day, &events[n].date->month, &events[n].date->year,
&events[n].time->hour, &events[n].time->minute, &events[n].time->second );
if ( count != 7 )
{ /* TODO: handle the error */ }
}

Program for Typedef Structure look up Keeps Crashing

I am trying to write a console application where the user enters in a City then the program looks up the city name in a typedef structure and proceeds to display the city's latitude and longitude coordinates. I have zero errors displaying for the program, but it seems that each time I enter a city and press enter the console application will display city not found and then close out. Here is the code with a few of the cities from the typdef structure (full structure contains 200 variables).
#include <stdio.h>
#include <string.h>
#define MAX_CITY_LEN 35
typedef struct {
char name[MAX_CITY_LEN];
float latitude;
float longitude;
} PLACE_T;
PLACE_T places[] =
{{"Aberdeen,Scotland",57.15,-2.15},
{"Adelaide,Australia",-34.92,138.6},
{"Albany,NY,USA",42.67,-73.75},
{"Albuquerque,NM,USA",35.08,-106.65},
{"Algiers,Algeria",36.83,3.0},
{"Amarillo,TX,USA",35.18,-101.83},
{"Amsterdam,Netherlands",52.37,4.88},
{"Anchorage,AK,USA",61.22,-149.9},
{"Ankara,Turkey",39.92,32.92},
{"Asuncion,Paraguay",-25.25,-57.67},
{"Athens,Greece",37.97,23.72},
{"Atlanta,GA,USA",33.75,-84.38},
{"Auckland,New Zealand",-36.87,174.75},
{"",999,999}};
int main()
{
int j;
int found=0;
char city[MAX_CITY_LEN];
int citySize=(sizeof(places)/sizeof(places[0]));
printf("Please Enter the Name of a City: \n");
scanf_s("%s", &city, MAX_CITY_LEN,stdin);
city[strlen(city)-1]='\0';
for(j=0;j<citySize;j++)
{
if(strcmp(city,places[j].name)==0)
{
found=1;
printf("lat = %f, long = %f",places[j].latitude,places[j].longitude);
break;
}
}
if(!found)
printf("City not found");
return 0;
}
Thanks!
try this
int found=0;
char city[MAX_CITY_LEN];
int citySize=(sizeof(places)/sizeof(places[0]));
int j, len;
printf("Please Enter the Name of a City: \n");
scanf_s("%34s", city, MAX_CITY_LEN);
len = strlen(city);
for(j=0;j<citySize;j++){
if(strncmp(city, places[j].name, len)==0 && places[j].name[len]==','){
found=1;
printf("lat = %f, long = %f",places[j].latitude,places[j].longitude);
break;
}
}
if(!found)
printf("City not found");

How do I search through a structure and display certain info after it has been entered by the user?

For my assignment I am to create a structure that allows the user to enter student info (ID, DOB, & Phone number). I have no problem doing this that is quite simple. Now I need to search through that enter info using the student ID to display that students corresponding DOB and phone number, this is the problem that I am having trouble working with. If you see any other problems with my program please let me know what is wrong and why I should change so I can learn from my mistakes.
Thank you.
#include <stdio.h>
#include <stdlib.h>
struct infoStruct
{
int studentID;
int year;
int month;
int day;
int phone;
int end;
};
int main (void)
{
int students = 0;
int infoArray [students];
struct infoStruct info;
int studentID;
int year;
int month;
int day;
int phone;
int end;
while (info.end != -1) {
students = students + 1;
printf("Enter student information (ID, day, month, year, phone)\n");
printf("Enter -1 following the phone number to end the process to continue enter 0\n");
scanf("%d %d %d %d %d %d", &info.studentID, &info.day, &info.month, &info.year, &info.phone, &info.end);
}
if (info.end = -1){
printf("You entered %d student(s)\n", students);
}
//Student Search
printf("Please enter the student ID of the student your looking for\n.");
scanf("%d", info.studentID);
printf(" DOB: %d %d %d, Phone: %d", info.month, info.day, info.year, info.phone);
}
info.end is not initialized before while (info.end != -1). Initiliaze all your variable (studentID...) and structure.
if (info.end = -1) is an assignment !
Use : if (info.end == -1) I prefer to use if (-1 == info.end) (if you had use : only = instead of == you would have get an error). (Yoda trick ^^)
And you have to use an array of struct in order to save every student (because you are continuously erasing the previous student information).
It's your homework, I won't do the work for you ;)
I'll leave most of the coding to you, as this is homework, but here is what you need to change to get this to work.
First of all, if you want to store multiple students info is going to need to be an array
static int MAX_STUDENTS = 50;
struct infoStruct info[MAX_STUDENTS];
and then you scan each student into a seperate part of the struct
scanf("%d %d %d %d %d %d", &info[students-1].studentID, &info[students-1].day, &info[students-1].month, &info[students-1].year, &info[students-1].phone, &info[students-1].end);
then you need to ensure that the end condition is checked properly (check the latest info[x].end)
It would also be wise to check you still have some room in the array before trying to add more.
with those done you are storing the students correctly.
as for searching, you need to scan the id to search into a seperate int.
then loop through the array (info[x]) and search each element's studentID against the search ID. When you have a match, print it out.
Edit:
its also worth considering storing the phone number as a "string" rather than an int, alot of phone numbers start with "0", but an int would remove the 0.
(so the phone number 012345, would become, 12345)

Resources