Find person with surname that starts with character c using bsearch - c

I have problem finding what is wrong with my code down below. It compiles, but doesn't work properly. What it has to do is to find person with surname that starts with character c using bsearch.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[26];
char surname[26];
} Person;
int compare(const void *a, const void *b) {
char x = (*((Person*)a)).surname[0];
char y = (*((Person*)a)).surname[0];
if(x < y) return -1;
else if(x > y) return 1;
else return 0;
}
int main() {
Person array_person[]={{"Mike", "Anthony"},
{"Dave", "Eric"},
{"Danny", "Markle"},
{"Anne", "Redmayne"},
{"Lulu", "Rsu"}};
char c;
scanf("%c",&c);
Person *p;
p = (Person*)bsearch(&c,array_person,sizeof(array_person)/sizeof(Person),sizeof(Person),compare);
printf("%s %s",p->name, p->surname);
return 0;
}

The first argument to the call (the parameter 'a' ) needs to be the character c and not an instance of Person. Please see down here, I hope this will help.
int compare(const void *a, const void *b) {
char x = (*(char*)a);
char y = ((Person*)b)->surname[0];
if(x < y) return -1;
else if(x > y) return 1;
else return 0;
}
int main() {
Person array_person[]={{"Mike", "Anthony"},
{"Dave", "Eric"},
{"Danny", "Markle"},
{"Anne", "Redmayne"},
{"Lulu", "Rsu"}};
char c;
scanf("%c",&c);
Person *p;
p = (Person*)bsearch(&c,array_person,sizeof(array_person)/sizeof(Person),sizeof(Person),compare);
if( p==NULL )
printf("Not found\n");
else
printf("%s %s\n",p->name, p->surname);
return 0;
}
You need to note that, as you wrote the function, it will always find a person with surname starting with the given character rather than all persons. I am not sure whether this is what you are supposed to implement.

Related

I want to sort my struct by alphabetical order, but if i do the sort, my program doesn't give any output

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct kezdo
{
int mennyi;
char betu;
}KEZDO;
int main(int argc, char* argv[])
{
int j;
int i;
int db=0;
int volt=0;
char sajt[22];
FILE* f=fopen(argv[1], "r");
if(f==NULL)
{
fprintf(stderr, "Hiba a fajl megnyitasaban!");
}
int k = 20;
KEZDO t[k];
KEZDO tmp;
for(i=0;i<k;i++)
{
t[i].mennyi = 0;
}
while(fgets(sajt,22,f)!=0)
{
if(sajt[strlen(sajt)-1] == '\n')
{
sajt[strlen(sajt)-1] = '\0';
}
for(i=0;i<k;i++)
{
if(t[i].betu == toupper(sajt[0]))
{
t[i].mennyi++;
volt=1;
}
}
if(volt==0)
{
t[db].betu = toupper(sajt[0]);
t[db].mennyi++;
db++;
}
else
{
volt = 0;
}
}
for(i=0;i<db;i++)
{
printf("%c: %d\n", t[i].betu, t[i].mennyi);
}
return 0;
}
I tried strcmp and stricmp but neither worked. I tried to fully change the struct by sorting the struct properties. When the struct properties are sorted it doesn't work, but it worked before in a non-sorted order. What is preventing output when the struct properties are sorted?
As i can see in your code, you want to sort on char betu. One way to sort structures is via qsort but that'd require comparator function stated below:
int compare(const void *void_a, const void *void_b)
{
const KEZDO *a = void_a;
const KEZDO *b = void_b;
return (a->betu) < (b->betu);
}
//Perform sort like this;
qsort((void *) &t, db, sizeof(KEZDO) , compare );
Moreover, qsort is in #include <stdlib.h>

How to print string into an array after used the isdigit?

I'm very new to isdigit and the string. I really need help from you guys. I want to print string into an array 'food[f]'.But can you guys help me to check where is my problem ? Here is my code.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{
char foo[20];
float price;
int number=1;
int f=0,i=0;
char *food[f];
adding_food :
food[f] = (char*)malloc(25);
printf("Adding food into Menu (0 to Main Menu): ");
scanf("%s", foo);
{
if(isdigit(foo[0])== 0)
{
foo[i] = *food[f]; //something wrong here
printf("Enter price (RM) : ");
scanf("%f",&price);
printf("\n%-16d%-19s%6.2f\n\n",number,foo,price);
printf("\n%-16d%-19s%6.2f\n\n",number,food[f],price);
number++;
i++;
f++;
goto adding_food;
}
else
return 0;
}
}
I would like my output be like this
Adding food into Menu (0 to Main Menu) : Cake
Enter price (RM) : 10
1 Cake 10 //foo[0]
1 Cake 10 //food[0]
There are several mistakes in your code. Example:
char *food[f];
is similar to
char *food[0];
as f is zero. That makes no sense.
Also the use of goto is not considered good style.
So let me show you another approach. Something like:
// Make a type that can hold both a name and a price
struct item
{
char name[25];
float price;
};
#define MAX_ITEMS 100
struct item* addItems(int* n)
{
*n = 0;
struct item* items = malloc(MAX_ITEMS * sizeof *items);
if (items == NULL) return NULL;
while (*n != MAX_ITEMS)
{
scanf("%24s", items[*n].name);
if (items[*n].name[0] == '0') break;
scanf("%f", &items[*n].price);
*n += 1;
}
return items;
}
void print_all(struct item* my_items, int num_items)
{
for (int i = 0; i < num_items; ++i)
printf("%s %f\n", my_items[i].name, my_items[i].price);
}
int main()
{
int num_items;
struct item* my_items = addItems(&num_items);
print_all(my_items, num_items);
free(my_items);
}

Why do I have to do ctrl+z twice to break end of file?

Basically I have a struct
typedef struct {
const char *nome;
const char *apelido;
int numero;
} Aluno;
I want to sort this by numero.
For example, Input:
jonhy_james_123
jack_china_111
Output :
jack_china_111
jonhy_james_123
I have sucessfully done this, but instead of one CTRL+Z to break end of file, I
somehow need to do it twice.
Here is the full code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <string.h>
typedef struct {
const char *nome;
const char *apelido;
int numero;
} Aluno;
Aluno aluno(const char *nome, const char *apelido, int numero)
{
Aluno result;
result.nome = nome;
result.apelido = apelido;
result.numero = numero;
return result;
}
Aluno *Aluno_new (int n)
{
return (Aluno *) malloc (n * sizeof(Aluno));
}
char *str_dup(const char *s)
{
char *result = (char *) malloc(strlen(s) + 1);
strcpy(result, s);
return result;
}
int aluno_read(Aluno *a)
{
int result = 0;
char nome[50];
char apelido[50];
int numero;
while (scanf("%[^_]_%[^_]_%d\n", nome, apelido, &numero) != EOF) {
a[result++] = aluno(str_dup(nome), str_dup(apelido), numero);
}
return result;
}
void aluno_write(Aluno *a, int n)
{
printf("%s_%s_%d\n", a[0].nome, a[0].apelido, a[0].numero);
for (int i = 1; i < n; i++) {
printf("%s_%s_%d\n", a[i].nome, a[i].apelido, a[i].numero);
}
}
int qsort_cmp_numero(Aluno *x, Aluno *y)
{
return (x->numero - y->numero);
}
int cmp_B(Aluno *x, Aluno *y)
{
int result = qsort_cmp_numero(x,y);
return result;
}
int cmp_final2(const void *p, const void *q)
{
return cmp_B((Aluno *) p, (Aluno *) q);
}
void test_sort()
{
Aluno *aluno = Aluno_new(100001);
int n_aluno = aluno_read(aluno);
qsort(aluno, n_aluno, sizeof(Aluno), cmp_final2);
aluno_write(aluno, n_aluno);
}
int main()
{
test_sort();
return 0;
}
While behavior of Ctrl-Z in Windows has some peculiarities, this is secondary at the moment.
The primary problem is that you placed an \n character at the end of your scanf format. By doing so you asked scanf to wait for non-empty input after the "primary" portion of the input is complete.
This by itself will easily result "strange" behaviors of your scanf, like "ignoring" Enter key and such.
What is that \n doing there? Why did you include it in your format string?

Adding an update node into a linked list

I'm having trouble figuring out how to do a update function in this current code. He does not want us to change the student ID, but wants us to change the GPA and the major associated with the current student. He wants us to
create a prompt for the user to enter the student ID number to search for. Also to create a prompt to determine which field the user wished to update then accept new input for that field and change the contents of the appropriate student. I don't want the answer. I just need to be pointed in the right direction.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stuff.h"
#include "staticll.h"
int compareID(void*, void*);
int compareGPA(void*, void*);
int compareMajor(void*, void*);
void main(void)
{
FILE *fp;
struct Node List[15];
int Begin, current, newStuff, oldStuff;
double oldData;
int(*fnPtr)();
fnPtr = compareMajor;
Begin = 0;
struct Student *stu;
for (int x = 0; x < 3; x++)
{
newStuff = FindSpace(List);
List[newStuff].nodeData = readData(stdin);
addNode(Begin, List, newStuff);
}
for (int i = Begin; i != -1; i = List[i].nodeLink)
fprintf(stdout,"%.2f\n",((Stu*)List[i].nodeData));
for (int i = Begin; i != -1; i = List[i].nodeLink)
free(List[i].nodeData);
}
int compareID(void *p1, void *p2)
{
if (((Stu*)p1)->stuID == ((Stu*)p2)->stuID)
return 0;
else
if ((((Stu*)p1)->stuID < ((Stu*)p2)->stuID))
return 1;
else
return -1;
}
int compareGPA(void *p1, void *p2)
{
if (((Stu*)p1)->stuGPA == ((Stu*)p2)->stuGPA)
return 0;
else
if ((((Stu*)p1)->stuGPA < ((Stu*)p2)->stuGPA))
return 1;
else
return -1;
}
int compareMajor(void *p1, void *p2)
{
return strcmp(((Stu*)p1)->stuMajor, ((Stu*)p2)->stuMajor);
}
This is the current code I've created for the update function needed.
#include"Stuff.h"
void updateNode(struct Node List[], int current, int *NewData)
{
int temp1;
List[current].nodeLink = List[*NewData].nodeData;
List[*NewData].nodeLink = NewData;
printf("enter the student ID number ");
}

warning: implicit declaration of function TableCreate

I have to build a hash table data structure for this project, which I have done it in other files. For some reason when I compile my program and I get error, which is regarding initialization function (TableCreate();) of hash table. When I remove this part of the code from main function and execute, it works fine but then I get segfault when i try to add something to the hash table.
I believe my hash table code has nothing to do with this errors because my hash table code is based upon examples of Hash table code which was provided to us by our professor
I'm using GCC compiler.
Please help me solve this issue.
Error Message
src/sshell.c: In function âmainâ:
src/sshell.c:34: warning: implicit declaration of function âTableCreateâ
src/sshell.c:34: warning: assignment makes pointer from integer without a cast
sshell.c
#include "parser.h"
#include "shell.h"
#include "hash_table.h"
#include "variables.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(void){
char input[1000], sInput[1000]; // String to get user input
int count=1, len; // num=0;
struct Table *t;
t = TableCreate(); //create the table
int while_track;
FILE *ptr_file;
ptr_file =fopen(".simpleshell_history","a");
fclose(ptr_file);
printf("\nWelcome to the sample shell! You may enter commands here, one\n");
printf("per line. When you're finished, press Ctrl+D on a line by\n");
printf("itself. I understand basic commands and arguments separated by\n");
printf("spaces, redirection with < and >, up to two commands joined\n");
printf("by a pipe, tilde expansion, and background commands with &.\n\n");
printf("\npssh$ ");
while (fgets(input, sizeof(input), stdin)) {
strcpy(sInput, input);
len = strlen(input);
if( input[len-1] == '\n' ){
input[len-1] = '\0';
}
while_track = 1; // used to keep track of loop
while (while_track == 1){
count+=1;
if (strcmp(input, "history")==0){
while_track = History(); // print history function call
}else if (strcmp(input, "!!")==0){
while_track = Previous(input); // execute previous function call
}else if (strncmp(input, "!",1)==0){ // !string and !number sort
if(isdigit(input[1])){
while_track = Number(input);
} else {
while_track = String(input);
}
}else { // if the user entry was not any of specfic comnnad then pass the command to parse to execute
other(input,t);
parse(input);
while_track = 0;
}
}
HistoryFile(sInput); // A function call to recode commands entered by the user into a file
printf("\npssh$ ");
}
return 0;
}
hash_table.c
#include "hash_table.h"
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
void feedData(char * var, char * val, struct Table *t){
//const char * key=0;
printf("\n In FeedData Function\n");
Table_add(t, var, val);
printf("\nInside Feed Function -- Veriable: %s Value: %s\n",var, val);
}
unsigned int hash(const char *x) {
printf("\n In Hash\n");
int i;
unsigned int h = 0U;
printf("\n In Hash - Before for loop\n");
for (i=0; x[i]!='\0'; i++)
printf("\n In Hash - In for loop %d \n", i);
h = h * 65599 + (unsigned char)x[i];
printf("\n In Hash - In for loop - after calculation \n");
unsigned int g;
g = h % 1024;
printf("\n In Hash - In for loop - before return: %u \n",g);
return g;
}
struct Table *Table_create(void) {
printf("\n In Table_create\n");
struct Table *t;
t = (struct Table*)calloc(1, sizeof(struct Table));
return t;
}
void Table_add(struct Table *t, const char *key, char * val){
printf("\n In Table_add\n");
struct Node *p = (struct Node*)malloc(sizeof(struct Node));
int h = hash(key);
printf("\n In Table_add - after hash key\n");
//p->key = *key;
strcpy(p->key,key);
printf("\n In Table_add - after first key\n");
strcpy(p->value,val);
printf("\n In Table_add - after Value\n");
p->next = t->array[h];
printf("\n In Table_add - after p->next\n");
t->array[h] = p;
printf("\n In Table_add - after t->array[h] = p\n");
}
/*
int Table_search(struct Table *t, const char *key, int *value){
struct Node *p;
int h = hash(key); //---------------------------------------------------------------------
for (p = t->array[h]; p != NULL; p = p->next)
if (strcmp(p->key, key) == 0) {
*value = p->value;
return 1;
}
return 0;
}
*/
/*
void Table_free(struct Table *t) {
struct Node *p;
struct Node *nextp;
int b;
for (b = 0; b < BUCKET_COUNT; b++)
for (p = t->array[b]; p != NULL; p = nextp) {
nextp = p->next;
free(p);
}
free(t);
}
*/
hash_table.h file code
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
struct Table *Table_create(void);
void Table_add(struct Table *t, const char *key, char * val);
unsigned int hash(const char *x);
void feedData(char * var, char * val, struct Table *t);
enum {BUCKET_COUNT = 1024};
struct Node {
char key[1000];
char variable[1000];
char value[1000];
struct Node *next;
};
struct Table {
struct Node *array[BUCKET_COUNT];
};
#endif
Warning 1: You are calling TableCreate while your function name is Table_create
Warning 2: After looking at new identifier followed by (, compiler assumes it is a function that takes variable number of arguments and returns int.

Resources