Why updated structure variable not printing - c

This is my code in which if student marks is greater than 85,scholarship status will be changed to sanctioned, but after updating it is not printing
#include<stdio.h>
#include<string.h>
struct scholor
{
char name[25];
int sem;
int marks;
char status;
};
void sanction(int m, char *s)
{
if(m>85)
{
char p[15]="sanctioned";
char *r;
r=p;
while(*r!='\0')
{
*s=*r;
s++;
r++;
}
*s='\0';
}
}
int main()
{
struct scholor s1;
scanf("%s%d%d%s",&s1.name,&s1.sem,&s1.marks,&s1.status);
sanction(s1.marks,&s1.status);
printf("%s",s1.status);
}

status is a single char but you are storing a string into it, effectively doing out of bounds access (undefined behaviour). Change it to an array and then you'll be able to copy.
struct scholor
{
char name[25];
int sem;
int marks;
char status[128];
};
and adjust the calls and passing (since status is an array now -- its name gets converted into a pointer t its first element when passed to functions):
scanf("%s%d%d%s",s1.name,&s1.sem,&s1.marks,s1.status);
sanction(s1.marks,s1.status);
printf("%s",s1.status);
Other suggestions:
1. Use a standard prototype for main such as: int main(void)
2. You could usr strcpy to copy the string as opposed to doing it yourself.

Your struct should have status as a character array not a character .Moreover when you scanf an array dont write & before because the name itself points to the assdress of the first element.Your corrected program is :
struct scholor
{
char name[25];
int sem;
int marks;
char status[16];
};
void sanction(int m, char *s)
{
if(m>85)
{
char p[15]="sanctioned";
char *r;
r=p;
while(*r!='\0')
{
*s=*r;
s++;
r++;
}
*s='\0';
}
}
int main()
{
struct scholor s1;
scanf("%s%d%d%s",s1.name,&s1.sem,&s1.marks,s1.status);
sanction(s1.marks,s1.status);
printf("%s",s1.status);
}

Related

How to determine to use pointer or normal variable in function argument?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct contact {
char name[30];
int phone_number;
char address [30];
};
int main(int argc, char **argv) {
struct contact friend;
strcpy(friend.name, "Jane Doe");
friend.phone_number = 377177377;
strcpy(friend.address, "3771 University Avenue");
char *name;
int number;
char *address;
update_contact(&friend, name, number, address);
return 0;
}
I need to implement the update_contact function to update the contact information. friend and number are normal variables. *name and *address are pointers. But the function call also use the address of the pointer friend, which is &friend. Now I'm very confused on what should I put in the function parameters.
I tried to put pointers in.
void update_contact (struct *c, char *name, int number, char *address) {
c->name = name;
c->phone_number = number;
c->address = address;
}
However, this comes up with a bunch of errors, such as
error: request for member 'address' in something not a structure or union
&c->address = address;
How can I fix this? Thank you
This is the fixed version. Thanks Thomas Jager and Some Name.
void update_contact (struct contact *c, char *name, int number, char *address) {
strcpy(c->name, name);
c->phone_number = number;
strcpy(c->address, address);
}
As David C. Rankin suggested:
You need to initialize the variables passed as parameters.
For example
char *name = "Donald Trump";
int number = 01010101010;
char *address = "White House;
char name[] = "Donald Trump";
int number = 01010101010;
char address[] = "White House;
or you can use literals and constants when calling the function
update_contact(&friend, "Donald Trump", 0101010010, "White House");
void update_contact (struct contact *c, char *name, int number, char *address) {
strcpy(c->name, name);
c->phone_number = number;
strcpy(c->address, address);
}
In function update_contract,
replace struct with struct contact
use strcpy
as follows
void update_contact(struct contact *c, char *name, int number, char *address) {
strcpy(c->name, name);
c->phone_number = number;
strcpy(c->address, address);
}

Pass String array and indexes using Struct to a thread in C

I am trying to pass a string array and indexes from where to start end searching in the array, I am unable to solve it from the last two days. I am sending to the pthread_create a struct data thread_data, here i am able to send the int and long data, but not the string array, can someone help me, how to pass these.
struct data{
int tid;
unsigned long start;
unsigned long end;
char * word;
char * str;
};
struct data thread_data[NUM_THREADS];
void *searchString(void *passeddata)
{
struct data *t_data;
int tid1;
char * str[3];
t_data=(struct data *) passeddata;
tid1=t_data->tid;
str=t_data->str;
.....
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
...
char work[]={"First Line","Second line","Third line"};
...
while(fgets(arr[index],120, fp)!=NULL){
index=index+1;
thread_data[index].tid=index;
thread_data[index].str=work;
...
rc=pthread_create(&threads[index],NULL,searchString,(void *)&thread_data[index]);
...
}
pthread_exit(NULL);
}
To hold the multiple strings you need 2D array.
const char *work[]={"First Line","Second line","Third line", "Fourth Line"};
You need to use pointer to pointer in struct data to hold the above array.
struct data{
.....
const char **str;
size_t lenOfStr;
};
And pass the length of array explicitly to thread function from main function.
Your sample code may look like below.
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct data{
int tid;
unsigned long start;
unsigned long end;
char * word;
const char **str;
size_t lenOfStr;
};
struct data thread_data[3];
void *searchString(void *passeddata)
{
struct data *t_data;
int tid1;
const char **str = NULL;
t_data=(struct data *) passeddata;
tid1=t_data->tid;
str=t_data->str;
int i = 0;
for (i = 0;i<t_data->lenOfStr;i++)
printf("%s\n", str[i]);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
const char *work[]={"First Line","Second line","Third line", "Fourth Line"};
int index = 0;
pthread_t threadid=0;
thread_data[index].tid=index;
thread_data[index].str=work;
thread_data[index].lenOfStr = sizeof(work)/sizeof(*work); // Calculate the size of work here
int rc=pthread_create(&threadid,NULL,searchString,&thread_data[index]);
pthread_exit(NULL);
}

Looping through C struct w/o union

My intention: To loop through -- without using unions -- 30 members of a structure, all of type character array, storing in each the result of a call to itoa. In the following code, I name the structure members a-z,A-D. In the calling function, I initialize a string of those characters, called 'letters', then I try to loop through the structure members by referring to them with my increment variable as the index into letters. Then, I try to dump the contents of each member of the structure. **edit: I realize that the members wouldn't contain anything, given what code you can see. The problem seems to be with referring to struct members like this.
struct listArrays {
char a[10];
char b[10];
char c[10];
char d[10];
char e[10];
char f[10];
char g[10];
char h[10];
char i[10];
char j[10];
char k[10];
char l[10];
char m[10];
char n[10];
char o[10];
char p[10];
char q[10];
char r[10];
char s[10];
char t[10];
char u[10];
char v[10];
char w[10];
char x[10];
char y[10];
char z[10];
char A[10];
char B[10];
char C[10];
char D[10];
};
struct listArrays Ternaries;
int testTernary(){
char letters[30] = "ABCDabcdefghijklmnopqrstuvwxyz";
int i;
for(i = 0; i < 30; ++i){
dumpArray((Ternaries.(letters[i])), 10);
}
return 0;
}
The error I get is "expected identifier before '(' token."
Problems I have ruled out:
-The dumpArray function works fine.
-Looping through the letters works fine, outside the context of the
referral to struct members
Identifiers (names) only exist in the program text. Once compiled and linked, they no longer exist. So you can't "index" the struct for the letter. What you can do is:
struct listArrays {
char letters[30][10];
};
Now you can access these "letters":
dumpArray((Ternaries.letters[i]), 10);

How can i pass a structure to a function

I have called a function with seven parameters from main
find_sync(es_data + (loop_count * size) + chunk_bytes_counter,
size - chunk_bytes_counter, &sync_index, &flag,
&sync_length, &chunk_bytes_counter, &total_bytes_counter);
in function.c:
void find_sync(char data[], size_t size, unsigned int *sync_index, int *flag, unsigned int *sync_length, unsigned int *chunk_bytes_counter, unsigned int *total_bytes_counter)
prototype in header file:
extern void find_sync(char data[], size_t size, unsigned int *sync_index, int *flag, unsigned int *sync_length, unsigned int *bytes_counter, unsigned int *total_bytes_counter);
Now, my question is, how can i declare all these 7 parameters in a structure, so that i can only pass one structure variable.
Begin by declaring the struct:
struct find_sync_parameters {
char* data;
size_t size;
unsigned int *sync_index;
int *flag;
unsigned int *sync_length;
unsigned int *bytes_counter;
unsigned int *total_bytes_counter;
}
Then change your function signature either to:
void find_sync(struct find_sync_parameters param)
Or to
void find_sync(struct find_sync_parameters *param)
In the first case the whole struct will be pushed onto the stack before transferring control to find_sync. On the second case only a pointer to the struct (stored elsewhere) will be pushed.
There are advantages and drawbacks in each one. When passing a pointer note that the function can change the contents (this can be positive: for returning values directly inside the struct; also can be negative: the caller cannot be sure if its data were changed or not). If the struct is too big (not your case), then pushing everything onto the stack can take a significant amount of time and become a performance hit.
Inside the function you use it either with '.' (dot, the first case) or '->' (arrow, the second case) operator.
To call it:
struct find_sync_parameters p = { ... };
find_sync(p); // first case
find_sync(&p); // second case
If you find it annoying to type struct find_sync_parameters everytime you can define a new type with typedef:
typedef struct find_sync_parameters find_sync_parameters;
Or in one line (struct and typedef definitions):
typedef struct find_sync_parameters {
...
} find_sync_parameters;
Or even without struct name (anonymous struct)
typedef struct {
...
} find_sync_parameters;
In this last case you cannot reference the struct itself inside the struct (the case, for example, with linked list nodes).
Just put in structure .
struct pars_t
{
char data[];
size_t size; unsigned int *sync_index;
int *flag; unsigned int *sync_length;
unsigned int *bytes_counter;
unsigned int *total_bytes_counter;
} pars;
and then call foo (pars_t par)
You can create a struct (and typedef it at the same time, to make it usable without saying "struct" every time) like so:
typedef struct _find_sync_str{
char* data;
size_t size;
unsigned int *sync_index;
int *flag;
unsigned int *sync_length;
unsigned int *bytes_counter;
unsigned int *total_bytes_counter;
} find_sync_str
Then you can list the function as:
void find_sync(find_sync_str f);
I am going to suggest:
struct find_sync_struct {
char* data;
size_t size;
unsigned int sync_index;
int flag;
unsigned int sync_length;
unsigned int bytes_counter;
unsigned int total_bytes_counter;
};
Change the input argument of find_sync to:
void find_sync(struct find_sync_struct* strPtr);
Call the function using:
struct find_sync_struct str;
// Set str.data to something suitable.
// ....
find_sync(&str);
Here is a simple example demonstrating how to pass a structure to a function:
#include<stdio.h>
#include<conio.h>
//-------------------------------------
struct Example
{
int num1;
int num2;
}s[3];
//-------------------------------------
void accept(struct Example *sptr)
{
printf("\nEnter num1 : ");
scanf("%d",&sptr->num1);
printf("\nEnter num2 : ");
scanf("%d",&sptr->num2);
}
//-------------------------------------
void print(struct Example *sptr)
{
printf("\nNum1 : %d",sptr->num1);
printf("\nNum2 : %d",sptr->num2);
}
//-------------------------------------
void main()
{
int i;
clrscr();
for(i=0;i<3;i++)
accept(&s[i]);
for(i=0;i<3;i++)
print(&s[i]);
getch();
}

Instantiations for structs in C?

So I'm trying to learn C right now, and I have some basic struct questions I'd like to clear up:
Basically, everything centers around this snippet of code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME_LEN 127
const char* getName(const Student* s);
void setName(Student* s, const char* name);
unsigned long getStudentID(const Student* s);
void setStudentID(Student* s, unsigned long sid);
int main(void) {
Student sarah;
const char* my_name = "Sarah Spond";
setName(&sarah, my_name);
printf("Name is set to %s\n", sarah.name);
}
typedef struct {
char name[MAX_NAME_LEN + 1];
unsigned long sid;
} Student;
/* return the name of student s */
const char* getName (const Student* s) { // the parameter 's' is a pointer to a Student struct
return s->name; // returns the 'name' member of a Student struct
}
/* set the name of student s
If name is too long, cut off characters after the maximum number of characters allowed.
*/
void setName(Student* s, const char* name) { // 's' is a pointer to a Student struct | 'name' is a pointer to the first element of a char array (repres. a string)
int iStringLength = strlen(name);
for (i = 0; i < iStringLength && i < MAX_NAME_LEN; i++) {
s->name[i] = name[i];
}
}
/* return the SID of student s */
unsigned long getStudentID(const Student* s) { // 's' is a pointer to a Student struct
return s->sid;
}
/* set the SID of student s */
void setStudentID(Student* s, unsigned long sid) { // 's' is a pointer to a Student struct | 'sid' is a 'long' representing the desired SID
s->sid = sid;
}
However, when I try and compile the program, I get a bunch of errors saying that there's an "unknown type name Student". What am I doing wrong?
Thanks!
Move the type definition for Student - the typedef .. right after #define MAX_NAME_LEN 127, i.e. before it's being referenced.
You need to move the declaration of the Student struct above the first time it is referenced by other code - otherwise those functions will not know what it is.
Struct declarations need to be defined before you use them , so you need to move your Student
As cnicutar said, move the typedef - the reason for this is that the type must be known before it's used. Alternatively, you can forward declare the type.
> Move the typedef .. right after #define MAX_NAME_LEN 127, i.e. before
> it's being used.
OR, if you want to keep your definition after, and if you are ready to use a pointer to Student, you can:
#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME_LEN 127
// forward declare Student ici
struct Student;
//...
// in main, use a pointer to student
int main(void) {
Student *sarah; // Changed to pointer
const char* my_name = "Sarah Spond";
setName(sarah, my_name); // Pass the pointer instead of reference
printf("Name is set to %s\n", sarah->name); // Use the pointer
//....
delete sarah; // delete object when done
}
// Change struct decl to the following // can't explain the diff yet
struct Student {
char name[MAX_NAME_LEN + 1];
unsigned long sid;
};
A basic structure of a C program is:
//======DOCUMENT SECTION=========
//File:test.c
//Author:
//Description:
//...
//================================
//====INCLUDE SECTION=============
#include "lib1"
#include <lib2>
//================================
//========DEFINITIONS SECTION=====
#define TRUE 1
#define FALSE 0
//================================
//========STRUCTURES SECTION======
struct P{
};
//================================
//========TYPEDEFS SECTION========
typedef *P P;
//================================
//========FUNCTION HEADERS========
void foo1(...);
int foo2(...,...,...);
//================================
//=========GLOBAL VARIABLES=======
int GLOBAL_INT;
float GLOBAL_FLOAT;
//================================
//=====MAIN FUNCTION DEFINITION===
void main(void)
{
...
...
...
}
//=================================
//======FUNCTIONS DEFINITION======
void foo1(...)
{
}
int foo2(...,...,...)
{
}
//================================
A main function is where a C program starts. A main function also typically has access to the command arguments given to the program when it was executed.
Usually you have got:
int main(void);
int main();
int main(int argc, char **argv);
int main(int argc, char *argv[]);

Resources