I had an assignment about entering an unknown number of the students' information and then printing them out. the code that I wrote works properly for one student but when I enter other students, only the output of the phone numbers and IDs are wrong but there isn't any error message. This is the shorter version of my code. I was hoping that someone could help me find the error.
Thank you for helping in advance!!
code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRSIZE 75
struct student GetData();
int print_info (struct student *STU, int i);
struct company
{
char Co_Intern[STRSIZE];
long int Co_Tel; ///this variable has wrong output
};
struct student
{
long int ID; ///this variable has wrong output
char name[STRSIZE];
long int Tel; ///this variable has wrong output
struct company COE;
int Tot_days;
struct Date
{
int dd;
int mm;
int yyyy;
}doj;
};
int main()
{
struct student *STU;
int i, n;
printf("Enter the number of students: ");
scanf("%d", &n);
STU = (struct student*) malloc(n * sizeof(struct student));
for(i = 0; i < n; ++i)
{
STU[i]= GetData(); //calling a struct function to scan data
}
printf("\nDisplaying Information:\n==============================\n\n");
for(i = 0; i < n; ++i)
{
print_info (STU, i); //calling a function to print data
}
return 0;
}
struct student GetData() ///struct function to scan data
{
struct student info_s;
printf("\nEnter student's information:\n");
printf("Student ID:\t");
scanf("%li", &info_s.ID);
printf("Student's name:\t");
getchar();
gets(info_s.name);
printf("Student Telephone number:\t");
scanf("%li", &info_s.Tel);
printf("\nEnter student's internship company date and information:\n");
printf("Student's Company of internship:\t");
scanf("%s", info_s.COE.Co_Intern);
printf("Company's Telephone:\t");
scanf("%li", &info_s.COE.Co_Tel);
printf("Beginning date: dd-mm-yyyy:\t");
scanf("%d%d%d", &info_s.doj.dd, &info_s.doj.mm, &info_s.doj.yyyy);
printf("Total days of internship:\t");
scanf("%d", &info_s.Tot_days);
return(info_s);
}
int print_info (struct student *STU, int i)
{
printf("\nStudent-%d:\t\t\t\t\t\t",i+1);
printf("\n\nStudent ID:\t\t\t\t\t%li", STU[i].ID);
printf("\n\nStudent's name:\t\t\t\t\t%s", STU[i].name);
printf("\n\nStudent Telephone number:\t\t\t%li", STU[i].Tel);
//here is the problem
printf("\n\nStudent's Company of internship:\t\t%s", STU[i].COE.Co_Intern);
printf("\n\nCompany's Telephone:\t\t\t\t%li", STU[i].COE.Co_Tel);
//here is the problem
printf("\n\nBeginning date: dd-mm-yyyy:\t\t\t%d%d%d", STU[i].doj.dd, STU[i].doj.mm, STU[i].doj.yyyy);
printf("\n\nTotal days of internship:\t\t\t%d", STU[i].Tot_days);
printf("\n\n==============================\n\n");
}
and this is the output in which the long numbers are wrong:
Enter the number of students: 2
Enter student's information:
Student ID: 1234567890
Student's name: xxxx xxxx
Student Telephone number: 987654321
Enter student's internship company date and information:
Student's Company of internship: aaaa
Company's Telephone: 5554443330
Beginning date: dd-mm-yyyy: 22-10-2020
Total days of internship: 365
Enter student's information:
Student ID: 1112223330
Student's name: nnnn ssss
Student Telephone number: 9998887770
Enter student's internship company date and information:
Student's Company of internship: name
Company's Telephone: 3333344444
Beginning date: dd-mm-yyyy: 20-10-2020
Total days of internship: 365
Displaying Information:
==============================
Student-1:
Student ID: 1234567890
Student's name: xxxx xxxx
Student Telephone number: 987654321
Student's Company of internship: aaaa
Company's Telephone: 1259476034
Beginning date: dd-mm-yyyy: 22-10-2020
Total days of internship: 365
==============================
Student-2:
Student ID: 1112223330
Student's name: nnnn ssss
Student Telephone number: 1408953178
Student's Company of internship: name
Company's Telephone: -961622852
Beginning date: dd-mm-yyyy: 20-10-2020
Total days of internship: 365
==============================
as you can see the following lines have problem, and only the IDs were correct however sometimes randomly the second Id is also wrong and has the wrong value but the dates and durations that I have in the code are correct. i also tried other ways that others asked about like scanning them individually as an int and then assigning them to their related struct but it didn't work as well.
Company's Telephone: -961622852
Student Telephone number: 1408953178
Company's Telephone: 1259476034
There are probably other issues, but the input string "%d%d%d" does not match the input given for the date. As a result, the scanf treats the values as negative numbers. To avoid this error, perhaps use a different input format. To avoid this type of error in general, you must always check the value returned by scanf, every time you call scanf. For example, perhaps use dd/mm/yy with:
if( 3 != scanf("%d/%d/%d", &info_s.doj.dd, &info_s.doj.mm, &info_s.doj.yyyy) ){
fprintf(stderr, "Invalid input\n");
exit(EXIT_FAILURE);
}
If you want to provide a friendlier interactive interface (which is best accomplished by using a language other than C!), you should probably not use scanf to read the input. Instead, use fgets and then parse the data (possibly with sscanf, but really you're better off avoiding the entire scanf family) after it has been read. Attempting to recover from unexpected input using scanf is often more difficult than it is worth.
See: http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
Related
I am trying to build this little database of students, using linked lists in C. For some reason I am getting a segmentation fault the second time I run this function. I have a switch inside a while loop where I can run the different functions by entering a number from the keyboard. So when I start the program, press 1 to run this function below, everything works fine. But when I try to run it a second time without terminating the program in between, it crashes and the debugger tells me that there was a segmentation fault. I can't figure out why.
This is a function in my script.
int add_student(void){
current_student = student_head;
current_study = study_head;
if (current_study == NULL || current_study == NULL)
return 1;
while(current_student->next_student != NULL){
current_student = current_student->next_student;
}
current_student->next_student = (student*)malloc(sizeof(student));
printf("Enter the persons personal number.");
scanf("%d", ¤t_student->next_student->pernum);
printf("Enter the persons name");
scanf("%s", current_student->next_student->name);
printf("Male or female? Write 1 for male and 0 for female.");
scanf("%d", ¤t_student->next_student->is_male);
if(current_student->next_student->is_male == 0)
num_of_female++;
else
num_of_male++;
printf("Enter the persons age");
scanf("%d", ¤t_student->next_student->age);
printf("Enter the persons email");
scanf("%s", current_student->next_student->email);
while(current_study->next_study != NULL){
current_study = current_study->next_study;
}
current_study->next_study = (study*)malloc(sizeof(study));
current_study->next_study->pernum = current_student->next_student->pernum;
printf("Does this student study math? Asnwer 1 for yes or 0 for no."); // Field of study.
scanf("%d", ¤t_study->next_study->math);
printf("Does this student study english? Asnwer 1 for yes or 0 for no.");
scanf("%d", ¤t_study->next_study->english);
printf("Does this student study chemistry? Asnwer 1 for yes or 0 for no.");
scanf("%d", ¤t_study->next_study->chemistry);
printf("Does this student study biology? Asnwer 1 for yes or 0 for no.");
scanf("%d", ¤t_study->next_study->biology);
printf("Does this student study history? Asnwer 1 for yes or 0 for no.");
scanf("%d", ¤t_study->next_study->history);
num_of_stud++;
}
I just want the function to be able to run an indefinite amount of times without crashing.
When I run the function the first time, current_student has a memory address as expected and current_student->next_student is NULL as expected. The second time current student has the same address and current_student->next_student has an address, so everything seems to be working so far?
Current_student, student head, current_study and study_head are all declared as global pointers.
Edit: Here are the declarations to the structs and the pointers to allocated memory. These are outside main on the top level outside any function:
typedef struct student{
int pernum;
char name[100];
int is_male;
int age;
char email[100];
struct student *next_student;
}student;
typedef struct study{
int pernum;
int math;
int english;
int chemistry;
int biology;
int history;
struct study *next_study;
}study;
int num_of_stud = 0;
int num_of_female = 0;
int num_of_male = 0;
student *current_student;
study *current_study;
student *student_head = NULL;
study *study_head = NULL;
Without seeing the content of your main function and how the add_student function was being called, I took a bit of artistic license to refactor some of the function so that it would sense when the first student structure or study structure was being added and act accordingly to provide a proper starting point and subsequent linked list chain. Following is a version of your function with some tweaks to determine a starting student/study point along with a main function that allows for a continuous number of student and study records to be entered. It is a bit lengthy, but I could not figure how to condense this any further.
#include <stdio.h>
#include <stdlib.h>
typedef struct student
{
int pernum;
char name[100];
int is_male;
int age;
char email[100];
struct student *next_student;
} student;
typedef struct study
{
int pernum;
int math;
int english;
int chemistry;
int biology;
int history;
struct study *next_study;
} study;
int num_of_stud = 0;
int num_of_female = 0;
int num_of_male = 0;
student *current_student = NULL;
study *current_study = NULL;
student *student_head = NULL;
study *study_head = NULL;
int add_student(void)
{
int resp = 0; /* Added to provide a user controlled end to student and study data entry */
if (current_student == NULL) /* If this is the initial student set up the initial structure allocation */
{
current_student = malloc(sizeof(student));
student_head = current_student;
}
else /* Else, chase down the linked list to the last current student */
{
while(current_student->next_student != NULL)
{
current_student = current_student->next_student;
}
}
current_student->next_student = malloc(sizeof(student));
printf("Enter the person's personal number: ");
scanf("%d", ¤t_student->next_student->pernum);
printf("Enter the persons name: ");
scanf("%s", current_student->next_student->name);
printf("Male or female? Write 1 for male and 0 for female: ");
scanf("%d", ¤t_student->next_student->is_male);
if(current_student->next_student->is_male == 0)
num_of_female++;
else
num_of_male++;
printf("Enter the persons age ");
scanf("%d", ¤t_student->next_student->age);
printf("Enter the persons email ");
scanf("%s", current_student->next_student->email);
current_student->next_student->next_student = NULL; /* Make sure the last student element has its pointer properly initialized */
if (current_study == NULL) /* If this is the initial study element set up the initial structure allocation */
{
current_study = malloc(sizeof(study));
study_head = current_study;
}
else /* Else, chase down the linked list to the last current study element */
{
while(current_study->next_study != NULL)
{
current_study = current_study->next_study;
}
}
current_study->next_study = malloc(sizeof(study));
current_study->next_study->pernum = current_student->next_student->pernum;
printf("Does this student study math? Asnwer 1 for yes or 0 for no: "); // Field of study.
scanf("%d", ¤t_study->next_study->math);
printf("Does this student study english? Asnwer 1 for yes or 0 for no: ");
scanf("%d", ¤t_study->next_study->english);
printf("Does this student study chemistry? Asnwer 1 for yes or 0 for no: ");
scanf("%d", ¤t_study->next_study->chemistry);
printf("Does this student study biology? Asnwer 1 for yes or 0 for no: ");
scanf("%d", ¤t_study->next_study->biology);
printf("Does this student study history? Asnwer 1 for yes or 0 for no: ");
scanf("%d", ¤t_study->next_study->history);
current_study->next_study->next_study = NULL; /* Make sure the last study element has its pointer properly initialized */
num_of_stud++;
printf("More students 0/1 "); /* Send a response back to the main function to determine if further entry will occur */
scanf("%d", &resp);
if (resp == 0)
{
return -1;
}
return 0;
}
int main()
{
while (1) /* A test harness to allow a variable number of students to be entered */
{
if (add_student() == -1)
{
break;
}
}
current_student = student_head->next_student; /* This bit added just to verify what was entered */
printf("Student list\n-----------------------------------------\n");
while (1)
{
printf("Number: %d Name: %s\n", current_student->pernum, current_student->name);
if (current_student->next_student == NULL)
{
break;
}
current_student = current_student->next_student;
}
current_student = student_head->next_student;
printf("\nStudy list\n-----------------------------------------\n");
while (1)
{
printf("Person number: %d Math: %d English: %d Chemistry: %d Biology: %d History: %d\n", current_study->pernum, current_study->math, current_study->english, current_study->chemistry, current_study->biology, current_study->history);
if (current_study->next_study == NULL)
{
break;
}
current_study = current_study->next_study;
}
return 0;
}
Some points to note.
Instead of immediately testing the pointer value in the student_head and study_head structure and exiting, that information is used to determine if the call to this function is meant to set up the initial student and study structures in the linked list.
As noted in the comments, the casting of the malloc function was removed.
To insure the linked list pointer integrity, the next student and next study pointers are set to NULL for every newly created student and study structure.
A response variable was added to provide a very simple method for indicating that student and study data entry is done; something more sophisticated might be used to determine when data entry is complete.
Just as a proof of function, the entered student and study records are printed out in the main function.
Following is some sample terminal output for two student/study entries; however, more students and their associated study structures could have been entered.
#Vera:~/C_Programs/Console/StudentBody/bin/Release$ ./StudentBody
Enter the person's personal number: 22
Enter the persons name: Craig
Male or female? Write 1 for male and 0 for female: 1
Enter the persons age 18
Enter the persons email craig#somemail.com
Does this student study math? Asnwer 1 for yes or 0 for no: 1
Does this student study english? Asnwer 1 for yes or 0 for no: 0
Does this student study chemistry? Asnwer 1 for yes or 0 for no: 0
Does this student study biology? Asnwer 1 for yes or 0 for no: 0
Does this student study history? Asnwer 1 for yes or 0 for no: 0
More students 0/1 1
Enter the person's personal number: 33
Enter the persons name: Lily
Male or female? Write 1 for male and 0 for female: 0
Enter the persons age 19
Enter the persons email lily#somemail.com
Does this student study math? Asnwer 1 for yes or 0 for no: 0
Does this student study english? Asnwer 1 for yes or 0 for no: 1
Does this student study chemistry? Asnwer 1 for yes or 0 for no: 0
Does this student study biology? Asnwer 1 for yes or 0 for no: 0
Does this student study history? Asnwer 1 for yes or 0 for no: 0
More students 0/1 0
Student list
-----------------------------------------
Number: 22 Name: Craig
Number: 33 Name: Lily
Study list
-----------------------------------------
Person number: 22 Math: 1 English: 0 Chemistry: 0 Biology: 0 History: 0
Person number: 33 Math: 0 English: 1 Chemistry: 0 Biology: 0 History: 0
Also, you may want to explore passing your structure or structure address as function parameters in lieu of using global variables as noted in the comments. But in order to provide a timely response with the code as is, I left your variables as global variables.
Give that a try and see if it meets the spirit of your project.
Please somebody help me when I use a function to populate my structure i get diffrent values from what i entered I have been stocked here for a while please somebody help me 🙏
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct myEMP
{
char *empName[20];
int *empID;
float *NofHworked;
int *payRate;
}myEMP;
char *Names;
myEMP getInfo(myEMP
employee) {
printf("Name:");
strcpy(employee.empName,fgets(
&Names,20,stdin) );
printf("ID :");
scanf("%d",&employee.empID);
printf("No of hours
worked :");
scanf("%f",&employee.NofHworked);
printf("Pyrate :");
scanf("%d",&employee.payRate);
return employee;
}
int main(){
int N;
myEMP *empINFO;
getInfo(*empINFO);
printf("Name \t Id \t
hours \t payrate \n" );
printf("%s \t %d \t %.2f \t
%d",empINFO-
>empName,empINFO-
>empID,empINFO-
>NofHworked,empINFO-
>payRate);
return 0;
}
I tried runing the code with
name: John Doe Id :01 No of hours worked : 06 Payrate :25
This is what I get
Name: â-#[|ìv Id: -1961038717 Hours: 0.00 Payrate:-1065106551
I dont know what to do since i am new to c somebody please help🙏🙏
Well, there are multiple issues with your code: The first one is that your code is very hard to read because it is not indented properly. I took the liberty to indent it for you:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct myEMP {
char* empName[20];
int* empID;
float* NofHworked;
int* payRate;
} myEMP;
char* Names;
myEMP getInfo(myEMP employee) {
printf("Name:");
strcpy(employee.empName, fgets(&Names, 20, stdin));
printf("ID :");
scanf("%d", &employee.empID);
printf("No of hours worked :");
scanf("%f", &employee.NofHworked);
printf("Pyrate :");
scanf("%d", &employee.payRate);
return employee;
}
int main() {
int N;
myEMP* empINFO;
getInfo(*empINFO);
printf("Name \t Id \t hours \t payrate \n");
printf("%s \t %d \t %.2f \t %d",empINFO->empName, empINFO->empID, empINFO->NofHworked, empINFO->payRate);
return 0;
}
The second thing is: You should decide on the signature of the function getInfo. IMHO, there are two possibilities:
Use void getInfo(myEMP* employee) as signature.
Use myEMP getInfo() as signature.
The first one will modify the employee which is stored at the memory address you provide, whereas the second one will return a new employee.
If you really want to use the function you have now, you have to improve your main function at least with regard to the following two points:
malloc the memory for empINFO.
Use the return value that getInfo provides.
However, I suggest redesigning the getInfo function.
Please note that I have not tested your code, so there is a good chance that there are even more issues.
this for adding new costumer.
typedef struct date{
int d,m,y;
}date;
typedef struct client{
int *id;
char *nom [30];
char *prenom [30];
date date;
char *adresse[30] ;
char *tel [30];
}client;
client cl;
void ajouter (){
int age;
printf("give first name:\n");
scanf("%s",&cl.nom);
printf("give last name:\n");
scanf("%s",&cl.prenom);
printf("give adresse:\n");
scanf("%s",&cl.adresse);
printf("give tel num:\n");
scanf("%s",&cl.tel);
printf("give date of birth :\n");
scanf("%d %d %d",&cl.date.d, &cl.date.m, &cl.date.y);
cl.id=1;
if(2019-cl.date.y<18)
printf("refuse");
else
printf(" succes\n");
printf("your informations:\n");
printf(" first name: %s \n last name: %s \n adresse: %s \n tel num: %s \n date of birth : %d/%d/%d \n ID: 0000000%d",cl.nom,cl.prenom,cl.adresse,cl.tel,cl.date.d,cl.date.m,cl.date.y,cl.id);
cl.id++;
}
the problem is when i add the 1st costumer i dont know how to store the informations
i want to save it without using files.
i am beginner and i know maybe its wrong what am doing
but am trying to do my best to make this code
int main()
{
int a,age;
char t[100];
printf("----------- menu ------------\n");
printf("add customer : 1\n");
printf("remove customer : 2\n");
printf("search for customer : 3\n");
scanf("%d",&a);
switch(a){
case(1):ajouter(a);break;
}
return 0;
}
i didnt finish it yet
Salut,
If I understood well, you wish to store a client's data in an array in RAM.
I believe you are using C, hence vectors are not really an option.
So instead, you have either the option of having an array of fixed size, which could be useful in certain situations but generally not, or having a dynamic array, which can be kind of hard to understand when begginning but you shouldn't have much trouble.
In the case a fixed-size array works for you, here's an example of how you'd do it:
//Declaring the client array
#define nClientsTableau 100
int nClients = 0;
client clients[nClientsTableau];
...
//Adding a new client, keep in mind it's just an example
ajouter();
clients[nClients] = cl;
nClients++;
if(nClients == nClientsTableau) printf("Max amount of clients reached");
Then for the second option, building a dynamic array. Different ways of doing it exist, here is a simple way to perform it for your code:
//Declaring the client array
client* clients = NULL;
client* clients2 = NULL;
int nClients = 0
//Adding a new client
ajouter();
nClients++;
clients2 = (client*)realloc(clients, nClients * sizeof(client));
clients = clients2; //NOTE: You should probably check for clients2 not being NULL first
clients[nClients - 1] = cl;
//Ending the program
free(clients);
I sincerely hope this helps. Apart from that, I'd like to tell you that your code is excellent for a beginner, just try having some naming conventions.
For my assignment I am to create a structure that allows the user to enter student info (ID, DOB, & Phone number). I have no problem doing this that is quite simple. Now I need to search through that enter info using the student ID to display that students corresponding DOB and phone number, this is the problem that I am having trouble working with. If you see any other problems with my program please let me know what is wrong and why I should change so I can learn from my mistakes.
Thank you.
#include <stdio.h>
#include <stdlib.h>
struct infoStruct
{
int studentID;
int year;
int month;
int day;
int phone;
int end;
};
int main (void)
{
int students = 0;
int infoArray [students];
struct infoStruct info;
int studentID;
int year;
int month;
int day;
int phone;
int end;
while (info.end != -1) {
students = students + 1;
printf("Enter student information (ID, day, month, year, phone)\n");
printf("Enter -1 following the phone number to end the process to continue enter 0\n");
scanf("%d %d %d %d %d %d", &info.studentID, &info.day, &info.month, &info.year, &info.phone, &info.end);
}
if (info.end = -1){
printf("You entered %d student(s)\n", students);
}
//Student Search
printf("Please enter the student ID of the student your looking for\n.");
scanf("%d", info.studentID);
printf(" DOB: %d %d %d, Phone: %d", info.month, info.day, info.year, info.phone);
}
info.end is not initialized before while (info.end != -1). Initiliaze all your variable (studentID...) and structure.
if (info.end = -1) is an assignment !
Use : if (info.end == -1) I prefer to use if (-1 == info.end) (if you had use : only = instead of == you would have get an error). (Yoda trick ^^)
And you have to use an array of struct in order to save every student (because you are continuously erasing the previous student information).
It's your homework, I won't do the work for you ;)
I'll leave most of the coding to you, as this is homework, but here is what you need to change to get this to work.
First of all, if you want to store multiple students info is going to need to be an array
static int MAX_STUDENTS = 50;
struct infoStruct info[MAX_STUDENTS];
and then you scan each student into a seperate part of the struct
scanf("%d %d %d %d %d %d", &info[students-1].studentID, &info[students-1].day, &info[students-1].month, &info[students-1].year, &info[students-1].phone, &info[students-1].end);
then you need to ensure that the end condition is checked properly (check the latest info[x].end)
It would also be wise to check you still have some room in the array before trying to add more.
with those done you are storing the students correctly.
as for searching, you need to scan the id to search into a seperate int.
then loop through the array (info[x]) and search each element's studentID against the search ID. When you have a match, print it out.
Edit:
its also worth considering storing the phone number as a "string" rather than an int, alot of phone numbers start with "0", but an int would remove the 0.
(so the phone number 012345, would become, 12345)
I am writing a program to create a structure named 'student'. I need to input various data about a particular student. Here is my program till now.
#include<stdio.h>
#include<stdlib.h>
struct student
{
char* name;
int id;
float marks_1;
float marks_2;
};
void main()
{
int num, var_i, var_j, var_k, var_l, duplicated_id = 0;
printf("Enter number of students\n");
scanf("%d", &num);
struct student s[num];
printf("Enter the data for the students\n");
for (var_i = 0; var_i < num; var_i++)
{
var_j = var_i + 1;
printf("Enter name of student_%d\n", var_j);
scanf(" %[^\n]%*c", &s[var_i].name);
printf("Enter id of student_%d\n", var_j);
scanf("%d", &s[var_i].id);
for (var_k = 0; var_k < var_i; var_k++)
{
if (s[var_k].id == s[var_i].id)
{
printf("Duplicate Id, program will exit");
return;
}
}
printf("Enter marks(sub_1) of student_%d\n", var_j);
scanf("%d", &s[var_i].marks_1);
printf("Enter marks(sub_2) of student_%d\n", var_j);
scanf("%d", &s[var_i].marks_2);
}
}
In the following for loop I am checking all the previously entered 'id' values to check if there is a duplicate. In case of a duplicate, the program will exit.
for(var_k=0;var_k<var_i;var_k++)
{
if(s[var_k].id==s[var_i].id)
{
printf("Duplicate Id, program will exit");
return;
}
}
Now instead of exiting the program I want to prompt the user to enter a different value. This goes on till he enters a unique value. How should I do it?
Any help appreciated.
This is wrong:
scanf(" %[^\n]%*c", &s[var_i].name);
You're passing the address of the pointer member name (i.e. you're passing a char **) to scanf() which per the format string, is expecting a char* and enough memory to hold the data it subsequently reads. This is invalid, is undefined behavior, and blindly overwrites data in the s[] array. Frankly I'm amazed this doesn't seg-fault your process.
Change this:
struct student
{
char* name;
int id;
float marks_1;
float marks_2;
};
To this:
struct student
{
char name[128]; // or some other suitable size.
int id;
float marks_1;
float marks_2;
};
And change this:
scanf(" %[^\n]%*c", &s[var_i].name);
To this:
scanf(" %[^\n]%*c", s[var_i].name);
I strongly suggest a size-limiter on that scanf() call as well, but I leave that to you to discover. Read about the API here.
Just use a loop.
here is some psudocode
bool isDuplicate = false
do
{
GetInput()
isDuplicate = CheckForDuplicate()
}while(isDuplicate);