I have a struct in this form:
typedef struct student{
double student_no;
char name[50];
char surname[50];
double phone_no;
char mail[50];
};
struct student person[100];
printf("Student's mail address: ");
scanf("%s", person[i].mail); //i use codeblocks and it works without the sign &
First I create an array of mails. Then I get a mail for user, then check if it is in my array that I created in the first place. I have to do it without strcmp(), and that's where I get stuck. Here is what I've tried so far:
char *e1, *e2;
int comp;
typedef struct info{
char email[50];
};
struct info mailaddress[0];
printf("Enter the mail address to search: ");
scanf("%s", mailaddress[0]);
for (int i = 0; i < u; i++) {
for (int j = i + 1; j < u; j++) {
e1 = person[i].mail;
e2 = mailaddress[j].email;
comp = 0;
while (*e1 && *e2) {
if (*e1 != *e2) {
comp = *e1 - *e2;
break;
}
++e1;
++e2;
}
if (comp == 0)
printf("%s\t %s %15.lf %15.lf %s\n",
person[i].name,
person[i].surname,
person[i].student_no,
person[i].phone_no,
person[i].mail);
}
}
Try like this
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>
#define NO_MAX 20
#define NAME_MAX 20
#define SURNAME_MAX 20
#define PHONE_NO_MAX 20
#define MAIL_NO_MAX 50
struct student{
char student_no[NO_MAX + 1];
char name[NAME_MAX + 1];
char surname[SURNAME_MAX + 1];
char phone_no[PHONE_NO_MAX + 1];
char mail[MAIL_NO_MAX + 1];
struct student *ptr_next;
};
struct student *ptr_head = NULL;
struct student *ptr_position;
void enter_item(char *ptr_label, char *ptr_result, int max){
// enter item until pressed enter to finished
char tmp[256];
do {
printf("%s: ", ptr_label);
gets(tmp);
} while((strlen(tmp) > max));
strcpy(ptr_result, tmp);
}
void enter_list(void) {
char more;
struct student *ptr_new;
do{
// order dynamic memory
ptr_new = (struct student *) malloc(sizeof(struct student));
if(ptr_new) {
// enter item
enter_item("student_no", ptr_new->student_no, NO_MAX);
enter_item("name", ptr_new->name, NAME_MAX);
enter_item("surename", ptr_new->surname, SURNAME_MAX);
enter_item("phone_no", ptr_new->phone_no, PHONE_NO_MAX);
enter_item("mail", ptr_new->mail, MAIL_NO_MAX);
// next item
ptr_new-> ptr_next = ptr_head;
ptr_head = ptr_new;
// enter item again or not
printf("- again(Y/N)? -");
do{
more = toupper(getch());
} while(!(more=='Y' || more=='N'));
printf(" %c\n\n", more);
}
else {
printf("Memory isn't enough!\n");
break;
}
} while(more == 'Y');
}
void search_mail() {
// enter mail
struct student *ptr_search;
ptr_search = (struct student *) malloc(sizeof(struct student));
enter_item("mail searching", ptr_search->mail, MAIL_NO_MAX);
char *mail = ptr_search->mail;
// searching mail
ptr_position = ptr_head;
while(ptr_position) {
if(strcmp(mail, ptr_position->mail) != 0) {
ptr_position = ptr_position-> ptr_next;
}
else {
printf("Email is found\n");
return;
}
}
printf("Email isn't found!\n");
}
int main()
{
enter_list();
search_mail();
return 0;
}
Result:
bool streq(char *a, char *b)
{
while (*a && *b && *a != *b)
a++, b++;
return !*a && !*b;
}
Related
I have project in school where in need to make a struct of AirportManager which holds the amount of airports and an array of Airport (another struct). I started writing the code but I having trouble with the malloc of the array of airports.
I attahced to code I write so far, the problem I have is that the values dont saved in the airportArray in the AirportManager.
//AirportManger Struct
typedef struct {
Airport* airportArray;
int airportAmount;
}AirportManager;
void initAirportManager(AirportManager* airportManager)
{
airportManager->airportAmount = 0;
airportManager->airportArray = (AirportManager*)malloc(0);
}
void addAirport(AirportManager* airportManager)
{
Airport airport;
printf("Enter Airport Name: ");
scanf("%s", airport.airportName);
printf("Enter Airport Address: ");
scanf("%s", airport.airportAddress);
airportManager->airportAmount++;
airportManager->airportArray = (Airport*)realloc(airportManager->airportArray, airportManager->airportAmount * sizeof(Airport));
airportManager->airportArray = airport;
}
//Airport Struct
typedef struct {
char airportName[MAX];
char airportAddress[MAX];
}Airport;
//Main
AirportManager airportManager;
initAirportManager(airportManager);
addAirport(&airportManager);
The code has some issues. We shouln't:
allocate zero bytes with malloc(0)
assign twice to airportManager->airportArray
use scanf
Here is the code modified. It uses malloc and realloc better, and fgets instead of scanf.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZ 512
typedef struct {
char airportName[SIZ];
char airportAddress[SIZ];
} Airport;
typedef struct {
Airport* airportArray;
int airportAmount;
} AirportManager;
// Call first on AirportManager
void initAirportManager(AirportManager* airportManager)
{
airportManager->airportAmount = 0;
airportManager->airportArray = NULL;
}
// Call last on AirportManager
void finalAirportManager(AirportManager* airportManager)
{
airportManager->airportAmount = 0;
if (airportManager->airportArray != NULL)
free(airportManager->airportArray);
airportManager->airportArray == NULL;
}
// Add an airport to the manager
void addAirportByNameAndAddress(AirportManager* airportManager, char *name, char *address)
{
// Calculate the amount of memory needed
size_t mem = (airportManager->airportAmount + 1) * sizeof(Airport);
// Get the memory required
Airport* newAirports = NULL;
if (airportManager->airportArray == NULL)
newAirports = (Airport*)malloc(mem);
else
newAirports = (Airport*)realloc(airportManager->airportArray, mem);
if (newAirports == NULL)
{
// error: out of memory
return;
}
// Copy the name and the address to new the new Airport
Airport *current = newAirports + airportManager->airportAmount;
memset(current->airportName, '\0', SIZ);
strncpy(current->airportName, name, SIZ - 1);
memset(current->airportAddress, '\0', SIZ);
strncpy(current->airportAddress, address, SIZ - 1);
// Update the manager
airportManager->airportAmount++;
airportManager->airportArray = newAirports;
}
void addAirport(AirportManager* airportManager)
{
char name[SIZ] = { 0 };
char address[SIZ] = { 0 };
printf("Enter Airport Name: ");
fgets(name, SIZ - 1, stdin);
printf("Enter Airport Address: ");
fgets(address, SIZ - 1, stdin);
addAirportByNameAndAddress(airportManager, name, address);
}
void main() {
AirportManager airportManager;
initAirportManager(&airportManager);
addAirport(&airportManager);
finalAirportManager(&airportManager);
}
I want to do structer array but I don't know structer array size therefore I need to use pointer structer and I want to do char array in the structer and I don't know char array size therefore I need to use pointer char in this structer but I don't understand malloc and realloc functions. How can I do this ?
#include <stdio.h>
#include <stdlib.h>
struct School{
char *school_name;
int student_size;
}*high_school;
void createSchool(struct School *s, char *schl_name, int student, int school_size)
{
int i = 0;
if(school_size == 1){
s = (struct School*) malloc(sizeof(struct School));
}
else{
s = (struct School*) realloc(s, (school_size*sizeof(struct School)));
}
(s+(school_size-1))->student_size = student;
(s+(school_size-1))->school_name = (char *) malloc(20); // 20 it is not important
(s+(school_size-1))->school_name = schl_name;
for(i; i<school_size; i++){
printf("%s\t%d\n",(s+i)->school_name, (s+i)->student_size);
}
printf("\n\n");
}
int main()
{
int i = 1;
createSchool(high_school, "Harvard", 50, i);
i++;
createSchool(high_school, "Oxford", 40, i);
i++;
createSchool(high_school, "MIT", 30, i);
}
I want to do screen shoot:
Harvard 50
Harvard 50
Oxford 40
Harvard 50
Oxford 40
MIT 30
but screen shoot of program :
Harvard 50
└1q 7405760
Oxford 40
7405760
(null) 0
MIT 30
Your pointer inside createSchool has local scope, so global pointer is not modified. Faster fix is to return new allocated memory back to caller.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct School{
char *school_name;
int student_size;
}*high_school;
struct School* createSchool(struct School *s, char *schl_name, int student, int school_size)
{
if(school_size == 1)
{
s = malloc(sizeof(struct School));
}
else
{
s = realloc(s, (school_size*sizeof(struct School)));
}
if (s != NULL)
{
s[school_size-1].student_size = student;
s[school_size-1].school_name = malloc(strlen(schl_name)+1);
strcpy(s[school_size-1].school_name, schl_name);
for(int i=0; i<school_size; i++)
{
printf("%s\t%d\n", s[i].school_name, s[i].student_size);
}
printf("\n\n");
}
return s;
}
int main(void)
{
int i = 1;
high_school = createSchool(high_school, "Harvard", 50, i);
i++;
high_school = createSchool(high_school, "Oxford", 40, i);
i++;
high_school = createSchool(high_school, "MIT", 30, i);
}
Minimal signature for main is int main (void)
Take note that malloc/realloc returned value have to be checked.
With your code, in case of realloc fails, you are loosing the pointer to the already allocated memory. So you should use a temp pointer to store the realloc result and check for integrity. After that you can reassign it ot your pointer.
struct School* createSchool(struct School *s, char *schl_name, int student, int school_size)
{
if(school_size == 1){
s = malloc(sizeof(struct School));
}
else
{
struct School *temp = realloc(s, (school_size*sizeof(struct School)));
if (temp == NULL)
return s;
s = temp;
}
if (s != NULL)
{
s[school_size-1].student_size = student;
s[school_size-1].school_name = malloc(strlen(schl_name)+1);
strcpy(s[school_size-1].school_name, schl_name);
for(int i=0; i<school_size; i++)
{
printf("%s\t%d\n", s[i].school_name, s[i].student_size);
}
printf("\n\n");
}
return s;
}
Different solution can be implemented using double pointer:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct School{
char *school_name;
int student_size;
}*high_school;
void createSchool(struct School **s, char *schl_name, int student, int school_size)
{
if(school_size == 1)
{
*s = malloc(sizeof(struct School));
}
else
{
struct School *temp = realloc(*s, (school_size*sizeof(struct School)));
if (temp == NULL)
return;
*s = temp;
}
if (*s != NULL)
{
(*s)[school_size-1].student_size = student;
(*s)[school_size-1].school_name = malloc(strlen(schl_name)+1);
strcpy((*s)[school_size-1].school_name, schl_name);
for(int i=0; i<school_size; i++)
{
printf("%s\t%d\n", (*s)[i].school_name, (*s)[i].student_size);
}
printf("\n\n");
}
}
int main(void)
{
int i = 1;
createSchool(&high_school, "Harvard", 50, i);
i++;
createSchool(&high_school, "Oxford", 40, i);
i++;
createSchool(&high_school, "MIT", 30, i);
}
Last thing take note that,to assign the name of school you can simply use:
(*s)[school_size-1].school_name = schl_name;
Alright sorry for creating another question but the last one got overwhelmed and chaotic.
So I'm making a hash table which inserts words from a file (tokens) and after I have inserted them I need to sort them. The program template was given, the only functions that weren't complete were : insert_ht() , clear_ht() and compare. Even though I've done tons of search about qsort with compare, the program doesn't sort the frequencies (number of times each word was inserted) . I want em sorted from the highest to lowest.
Here is the code : "note that i shouldn't change any function except insert_ht() , clear_ht() and compare
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZ 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* link;
struct node { char *token; int freq; link next; };
link htable[HTABLE_SIZ] = { NULL }; /* Table of lists (#buckets) */
int size = 0; /* Size (number of elements) of hash table */
unsigned int hash (char *tok );
void insert_ht (char *data);
void clear_ht ( );
void print_ht ( );
void Process(FILE *fp);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
printf("prin tin for \n");
for (i=1; i < argc; i++)
{
printf("prin tin fopen \n");
fp = fopen(argv[i],"r");
if (NULL == fp)
{
fprintf(stderr,"Problem opening file: %s\n",argv[i]);
continue;
}
printf("prin tin process \n");
Process(fp);
fclose(fp);
}
print_ht();
//clear_ht();
return 0;
}
void Process(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n";
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL)
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators)){
printf("prin tin insert %s \n",s);
insert_ht(s);
}
}
}
/* Hash Function */
unsigned int hash(char *tok)
{
printf("bike stin hash \n");
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
printf("VGAINEIIIIIIIIIIIIII %d \n",hv);
return hv % HTABLE_SIZ;
}
void insert_ht(char *token)
{
printf("bike stin insert %s \n",token);
unsigned int hashval = hash(token);
struct node *new_list;
if (htable[hashval]==NULL){
printf("mesa stin prwti if %u %s \n",hashval,token);
//token = strdup(token);
new_list = malloc(sizeof(link));
new_list->token = strdup(token) ;
new_list->freq = 1;
new_list->next = htable[hashval];
htable[hashval] = new_list;
size++;
}else {
htable[hashval]->freq++;
}
printf("ta evale epitixws \n");
}
void clear_ht()
{
int i;
for(i=0; i<HTABLE_SIZ; i++) {
while(htable[i]->token!=NULL) {
htable[i]->token=NULL;
htable[i]->freq=NULL;
free(htable[i]);
}
}
}
int compare(const void *elem1, const void *elem2)
{
const struct node *p1 = elem1;
const struct node *p2 = elem2;
if (p1->freq > p2->freq)
return(+1);
else if (p1->freq < p2->freq)
return(-1);
else
return(0);
}
void print_ht()
{
int i, j=0;
link l, *vector = (link*) malloc(sizeof(link)*size);
for (i=0; i < HTABLE_SIZ; i++)
for (l=htable[i]; l; l=l->next)
vector[j++] = l;
qsort(vector,size,sizeof(link),compare);
for (i=0; i < size; i++)
printf("%-50s\t%7d\n",vector[i]->token,vector[i]->freq);
free(vector);
}
Ι found the solution. Apparently for some reason my compare function was wrong.
I still haven't figured out why but here is the correct one, hopefully someone else will find this post helpful!
int compare(const void *elem1, const void *elem2)
{
return (*(link*)elem2)->freq - (*(link*)elem1)->freq;
}
I'm trying to make a queue that dynamically increases by it's size by 3 when it reaches the size of 3 the first time. I haven't used malloc or realloc that much, but afaik they should be correct in the code
**Header:**
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
typedef char Titem;
/*The interface of queue */
#define MAXN 3
typedef enum {NOT_OK, OK } Tboolean;
typedef struct {
Titem array[MAXN];
int number_of_items;
} Tqueue;
void initialize_queue (Tqueue *Pqueue);
Tboolean enqueue( Tqueue *p, Titem item);
Tboolean dequeue( Tqueue *p, Titem *Pitem);
void print_queue(const Tqueue *Pqueue);
**Queue functions:**
#include "jono.h"
void initialize_queue ( Tqueue *Pqueue) {
int size = 0;
Pqueue->number_of_items = 0;
*Pqueue->array = (Titem) calloc (MAXN, sizeof(MAXN));
size = sizeof (Pqueue->array);
printf ("%d\n", size);
}
Tboolean enqueue( Tqueue *Pqueue, Titem item) {
int size = 0;
if (Pqueue->number_of_items >= MAXN) {
*Pqueue->array = (Titem) realloc (Pqueue->array, sizeof(Pqueue->array) + MAXN);
size = sizeof (Pqueue->array);
printf ("\%d", size);
Pqueue->array[Pqueue->number_of_items++] = item;
return(OK);
}
else {
Pqueue->array[Pqueue->number_of_items++] = item;
return (OK);
}
}
Tboolean dequeue( Tqueue *Pqueue, Titem *Pitem) {
int i;
if (Pqueue->number_of_items == 0)
return(NOT_OK);
else {
*Pitem = Pqueue->array[0];
for (i = 0 ; i < Pqueue->number_of_items-1 ; i++)
Pqueue->array[i] = Pqueue->array[i+1];
Pqueue->number_of_items--;
return (OK);
}
}
void print_queue (const Tqueue *Pqueue) {
int i;
printf("\nQueue now: \n\n");
for (i = 0 ; i < Pqueue->number_of_items ; i++ ) {
printf(" %c ", Pqueue->array[i]);
}
printf("\n\n");
}
**Main:**
#include "jono.h"
int main(void) {
Tqueue queue;
Tboolean succeed;
char chr;
initialize_queue(&queue);
printf("\nEnter a letter to be queued ");
printf("\nor digit 1 to dequeue a letter");
printf("\nor Return to quit a program\n");
chr = _getche();
while (chr != 10 && chr != 13) {
if (isalpha(chr)) {
succeed=enqueue(&queue, chr);
print_queue(&queue);
if (!succeed)
printf("\n Enqueue operation failed\n");
}
if (chr == '1') {
succeed = dequeue(&queue, &chr);
if (succeed) {
printf("\na letter dequeued %c ", chr);
print_queue(&queue);
}
else printf("\nDequeue operation failed\n ");
}
chr = _getche();
}
}
typedef struct {
Titem array[MAXN]; /* char array[3] */
int number_of_items;
} Tqueue;
*Pqueue->array = (Titem) calloc (MAXN, sizeof(MAXN));
You can not reserve space for an array (only pointers can use (m/c/re)alloc)
Can anyone give me some indication as to why array of structs doesn't print out properly ?
I think its something to do with the memory I have allocated to the struct I am unsure !!
Using mac osx mountain lion xcode 4 gcc
Thanks for any help completely stuck!!
(Please have patience I am only a student !)
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
typedef struct{
char* one;
char* two;
} Node;
Node *nodes;
int count = 0;
//-----------------------------------------------------------------------
void add(char *one,char*two){
char x[40];
char y[40];
printf("reached..\n");
strcpy(x,one);
strcpy(y,two);
printf("--> X: %s\n",x);
printf("--> Y: %s\n",y);
Node newNode;
newNode.one = x;
newNode.two = y;
nodes[count]= newNode;
count++;
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void print(){
int x;
for (x = 0; x < 10; x++)
{
printf("%d : (%s, %s) \n",x,nodes[x].one, nodes[x].two);
}
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void check(char **arg)
{
if(strcmp(*arg, "Add") == 0)
{
add(arg[1],arg[2]);
}else if(strcmp(*arg,"print") == 0)
{
print();
}else{
printf("Error syntax Enter either: \n Add [item1][item2]\n OR \n print\n");
}
}
//-----------------------------------------------------------------------
void readandParseInput(char *line,char **arg)
{
if (fgets (line, 512, stdin)!= NULL) {
char * pch;
pch = strtok (line," \n\t");
int count = 0;
arg[0] = pch;
while (pch != NULL)
{
count++;
pch = strtok (NULL, " \n\t");
arg[count] =pch;
}
}else{
printf("\n");
exit(0);
}
}
//-----------------------------------------------------------------------
int main()
{
int size = 100;
nodes = calloc(size, sizeof(Node));
int i;
for(i = 0;i <100; i++){
printf("%s , %s \n",nodes[i].one,nodes[i].two );
// nodes[i].one = ".";
// nodes[i].two = ".";
}
char line[512]; /* the input line */
char *arg[50]; /* the command line argument */
while (1)
{
readandParseInput(line,arg);
if(arg[0] != NULL){
check(arg);
}
}
return(0);
}
You're keeping pointers to the following automatic variables:
char x[40];
char y[40];
These go out of scope when add() returns, leaving you with dangling pointers.
You either have to turn Node::one and Node::two into arrays, or allocate memory for them on the heap.
In you add() function, you cannot assign one struct to another via an = operator... you would have to copy it...
memcpy( &nodes[count], &newNode )
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *fn;
}NAME;
#define NAME_LEN 20
int main()
{
NAME name;
name.fn = (char *) calloc(NAME_LEN, sizeof(char));
strcpy(name.fn, "Namco");
printf("Name: %s\n", name.fn);
free(name.fn);
return 0;
}
you can't just assign a string like this in c
newNode.one = x;
newNode.two = y;
what is newNode.one referring to???
at Function add
newNode.one = x;
newNode.two = y;
to
newNode.one = strdup(x);
newNode.two = strdup(y);