Access Violation error in Pointers in C - c

This is the simple function month_day which converts the day of the year into the month and day. This is from the C tutorial with some modifications.
I dont know,when I run this I get
"....... Access violation at address 004011DD ....." error stopping at
*month=i; //in daytellerlib.c file.
This is the complete program in the two files. File 1:
#include<stdio.h>
#include<conio.h>
#include"daytellerlib.c"
int main()
{
int dayyear,year;
int *pday=0;
int *pmonth=0;
dayyear=99;
year=2011;
month_day(dayyear,year,pmonth,pday);
printf("dayyear=%d YEar=%d day=%d month=%d \n",dayyear,year,*pday,*pmonth);
getch();
return 0;
}
File 2:
void month_day(int day,int year,int *,int *);
static table[2][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
void month_day(int dayyear,int year,int *month,int *day)
{
int i=1,count=0,leap;
leap = year%4 == 0 &year%100 != 0 || year%400 == 0;
for(;dayyear>(count+=table[leap][i]);i++)
;
*month=i;
*day=dayyear+table[0][i]-count;
}
I know this is because we are accessing the pointer which has some other address.

When you call month_day() you are passing pointers to ints which have no ints associated with them.
int day;
int month;
int * pday = &day;
int * pmonth = &month;
or more simply
int day;
int month;
month_day(dayyear, year, &month, &day);
Update: as #Eran Zimmerman points out, you should use && (logical AND) instead of & (bitwise AND) when calculating leap.

Related

adding a int from a struct pointer

I'm trying to increase the day of a date struct in C. I keep getting a return where the memory seems to be adding [not the actual int day in the struct].
For example, if I INPUT:
2018 10 2
I should get
OUTPUT:
10/03/2018
INSTEAD, I GET:
32594/10/-352487872
I believe I'm not using pointers correctly in the method: advanceDay(struct date d)
#include <stdio.h>
struct date {
int year;
int month;
int day;
};
/* function prototypes */
void printDate(struct date);
void readDate(struct date *);
struct date advanceDay(struct date);
int main(void) {
struct date today, tomorrow;
readDate(&today);
printDate(today);
tomorrow = advanceDay(today);
printDate(tomorrow);
return 0;
}
/* add your function definitions here */
void printDate(struct date d) {
printf("%02d/%02d/%04d\n", d.month, d.day, d.year);
}
void readDate(struct date *d){
scanf("%d %d %d", &(d->year), &(d->month), &(d->day));
}
struct date advanceDay(struct date d) {
d.day = d.day+1;
}
I've tried to change
d.day = d.day+1;
to
d.day = (*d.day)+1;
But I get an error. I've tried the -> and also moving around the *
Note that advanceDay doesn't explicitly return anything, resulting in undefined behavior (and probably reading uninitialized memory - the compiler should have warned you about it).
Instead, you could pass a struct date* to the function, and update it in place:
void advanceDay(struct date * d) {
d->day = d->day + 1;
}
Note that your main also needs to change accordingly:
int main(void) {
struct date today;
readDate(&today);
printDate(today);
advanceDay(&today); /* no retrun value here */
printDate(today); /* today was updated in-place */
return 0;
}
You declare advanceDay to return a value, but you don't return anything. You invoke undefined behavior by failing to return a value from this function and then subsequently attempting to use the return value.
Create a copy of the passed in struct date, perform the operation on the copy, and return it.
struct date advanceDay(struct date d) {
struct date nextDay;
nextDay.day = nextDay.day+1;
return nextDay;
}

Program received signal SIGTRAP when I return 2 structs

Im trying to read these 2 files and store its content into 2 differents structs so my program dont need to be reading it over and over again, the problem is when I try to run both structs the program crashes, when I try to debug it, it shows the title's error, however if I try to run only the products file or the sells file it works fine and shows the result.
The code:
#include <stdlib.h>
#include <stdio.h>
typedef struct sellsFile{
int year, month, day, code;
float sell_amount, price;
}sells;
typedef struct productsFile{
int code;
float stock_amount, uni_price, profit;
char type;
}products;
productsFile *read_productsFile(int *q);
sellsFile *read_sellsFile(int *q);
int main(){
int productsSize, sellsSize;
products *v_products;
sells *v_sells;
v_products = read_productsFile(&productsSize);
for(int cont=0;cont<productsSize;cont++){
printf("%d;%c;%.2f;%.2f;%.2f;\n",v_products[cont].code, v_products[cont].type,v_products[cont].stock_amount,v_products[cont].uni_price,v_products[cont].profit);
}
printf("\n\n\n");
v_sells = read_sellsFile(&sellsSize);
for(int cont=0;cont<sellsSize;cont++){
printf("%d/%d/%d %d %.2f %.2f\n",v_sells[cont].year,v_sells[cont].month,v_sells[cont].day,v_sells[cont].code,v_sells[cont].sell_amount,v_sells[cont].price);
}
}
productsFile *read_productsFile(int *q){
(*q) = 0;
FILE *archive;
products *result;
int code;
float stock_amount, uni_price, profit;
char type;
archive = fopen("products.txt", "r");
while(fscanf(archive,"%d;%c;%f;%f;%f;",&code,&type,&stock_amount,&uni_price,&profit) != EOF){
(*q)++;
result = (products *)realloc(result, sizeof(products) * (*q));
result[(*q)-1].code = code;
result[(*q)-1].type = type;
result[(*q)-1].stock_amount = stock_amount;
result[(*q)-1].uni_price = uni_price;
result[(*q)-1].profit = profit;
}
return(result);
}
sellsFile *read_sellsFile(int *q){
int year, month, day, code;
float sell_amount, price;
sells *result;
*q = 0;
FILE *archive;
archive = fopen("sells.txt","r");
while(fscanf(archive,"%d;%d;%d;%d;%f;%f;",&year,&month,&day,&code,&sell_amount,&price) != EOF){
(*q)++;
result = (sells *)realloc(result,sizeof(sells) * (*q));
result[(*q)-1].year = year;
result[(*q)-1].month = month;
result[(*q)-1].day = day;
result[(*q)-1].code = code;
result[(*q)-1].price = price;
result[(*q)-1].sell_amount = sell_amount;
}
return(result);
}
Example of produts file:
12100;P;17.400;2.30;38.80;
12200;P;25.000;23.70;13.58;
12300;P;16.090;17.48;12.75;
Example of sells file:
2015;1;1;15800;114.000;5.07;
2015;1;1;15600;9.000;9.79;
2015;1;1;12800;32.483;9.71;
Give the uninitialized value of result from this line of code:
sells *result;
this code results in undefined behavior:
result = (sells *)realloc(result,sizeof(sells) * (*q));
as results starts with an unknown value.

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 */ }
}

scanf a structure from a function, call from same function to scan other structures

Im trying to scanf a structure from file input within a function, and print it using another function.
Ultimately I need to be able to print out the same information that I would from the code that I commented out, but doing so from the functions I have listed in the function prototypes declaration area. I only un-commented 2 of those so I could try baby steps to get something to scan and print using functions. The functions themselves are located at the very bottom.
To finish the scan_auto function, somehow I need to scanf 2 other structures that are part of the main structure. I assume I need to call the functions scan_date and scan_tank from scan_auto, however I am unsure how to do that properly.
Here is the code I have so far...
#include <stdio.h>
#define STRSIZE 20
/* Structure definitions */
typedef struct {
int month,
day,
year;
} date_t;
typedef struct {
double capacity,
current;
} tank_t;
typedef struct {
char make[STRSIZE],
model[STRSIZE];
int odometer;
date_t manuf,
purch;
tank_t tank;
} auto_t;
/* Function prototypes */
/*
int scan_date(date_t *date);
int scan_tank(tank_t *tank);
*/
int scan_auto(auto_t *vehicle, FILE *inp);
/*
void print_date(date_t date);
void print_tank(tank_t tank);
*/
void print_auto(auto_t vehicle);
int main()
{
auto_t vehicle;
int number=0,
i=0,
status=1;
FILE *inp = fopen("autos.txt","r"); /* defining file input */
/* Check to make sure input file is found and readable. */
if(inp==NULL){
printf("Error: Input file - autos.txt - not found!\n");
getch();
return 0;
}
printf("Vehicle Vehicle Odometer Date Date Tank Current\n");
printf("Make Model Reading Purchased Manufactured Capacity Fuel Level\n");
printf("\n----------------------------------------------------------------------------\n\n");
/*******************COMMENTED OUT*************************************
while(status>0){
status=fscanf(inp, "%s%s%d%d%d%d%d%d%d%lf%lf", vehicle.make,
vehicle.model,
&vehicle.odometer,
&vehicle.manuf.month,
&vehicle.manuf.day,
&vehicle.manuf.year,
&vehicle.purch.month,
&vehicle.purch.day,
&vehicle.purch.year,
&vehicle.tank.capacity,
&vehicle.tank.current);
if(status==11){
printf("%-10s%-9s%-10d%2d/%d/%-6d%2d/%d/%-8d%-11.1lf%.1lf\n", vehicle.make,
vehicle.model,
vehicle.odometer,
vehicle.manuf.month,
vehicle.manuf.day,
vehicle.manuf.year,
vehicle.purch.month,
vehicle.purch.day,
vehicle.purch.year,
vehicle.tank.capacity,
vehicle.tank.current);
i++;}
else if(status <11 && status>0){
printf("\nInvalid Input - The next line of data is corrupt.\n");
}
}
******************************************************************************/
scan_auto(&vehicle, inp);
print_auto(vehicle);
/*
print_auto(vehicle);
*/
getch();
return 0;
}
/*********************************************************************************/
int scan_date(date_t *date)
{
int result;
result=scanf("%d%d%d", &(*date).month,
&(*date).day,
&(*date).year);
if (result==3)
result=1;
else if(result !=EOF)
result=0;
return (result);
}
/*********************************************************************************/
double scan_tank(tank_t *tank)
{
int result;
result=scanf("%lf%lf", &(*tank).capacity,
&(*tank).current);
if (result==2)
result=1;
else if(result !=EOF)
result=0;
return (result);
}
/*********************************************************************************/
int scan_auto(auto_t *vehicle, FILE *inp)
{
int result;
result=fscanf(inp, "%s%s%d", (*vehicle).make,
(*vehicle).model,
&(*vehicle).odometer);
if (result==3)
result=1;
else if(result !=EOF)
result=0;
return (result);
}
/*********************************************************************************/
void print_auto(auto_t vehicle)
{
printf("%-10s%-9s%-10d", vehicle.make,
vehicle.model,
vehicle.odometer);
}
The text file (autos.txt) I am using....
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
however I am unsure how to do that properly.
Can you elaborate on what you're unsure? If you're not sure how to assign value to struct member of struct, perhaps this sample code will help you? I combined all of the things together...
Oh, and I changed your *vehicle to *v to make it shorter and easier to read.
Also, since you're accessing member of struct pointer, why don't you use v->xxx instead of (*v).xxx ?
UPDATE 1: You asked how to do it separately. Here it is:
int scan_date(date_t *date, FILE *inp)
{
int result = fscanf(
inp,
"%d%d%d",
&(date->day),
&(date->month),
&(date->year));
return (result == 3);
}
int scan_tank(tank_t *tank, FILE *inp)
{
int result = fscanf(
inp,
"%lf%lf",
&(tank->capacity),
&(tank->current));
return (result == 2);
}
int scan_auto(auto_t *v, FILE *inp)
{
int result = fscanf(
inp,
"%s%s%d",
v->make,
v->model,
&(v->odometer));
result += scan_date(&(v->purch), inp);
result += scan_date(&(v->manuf), inp);
result += scan_tank(&(v->tank), inp);
return (result == 11); // return 0 if true
}

scanf doesn't store proper information in structure

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!

Resources