I'm not sure if I'm asking the right question. lets say we have the following
typedef struct {
char month[2];
char day[2];
char year[4];
} dateT;
void dates(dateT* ptrDateList);
int main()
{
dateT* ptrList;
scanf("%d", &n);//number of date entries
ptrList = malloc(n*sizeof(dateT));
for (i=0; i<n; i++)
dates(&ptrList[i]);
}
void dates(dateT* ptrDateList);
{
char inputMonth[2];
char inputDay[2];
char inputYear[4];
scanf("%s",inputMonth);
strcpy(ptrDateList->month,inputMonth);
scanf("%s",inputDay);
strcpy(ptrDateList->day,inputDay);
scanf("%s",inputYear);
strcpy(ptrDateList->year,inputYear);
}
how you compare the value of day in ptrList[2] with lets say the value of day in ptrList[5]
I know that if I did
dateT list2={5,10,2009};
dateT list5={7,10,2009};
I could do
list2.day == list5.day
but how would I do that with the arrays
ptrList[2].day == ptrList[5].day would work if the type was say integer, but as you store the characters you might want to use strcmp, like so:
if ((strcmp(ptrList[2].day,ptrList[5].day) == 0) // same day
note that you need an extra character for the end of string sentinel \0,
so it should be;
typedef struct {
char month[3];
char day[3];
char year[5];
} dateT;
another issue is the way you handle input: can you be sure that the user will provide valid input? for instance you could use scanf("%2s", string); to input the day (of max. length two).
Here's pretty much what jev already explain. Just I thought I might as well post it, since it works.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char month[3];
char day[3];
char year[5];
} dateT;
void dates(dateT* ptrDateList);
int main()
{
dateT* ptrList;
int i, n;
printf("Enter number of dates: ");
scanf("%d", &n);//number of date entries
ptrList = malloc(n*sizeof(dateT));
for (i=0; i<n; i++)
dates(&ptrList[i]);
if (n > 1) {
if (!strcmp(ptrList[0].day,ptrList[1].day)) {
printf("First two days match.\n");
} else {
printf("First two days don't match.\n");
}
}
return 0;
}
void dates(dateT* ptrDateList)
{
char inputMonth[3];
char inputDay[3];
char inputYear[5];
printf("Enter month: ");
scanf("%2s",inputMonth);
inputMonth[2] = '\0';
strcpy(ptrDateList->month,inputMonth);
printf("Enter Day: ");
scanf("%2s",inputDay);
inputDay[2] = '\0';
strcpy(ptrDateList->day,inputDay);
printf("Enter Year: ");
scanf("%4s",inputYear);
inputYear[4] = '\0';
strcpy(ptrDateList->year,inputYear);
}
Related
I'm trying to create an array of Product structs and then print the name and code of each Product in the array, but I keep getting a segmentation fault. I have tried to insert each value without a loop and then printing, and it works, but I'd like to automate it. The function fill_products fills the products array according to the user's input, and the select_products prints each name-code pair for the entire array.
This is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int code;
char *name;
float price;
} Product;
void select_products(Product *products, int len)
{
int i;
printf("%-30s%s\n", "Name", "Code");
for (i = 0; i < len; i++)
{
printf("%-30s%d\n", products[i].name, products[i].code);
}
return;
}
void fill_products(Product *products, int len)
{
int i, code;
char *name;
float price;
for (i = 0; i < len; i++)
{
printf("Insert product name (%d / %d): ", i + 1, len);
scanf("%s", &name);
printf("Insert product price (%d / %d): ", i + 1, len);
scanf("%f", &price);
products[i].code = i;
products[i].name = name;
products[i].price = price;
}
return;
}
int is_alloc(Product *products)
{
if (products == NULL)
{
printf("Error: memory allocation unsuccessful.\n");
}
return products != NULL;
}
int main(void)
{
int len, n_bytes;
Product *products;
printf("Insert length of array: ");
scanf("%d", &len);
n_bytes = sizeof *products * len;
products = malloc(n_bytes);
if(!is_alloc(products))
{
exit(0);
}
fill_products(products, len);
select_products(products, len);
free(products);
return 0;
}
I keep getting a segmentation fault.
Please enable compiler warnings, and pay attention to them.
This code:
char *name;
...
scanf("%s", &name);
is bogus and doesn't do at all what you intend.
You must either allocate space for name separately (and then not forget to free() it), or make that space available in the Product structure like so:
typedef struct
{
int code;
char name[100];
float price;
} Product;
(this assumes there is a reasonable limit on name length).
I am trying to free the memory allocated by my getSongInfo function, I have tried using a pointer to the function call but I get an error "cannt assign int to type int*" error. Any help would be great as the current way I have seems like it may work, but I might be completely wrong. Thanks!
Original Attempt:
int *memPtr = NULL
memPtr = getSongInfo(&fillPtr[arrayCounter], tempArtist[counter], tempSong[counter]);
Gives error!
Current Attempt:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
int getSongInfo(struct songInfo *pFillInfo, char *artistName, char *songName);
void printSongInfo(struct songInfo songList[10]);
struct songInfo {
char *songArtist;
char *songTitle;
};
int main(void)
{
struct songInfo *fillPtr;
struct songInfo songList[10];
fillPtr = &songList[0];
char tempArtist[10][30];
char tempSong[10][30];
int *memPtr = NULL;
int i = 0;
int counter = 0;
int arrayCounter = 0;
while (counter != 10)
{
printf("Please enter the artist name: ");
fgets(tempArtist[counter], sizeof(tempArtist[counter]), stdin);
tempArtist[counter][strcspn(tempArtist[counter], "\n")] = 0;
printf("Please enter the song name: ");
fgets(tempSong[counter], sizeof(tempSong[counter]), stdin);
tempSong[counter][strcspn(tempSong[counter], "\n")] = 0;
getSongInfo(&fillPtr[arrayCounter], tempArtist[counter], tempSong[counter]);
printf("Song and Artist Captured! \n");
counter++;
arrayCounter++;
}
printSongInfo(fillPtr);
free(fillPtr->songArtist);
free(fillPtr->songTitle);
}
int getSongInfo(struct songInfo *pFillInfo, char *artistName, char *songName)
{
pFillInfo->songArtist = (char*)malloc(strlen(artistName) + 1);
pFillInfo->songTitle = (char*)malloc(strlen(songName) + 1);
strcpy(pFillInfo->songArtist, artistName);
strcpy(pFillInfo->songTitle, songName);
return 1;
}
void printSongInfo(struct songInfo songList[10])
{
int counter = 0;
while (counter != 10)
{
printf("%-35s %-35s\n", songList[counter].songArtist, songList[counter].songTitle);
counter++;
}
}
Your getSongInfo function does not return a pointer, so attempting to put the return value into a variable and then free it is pointless. The pointers in question are inside the struct songInfo, specifically, the fillPtr variable (which is actually redundant, since songList and fillPtr point to the same location).
In addition, please be aware that strcspn will not always return a valid index. If it does not find a match, it will return the length of the first argument.
I think this is more like what you are trying to do:
int main(void)
{
const int numSongs = 10;
struct songInfo songList[numSongs];
char tempArtist[30];
char tempSong[30];
int i;
int newline_idx;
for (i = 0; i < numSongs; ++i)
{
printf("Please enter the artist name: ");
fgets(tempArtist, sizeof(tempArtist), stdin);
newline_idx = strcspn(tempArtist, "\n");
if (newline_idx < sizeof(tempArtist))
tempArtist[newline_idx] = 0;
printf("Please enter the song name: ");
fgets(tempSong, sizeof(tempSong), stdin);
newline_idx = strcspn(tempSong, "\n");
if (newline_idx < sizeof(tempSong))
tempSong[newline_idx] = 0;
getSongInfo(&songList[i], tempArtist, tempSong);
printf("Song and Artist Captured! \n");
}
for (i = 0; i < numSongs; ++i)
{
free(songList[i].songArtist);
free(songList[i].songTitle);
}
}
You might consider separating the code for free()ing each struct into its own function.
You might also consider heeding that compiler warning instead of ignoring it, as Bodo commented. Careless handling of strings from stdin is dangerous.
I am trying to create an array of structures containing some basic information. My code is as follows:
typedef struct {
char firstName[30];
char lastName[30];
char street[35];
char city[20];
char state[3];
int zip;
char phone[15];
int accountId;
} Customer;
int main(void) {
int i, customer_number, _zip, _accountId;
struct Customer customer_list[9];
char _firstName[30], _lastName[30], _street[35], _city[20], _state[3], _phone[15];
for (i = 0; i < 10; i++) {
customer_number = 0;
printf("Enter data for customer %d: \n", customer_number);
printf("Enter First Last Phone: ");
scanf("%s%s%s", &_firstName, &_lastName, &_phone);
printf("\nEnter Address (Street City State ZIP): ");
scanf("%s%s%s%d", &_street, &_city, &_state, &_zip);
Customer customer_list[i] = {[i].firstName = _firstName}
}
return 0;
}
It seems like this should work, however I am getting an error saying " i must have constant value" Can anyone push me in the right direction? Thank you!
Customer customer_list[i] = {[i].firstName = _firstName}
This line needs to be
strcpy(customer_list[i].firstName, _firstName);
EDIT: assignment should be done by strcpy()
I have an issue with my code, I changed a few of the functions to accomodate the structure I added, so instead of having variables all over the place, but now it does not work at all. I need it to create a structure person, then it prompts the user to enter the persons name, and age; then it asks for more persons to fill a doubly linked list which stops the loop if nothing is input for the persons name. THEN it spits out the reverse of what I input into the doubly linked list. All help is appreciated ^-^
struct person
{
char name[10][41];
int age[10];
};
int write(struct person *people);
void print(struct person *people);
int main(void)
{
char names[10][41];
int n = 10;
int ages[10];
typedef struct person people;
n = write(people);
print(people);
system("PAUSE");
return 0;
}
int write(struct person *people)
{
int i;
char name[41];
int age[10];
for(i=0; i<=i; i++)
{
fflush(stdin);
printf("Enter full name\n");
gets(people.name);
strcpy(names[i], name);
if(names[i][0] == '\0')
break;
printf("Enter their age\n");
scanf("%d", &age[i]);
ages[i] = age[i];
}
}
void print(struct person *people)
{
int i = 0;
for(i = 0; i < 10; i++)
{
if(names[i][0] == '\0')
break;
printf("%s is %d year(s) old\n", names[i], ages[i]);
}
return i;
}
You are passing the name of a type that you just defined instead of a variable declared of that type, this
typedef struct person people;
should be
struct person people;
Change
n = write(people);
to
n = write(&people);
Remove fflush(stdin) it's undefined behavior.
Do not use gets() it's very unsafe, use fgets() instead
char name[40];
gets(name);
should be
char name[40];
fgets(name, sizeof(name), stdin);
I have come across this wierd and mysterous (at least to me) error that I am finding a very hard time finding. It gives me an error at the line where I call my function input(student_list1[MAX], &total_entries); where the compiler says:
incompatible type for agument 1 in 'input'
What am I doing wrong here? I sense it something very simple and stupid but I have gone through the code several times now without any avail.
#define MAX 10
#define NAME_LEN 15
struct person {
char name[NAME_LEN+1];
int age;
};
void input(struct person student_list1[MAX], int *total_entries);
int main(void)
{
struct person student_list1[MAX];
int total_entries=0, i;
input(student_list1[MAX], &total_entries);
for(i=0; i<total_entries; i++)
{
printf("Student 1:\tNamn: %s.\tAge: %s.\n", student_list1[i].name, student_list1[i].age);
}
return 0;
} //main end
void input(struct person student_list1[MAX], int *total_entries)
{
int done=0;
while(done!=1)
{
int i=0;
printf("Name of student: ");
fgets(student_list1[i].name, strlen(student_list1[i].name), stdin);
student_list1[i].name[strlen(student_list1[i].name)-1]=0;
if(student_list1[i].name==0) {
done=1;
}
else {
printf("Age of student: ");
scanf("%d", student_list1[i].age);
*total_entries++;
i++;
}
}
}
struct person student_list1[MAX] in the function argument is actually a pointer to struct person student_list1.
student_list1[MAX] you passed is a (out of bound) member of the array struct person student_list1[MAX]. Valid array index shoudl be between 0 to MAX - 1.
Change it to:
input(student_list1, &total_entries);
Note that here the array name student_list1 is automatically converted to a pointer to student_list1[0].
There are many things wrong with the code; this is my attempt at making it somewhat more robust:
#include <stdio.h>
#include <string.h>
#define MAX 10
#define NAME_LEN 15
// use a typedef to simplify code
typedef struct person {
char name[NAME_LEN];
int age;
} person_t;
// size qualifier on student_list is redundent and person_t* does the same
void input(person_t *student_list, int *total_entries);
int main(void)
{
person_t student_list[MAX];
int total_entries, i;
// pass array and not the non-existent 'student_list[MAX]' element
input(student_list, &total_entries);
for(i=0; i<total_entries; i++)
{
// age is an int, not a string so use %d
printf("Student 1:\tName: %s.\tAge: %d.\n", student_list[i].name, student_list[i].age);
}
return 0;
} //main end
void input(person_t *student_list, int *total_entries)
{
int done = 0, i = 0;
*total_entries = 0;
while (i < MAX) {
printf("Name of student: ");
// use NAME_LEN instead of strlen(list[i].name) because latter is
// probably not initialized at this stage
if (fgets(student_list[i].name, NAME_LEN, stdin) == NULL) {
return;
}
// detect zero-length string
if (student_list[i].name[0] == '\n') {
return;
}
printf("Age of student: ");
scanf("%d", &student_list[i].age);
// read the newline
fgetc(stdin);
*total_entries = ++i;
}
}
input(student_list1[MAX], &total_entries); shoud be input(student_list1, &total_entries);.
In C,
void input(struct person student_list1[MAX], int *total_entries);
equals
void input(struct person *student_list1, int *total_entries);