the teacher gives me a code, I try to run it on visual basic 2019 but get Exception thrown at 0x7C43F338 (ucrtbased.dll).
I'm just introduced to c and have no clue what's wrong
here my code :
#include <cstdio>
#include <malloc.h>
#include <string.h>
//percobaan 1 dan 3
int main(){
printf("percobaan 1 dan 3\n");
struct dtnilai
{
char nrp[10];
char nama[20];
double nilai;
struct dtnilai* next;
};
struct dtnilai* ujung;
void sisip_awal_LIFO();
{
struct dtnilai* tampung = 0;
int j = 0; char jawab[2];
while (1)
{
ujung = (struct dtnilai*)malloc(sizeof(struct dtnilai));
fflush(stdin);
printf("NRP :"); scanf("%s", &ujung->nrp);
printf("Nama :"); scanf("%s", &ujung->nama);
printf("Nilai Test :"); scanf("%lf", &ujung->nilai);
if (j == 0)
{
ujung->next = NULL;
tampung = ujung;
}
else
{
ujung->next = tampung;
tampung = ujung;
}
printf("Ada data lagi(y/t):"); scanf("%s", &jawab);
if ((strcmp(jawab, "Y") == 0) || (strcmp(jawab, "y") == 0))
{
j++; continue;
}
else if ((strcmp(jawab, "T") == 0) || (strcmp(jawab, "t") == 0))
break;
}
}
void tampil_list();
{
struct dtnilai* tampil;
printf("Data Mahasiswa yang telah diinputkan :\n");
printf("NRP\tNama\tNilai\n");
tampil = ujung;
while (tampil != NULL)
{
printf("%s\t%s\t%6.2f\n", tampil->nrp, tampil->nama,
tampil->nilai);
tampil = tampil->next;
}
}
void sisip_stl_simpul();
{
struct dtnilai* sisip; struct dtnilai* stl;
char cari[20];
char nrp[10];
char nama[20];
double nilai;
struct dtnilai* next;
if (ujung == NULL)
printf("List Belum Terbentuk. Buatlah Dulu!");
else
{
ujung = (struct dtnilai*)malloc(sizeof(struct dtnilai));
sisip = (struct dtnilai*)malloc(sizeof(struct dtnilai));
printf("Masukkan Data Yang Akan Disisipkan \n");
printf("NRP :\n"); gets_s(sisip->nrp); //<- cant input
printf("Nama :\n"); gets_s(sisip->nama);
printf("Nilai Test :\n"); (sisip->nilai); //<-cant input
printf("Data disisipkan setelah data ? (nama) : ");
gets_s(cari);
//gets_s(cari);
stl = ujung;
while(strcmp(stl->nama, cari) != 0) //<- error
{
stl = stl->next;
}
sisip->next = stl->next;
stl->next = sisip;
}
}
void tampil_list();
{
struct dtnilai* tampil;
printf("Data Mahasiswa yang telah diinputkan :\n");
printf("NRP\tNama\tNilai\n");
tampil = ujung;
while (tampil != NULL)
{
printf("%s\t%s\t%6.2f\n", tampil->nrp, tampil->nama,
tampil->nilai);
tampil = tampil->next;
}
}
}
on this line
printf("NRP :\n"); gets_s(sisip->nrp); //<- cant input
printf("Nama :\n"); gets_s(sisip->nama);
printf("Nilai Test :\n"); (sisip->nilai); //<-cant input, also if i put gets_s in here i get error.
printf("Data disisipkan setelah data ? (nama) : ");
gets_s(cari);
the original was for gets_s was "gets" but "gets" get identifier is undefined, I also try with fgets, scanf but it just didn't work
sorry for my English.
Related
I'm new here. I started software engineering and I have no knowledge of the C language. I did the adding part to the queue, but I cannot separate the foreign values entered. Can you help me with this?
I want to perform the steps in the picture
For example:
Input: E)(=89y-/u665%P
Output: EYUP
My Code
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#define max 5
int insq(char queue[max][80], int *rear, char data[80])
{
if (*rear == max -1)
return(-1);
else
{
*rear = *rear + 1;
strcpy(queue[*rear], data);
return(1);
}
}
int delq(char queue[max][80], int *front, int *rear, char data[80])
{
if(*front == *rear)
return(-1);
else
{
(*front)++;
strcpy(data, queue[*front]);
return(1);
}
}
int main()
{
char queue[max][80], data[80];
int front, rear, reply;
int ch;
front = rear = -1; //... Initialize a Queue
printf("------------------------------\n");
printf("\tMenu");
printf("\n------------------------------");
printf("\n 1. Insert String in a Queue");
printf("\n 2. Delete String from a Queue");
printf("\n 3. Exit");
printf("\n------------------------------\n");
while(1)
{
printf("Choose operation : ");
scanf("%d", &ch);
switch(ch)
{
case 1 : // insert
printf("\nEnter Something : ");
scanf("%s",data);
reply = insq(queue, &rear, data);
if(reply == -1 )
printf("\nQueue is Full \n");
else
printf("\n'%s' is inserted in queue.\n\n",data);
break;
case 2 : // delete
reply = delq(queue, &front, &rear, data);
if( reply == -1 )
printf("\nQueue is Empty \n");
else
printf("\nDeleted String from Queue is : %s\n", data);
printf("\n");
break;
case 3 : exit(0);
default: printf("Invalid operation \n");
}
}
return 0;
}
You have to parse char by char your string.
Test if it is an char with isalpha then do toupper and happen it to the buffer out. If not test for a blank char and copy it as it, finally just skip char.
Don't forget to add the final \0
/!\ A test if missing to check if you don't overflow out
#include <stdio.h>
#include <ctype.h>
int main() {
const char *p = "E)(=89y-/u665%P";
char out[80];
char *q = out;
while (*p) {
if (isalpha(*p)) {
*q++ = toupper(*p++);
continue;
} else if (isblank(*p)) {
*q++ = *p++;
continue;
}
p++;
}
*q= '\0';
printf("%s\n", out);
return 0;
}
You have in out "EYUP"
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
a- Read and print the data from the file "detyra_day.dat"
b- Add another citizen when you know the IDNR is unique
c- Change the information of a citizen without changing IDNR
d- Create a "Permit to go outside" application for only 1 person per family per day
(the applicant can apply for another family member and the applicant must be over 18 years old)
and the "Permit to go outside" is granted from 8:00 to 17:00 which lasts 2 hours.
e- Check if a citizen does have permission to go outside (print IDNR, date and time).
f- Save
g- Print all "Permissions to go outside" for all citizens and families.
h- Print the list of 10 citizens that asked for the permission the most and 10 that asked the least (exclude the ones that didn't asked at all)
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <windows.h>
int permission;
int hour;
int minute;
int nr_people;
struct citizen{
char idnr[10];
char name[50];
char lname[50];
long int birthday;
int id_family;
};
struct birthday{
int year;
int month;
int day;
};
char fname[]={"detyra_day.dat"};
void readPeopleInfo(){
nr_people=0;
struct citizen s;
FILE *f;
f=fopen(fname,"r");
printf("\n========================================================\n\n");
printf("\t\t Details of all citizen \n\n");
printf("========================================================\n\n");
printf("IDNR\tname\tlname\tbirthday\tid_family\n\n");
if(f == NULL)
{
printf("Error opening file\n");
exit(1);
}
while(fread(&s,sizeof(struct citizen),1,f))
{
printf("%s\t",s.idnr);
printf("%s\t",s.name);
printf("%s\t",s.lname);
printf("%ld\t",s.birthday);
printf("%d\t\n\n",s.id_family);
nr_people++;
}
fclose(f);
printf("========================================================\n\n");
printf("Number of citizen = %d",nr_people);
}
void add(){
struct citizen s,s1;
int nr_people=5;
int found=0;
printf("\n Give the unique IDNR: ");
scanf("%s",&s1.idnr);
for(int i=0;i<nr_people;i++){
if(s1.idnr==s.idnr){
printf("The citizen with this IDNR exist");
found=1;
return;
}
}
if(found==0){
printf("The citizen with this IDNR doesn't 'exist");
strcpy(s.idnr,s1.idnr);
printf("\nGive the name of the citizen: ");
scanf("%s",s.name);
printf("\n Give the lname of the citizen: ");
scanf("%s",s.lname);
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%ld",&s.birthday);
printf("\n Give the ID of the family of the citizen: ");
scanf("%d",&s.id_family);
nr_people++;
}
}
void change(){
struct citizen s[50];
char *idnr;
printf("\n IDNR of citizen: ");
scanf("%s",&idnr);
for(int i=0;i<nr_people; i++){
if (strcmp(s[i].idnr,idnr)==0){
printf("\nGive the name of the citizen: ");
scanf("%s",s[i].name);
printf("\n Give the lname of the citizen: ");
scanf("%s",s[i].lname);
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%ld",&s[i].birthday);
printf("\n Give the ID of the family of the citizen: ");
scanf("%d",&s[i].id_family);
printf("\n Changed succesfully.");
return; }
printf("\n The change didn't happened.");
}
}
void permit(){
int permission;
struct birthday bday;
struct citizen s[50];
int age[nr_people];
SYSTEMTIME d;
GetLocalTime(&d);
for(int i=0;i<nr_people;i++){
if(bday.month>d.wMonth||(bday.month==d.wMonth&&bday.day>=d.wDay)){
age[i]=d.wYear-bday.year;
}
else{
age[i]=d.wYear-bday.year-1;
}
}
char *name;
char *lname;
char *chosenperson;
int id_family;
int i;
int apply=0;
int familymembers=0;
printf("Put your name: ");
scanf("%s",&name);
printf("Put your lname: ");
scanf("%s",&lname);
for (i=0;i<nr_people;i++){
if((strstr(name,s[i].name)==0&&strstr(lname,s[i].lname)==0&&age[i]>=18)){
printf("Your name is on the list and you are in the age to apply");
id_family=s[i].id_family;
apply=1;
}
}
if(apply==0){
printf("Your name is not on the list or you are not in the age to apply");
return;
}
struct citizen tmp;
for(i=0;i<nr_people;i++){
if(id_family==s[i].id_family){
tmp=s[50];
familymembers++;
}
}
for(i=0;i<familymembers;i++){
printf("%d. name: %10s",i+1,tmp.name);
}
apply=0;
printf("Give the name of the person from your family that you want to apply: ");
scanf("%s",chosenperson);
printf("\nYou chose: ");
for(i=0;i<familymembers;i++){
if(strstr(chosenperson,tmp.name)==0){
printf("%s",tmp.name);
apply=1;
}
}
if(apply==0){
printf("\nThe selected name is not on the list");
return;
}
printf("\nChose a time between 8:00 and 17:00: ");
float timez;
int hour;
int minute;
scanf("%f",&timez);
if(timez>=8.00&&timez<=17.00){
hour=timez;
minute=(timez-hour)*100;
if(minute>59){
printf("Minutes are placed wrong");
return;
}
printf("\nYour application to go out from %f to %f is accepted!",timez,timez+2);
permission=1;
}
else{
printf("You have chosen the wrong time");
return;
}
}
void control(){
permit();
struct citizen s[50];
SYSTEMTIME d;
GetLocalTime(&d);
int g=permission;
for(int i=0;i<nr_people;i++){
if(g==1){
printf("\n The citizen with IDNR: %s Date: %d/%d/%d Time: %d.%d has applied to go outside",s[nr_people].idnr,d.wYear,d.wMonth,d.wDay,hour,minute);
}
}
}
void save(){
struct citizen s[50];
FILE *f;
f=fopen("detyra_day.dat","w");
if (f==NULL){
printf("\n Error on the file");
return;
}
for(int i=0;i<nr_people; i++){
fwrite(&s[i],sizeof(struct citizen),1,f);
}
}
int main(){
char selection;
do{
printf("\n=============================");
printf("\n 1 - Read and print the data from the file detyra_day.dat");
printf("\n 2 - Add a citizen");
printf("\n 3 - Change a citizen");
printf("\n 4 - Create a Permit to go outside");
printf("\n 5 - Control the permission");
printf("\n 6 - Save");
printf("\n 7 - Print all Permissions to go outside for all citizens and families");
printf("\n 8 - Print the list of 10 citizens that asked for the permission the most and 10 that asked the least (exclude the ones that didn't asked at all)");
printf("\n 9 - Exit");
printf("\n-----------------------------");
printf("\n Zgjedhja : ");
selection=getch();
switch(selection){
case '1':
readPeopleInfo();
break;
case '2':
add();
break;
case '3':
change();
break;
case '4':
permit();
break;
case '5':
control();
break;
case '6':
save();
break;
case '9':
exit(0);
}
getch();
} while(selection!='9');
return 0;
}
After I press Run and try number 1 which is read and print it prints every person as 1 not as the struct says. For example I want to print it like this:
IDNR: H65328040Q
Name: Azbie
Lname: Gockaj
Birthday (YYYYMMDD format):19760328
ID_Family: 1
Instead I get:
INDR: Name: Lname: Birthday: ID_Family:
and then every person ordered
This is the detyra_day.dat file
H65328040Q Azbie Gockaj 19760328 1
J70507042S Ledion Celaj 19970507 1
G70312202S Pellumb Osmani 19670312 2
H45827189P Albina Osmani 19740827 2
There are a number of errors.
First, you need a global array of struct citizen instead of having a function scoped struct citizen in each function.
In struct citizen, idNr was too small to contain a 10 digit ID number. It has to be [at least] one more to account for the EOS char at the end of the string.
Using fread and fwrite to access the data file. They are for binary files, but you have a text file. You need to use fscanf and fprintf respectively.
Using (e.g.) a [function scoped] char *name;. This is a pointer to a char [array/string] and it is uninitialized. Change this to char name[100];
Using strstr instead of strcmp.
Use of scanf or fscanf was inconsistent. If you had compiled with -Wall -Wextra to enable warnings [gcc], they would have become apparent.
It's bad practice to intermix getch [fgetc] and scanf on the same stream.
For consistency, I've added a prompt function instead of the various printf(...); scanf(...); sequences for prompting the user.
You didn't really use your struct birthday in the code.
Here's the cleaned up code. Some basics have been tested, but there are still some issues I couldn't get to. In most places, I've used #if 0 to denote your old code [vs. my new code]
#include <stdio.h>
#include <string.h>
#ifndef __linux__
#include <conio.h>
#include <dos.h>
#endif
#include <windows.h>
#ifdef __linux__
#include <time.h>
int
getch(void)
{
char buf[1000];
int chr;
if (fgets(buf,sizeof(buf),stdin) != 0)
chr = buf[0];
else
chr = -1;
return chr;
}
WINBASEAPI VOID WINAPI
GetLocalTime(LPSYSTEMTIME lps)
{
time_t tod;
struct tm *tm;
tod = time(NULL);
tm = localtime(&tod);
lps->wYear = tm->tm_year + 1900;
lps->wMonth = tm->tm_mon + 1;
lps->wDayOfWeek = tm->tm_wday;
lps->wDay = tm->tm_mday;
lps->wHour = tm->tm_hour;
lps->wMinute = tm->tm_min;
lps->wSecond = tm->tm_sec;
lps->wMilliseconds = 0;
}
#endif
int permission;
int hour;
int minute;
int nr_people;
struct birthday {
int year;
int month;
int day;
};
struct citizen {
#if 0
char idnr[10];
#else
char idnr[10 + 1];
#endif
char name[50];
char lname[50];
struct birthday birthday;
int id_family;
};
#define CITMAX 50
struct citizen citlist[CITMAX];
char fname[] = { "detyra_day.dat" };
void
prompt(const char *str,char *buf)
{
printf("%s: ",str);
fflush(stdout);
fgets(buf,100,stdin);
char *cp = strchr(buf,'\n');
if (cp != NULL)
*cp = 0;
}
void
getbday(const char *buf,struct birthday *bday)
{
sscanf(buf,"%4d%2d%2d",&bday->year,&bday->month,&bday->day);
}
void
loadPeopleInfo()
{
struct citizen *s;
char birthday[100];
FILE *f;
nr_people = 0;
f = fopen(fname, "r");
if (f == NULL) {
printf("Error opening file\n");
exit(1);
}
while (1) {
s = &citlist[nr_people];
if (fscanf(f," %s %s %s %s %d\n",
s->idnr,s->name,s->lname,birthday,&s->id_family) != 5)
break;
getbday(birthday,&s->birthday);
nr_people++;
if (nr_people >= CITMAX)
break;
}
fclose(f);
}
void
printPeopleInfo()
{
struct citizen *s;
printf("\n========================================================\n\n");
printf("\t\t Details of all citizen \n\n");
printf("========================================================\n\n");
printf("IDNR\t\tname\tlname\tbirthday\tid_family\n\n");
for (int i = 0; i < nr_people; ++i) {
s = &citlist[i];
printf("%s\t", s->idnr);
printf("%s\t", s->name);
printf("%s\t", s->lname);
struct birthday *bday = &s->birthday;
printf("%4.4d%2.2d%2.2d\t",bday->year,bday->month,bday->day);
printf("%d\t\n", s->id_family);
}
printf("========================================================\n\n");
printf("Number of citizen = %d\n", nr_people);
}
void
add()
{
#if 0
struct citizen s, s1;
#else
struct citizen *s;
struct citizen s1;
#endif
#if 0
int nr_people = 5;
#endif
int found = 0;
char buf[100];
#if 0
printf("\n Give the unique IDNR: ");
scanf("%s\n", &s1.idnr);
#else
prompt("Give the unique IDNR",s1.idnr);
#endif
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
#if 0
if (s1.idnr == s->idnr) {
#else
if (strcmp(s1.idnr,s->idnr) == 0) {
printf("The citizen with this IDNR exist\n");
found = 1;
return;
}
#endif
}
if (found == 0) {
s = &citlist[nr_people];
printf("The citizen with this IDNR doesn't 'exist\n");
strcpy(s->idnr, s1.idnr);
#if 0
printf("\nGive the name of the citizen: ");
scanf("%s\n", s->name);
#else
prompt("Give the name of the citizen",s->name);
#endif
#if 0
printf("\n Give the lname of the citizen: ");
scanf("%s\n", s->lname);
#else
prompt("Give the lname of the citizen",s->lname);
#endif
#if 0
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%s\n",buf);
#else
prompt("Give the birthday of the citizen in the format YYYYMMDD",buf);
#endif
getbday(buf,&s->birthday);
#if 0
printf("\n Give the ID of the family of the citizen: ");
scanf("%d\n", &s->id_family);
#else
prompt("Give the ID of the family of the citizen",buf);
sscanf(buf,"%d", &s->id_family);
#endif
nr_people++;
}
}
void
change()
{
struct citizen *s;
char birthday[100];
#if 0
char *idnr;
#else
char idnr[100];
#endif
printf("\n IDNR of citizen: ");
#if 0
scanf("%s", &idnr);
#else
scanf("%s\n",idnr);
#endif
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
if (strcmp(s->idnr, idnr) == 0) {
printf("\nGive the name of the citizen: ");
scanf("%s\n", s->name);
printf("\n Give the lname of the citizen: ");
scanf("%s\n", s->lname);
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%s\n", birthday);
getbday(birthday,&s->birthday);
printf("\n Give the ID of the family of the citizen: ");
scanf("%d\n", &s->id_family);
printf("\n Changed succesfully.");
return;
}
#if 0
printf("\n The change didn't happened.");
#endif
}
#if 1
printf("\n The change didn't happened.");
#endif
}
void
permit()
{
#if 0
struct birthday bday;
#else
struct birthday *bday;
#endif
struct citizen *s;
int age[nr_people];
SYSTEMTIME d;
GetLocalTime(&d);
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
bday = &s->birthday;
if (bday->month > d.wMonth ||
(bday->month == d.wMonth && bday->day >= d.wDay)) {
age[i] = d.wYear - bday->year;
}
else {
age[i] = d.wYear - bday->year - 1;
}
}
#if 0
char *name;
char *lname;
char *chosenperson;
#else
char name[100];
char lname[100];
char chosenperson[100];
#endif
int id_family;
int i;
int apply = 0;
int familymembers = 0;
#if 0
printf("Put your name: ");
scanf("%s", &name);
#else
prompt("Put your name",name);
#endif
#if 0
printf("Put your lname: ");
scanf("%s", &lname);
#else
prompt("Put your lname",lname);
#endif
// NOTE/BUG: use strcmp instead of strstr
for (i = 0; i < nr_people; i++) {
s = &citlist[i];
if ((strcmp(name, s->name) == 0 && strcmp(lname, s->lname) == 0 &&
age[i] >= 18)) {
printf("Your name is on the list and you are in the age to apply [%d]\n",age[i]);
id_family = s->id_family;
apply = 1;
}
}
if (apply == 0) {
printf("Your name is not on the list or you are not in the age to apply");
return;
}
struct citizen tmp[nr_people];
for (i = 0; i < nr_people; i++) {
s = &citlist[i];
if (id_family == s->id_family) {
tmp[familymembers++] = *s;
}
}
for (i = 0; i < familymembers; i++) {
printf("%d. name: %10s\n", i + 1, tmp[i].name);
}
apply = 0;
prompt("Give the name of the person from your family that you want to apply ",chosenperson);
printf("\nYou chose: ");
for (i = 0; i < familymembers; i++) {
if (strcmp(chosenperson, tmp[i].name) == 0) {
printf("%s", tmp[i].name);
apply = 1;
}
}
if (apply == 0) {
printf("\nThe selected name is not on the list");
return;
}
printf("\nChose a time between 8:00 and 17:00: ");
float timez;
int hour;
int minute;
scanf("%f", &timez);
if (timez >= 8.00 && timez <= 17.00) {
hour = timez;
minute = (timez - hour) * 100;
if (minute > 59) {
printf("Minutes are placed wrong");
return;
}
printf("\nYour application to go out from %f to %f is accepted!",
timez, timez + 2);
permission = 1;
}
else {
printf("You have chosen the wrong time");
return;
}
}
void
control()
{
permit();
SYSTEMTIME d;
struct citizen *s;
GetLocalTime(&d);
int g = permission;
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
if (g == 1) {
printf("\n The citizen with IDNR: %s Date: %d/%d/%d Time: %d.%d has applied to go outside",
s->idnr, d.wYear, d.wMonth, d.wDay, hour, minute);
}
}
}
void
save()
{
struct citizen *s;
struct birthday *bday;
FILE *f;
f = fopen("detyra_day.dat", "w");
if (f == NULL) {
printf("\n Error on the file");
return;
}
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
fprintf(f,"%s ", s->idnr);
fprintf(f,"%s ", s->name);
fprintf(f,"%s ", s->lname);
bday = &s->birthday;
fprintf(f,"%4.4d%2.2d%2.2d ",bday->year,bday->month,bday->day);
fprintf(f,"%d\n", s->id_family);
}
#if 1
fclose(f);
#endif
}
int
main()
{
char buf[100];
int selection = 0;
loadPeopleInfo();
do {
printf("\n=============================");
printf("\n 1 - Read and print the data from the file detyra_day.dat");
printf("\n 2 - Add a citizen");
printf("\n 3 - Change a citizen");
printf("\n 4 - Create a Permit to go outside");
printf("\n 5 - Control the permission");
printf("\n 6 - Save");
printf("\n 7 - Print all Permissions to go outside for all citizens and families");
printf("\n 8 - Print the list of 10 citizens that asked for the permission the most and 10 that asked the least (exclude the ones that didn't asked at all)");
printf("\n 9 - Exit");
printf("\n-----------------------------\n");
prompt("Zgjedhja",buf);
selection = buf[0];
switch (selection) {
case '1':
printPeopleInfo();
break;
case '2':
add();
break;
case '3':
change();
break;
case '4':
permit();
break;
case '5':
control();
break;
case '6':
save();
break;
#if 0
case '9':
exit(0);
#endif
}
#if 0
getch();
#endif
} while (selection != '9');
return 0;
}
The read_to_list function is designed to scan the contents of a file - dump.txt - and load it into the array of singly linked lists.
The problem lies in LINE 2 of the main function: read_to_list(argv[1]);
The dump.txt file contains the following information:
Name Group Size
----------------------------------
Anna 2
Bill 4
Connor 6
Denise 8
The argv[1] correlates to a text file that I declare on the command line to dump data from my linked list after running the program. After exiting the program the .txt file saves the data in the above format format.
I do not know why I am getting a segmentation fault when calling the read_to_list function on the file passed in the CLI as it appears to me that the function should load the data correctly and the function is called at the right position in the main function.
Thank you for any and all help that I can get!
The code is below:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{
char name[20];
int size;
struct node *next;
}node;
node* head[4]={NULL,NULL,NULL,NULL};
node* tail[4]={NULL,NULL,NULL,NULL};
void read_to_list(char *filename)
{
FILE *fp;
int mined_partysize;
char mined_partyname[20];
char header = "Name\t\tGroup Size\n----------------------------------\n";
fp = fopen(filename, "r");
if (fp == NULL)
return;
fseek(fp, strlen(header), SEEK_SET);
printf("This is working1");
while(fscanf(fp, "%s%d", mined_partyname, &mined_partysize) == 2)
{
printf("This is working2");
if(mined_partysize == 0)
{
printf("\nThat is not a valid command. Party not added!\n");
}
if(mined_partysize >= 1 && mined_partysize <= 2)
{
add_party(0, mined_partyname, mined_partysize);
}
else if(mined_partysize >= 3 && mined_partysize <= 4)
{
add_party(1, mined_partyname, mined_partysize);
}
else if(mined_partysize >= 5 && mined_partysize <= 6)
{
add_party(2, mined_partyname, mined_partysize);
}
else if(mined_partysize >= 7)
{
add_party(3, mined_partyname, mined_partysize);
}
}
fclose(fp);
return;
}
//
// main function
//
int main(int argc, char *argv[])
{
int x;
read_to_list(argv[1]);
while (1)
{
fflush(stdin);
printf("\n\nEnter 1 to add a party\nEnter 2 to remove a party\nEnter 3 for the list of the party\nEnter 4 to change party size.\nEnter 5 to quit.\n\n");
// user interface
scanf("%d",&x);
char name[20];
int size;
switch(x)
{
case 1:
printf("\nParty Name: ");
scanf("%s", name);
printf("\nParty Size: ");
scanf("%d", &size);
if(size == 0)
{
printf("\nThat is not a valid command. Party not added!\n");
}
if(size >= 1 && size <= 2)
{
add_party(0, name, size);
}
else if(size >= 3 && size <= 4)
{
add_party(1, name, size);
}
else if(size >= 5 && size <= 6)
{
add_party(2, name, size);
}
else if(size >= 7)
{
add_party(3, name, size);
}
break;
case 2:
printf("\nSize of party to delete: ");
scanf("%i", &size);
delete_party(NULL, size);
break;
case 3:
list_parties();
break;
case 4:
change_partysize(name, size);
break;
case 5:
write_to_file(argv[1]);
exit(0);
break;
default:
continue;
}
}
}
//
//add function
//
void add_party(int h, char *name, int size)
{
//declare file pointer
FILE *fp;
//to be used by fscanf
int number;
//create a new node
int i=0;
int breaker = 0;
node *p;
node *new_item;
new_item = (node *)malloc(sizeof(node)); // allocate memory the size of the struct
strcpy(new_item->name,name);
new_item->size = size;
if(head[h] == NULL && tail[h] == NULL) // if an empty list, create a head and tail
{
head[h] = new_item;
tail[h] = head[h];
new_item->next = NULL;
return;
}
//traversal
for(i=0; i<4; i++)
{
p = head[i];
while(p != NULL)
{
//check that no repeating names. delete nodes that do have repeating names
if(strcmp(p->name,name) == 0)
{
printf("\nSorry, that name is already taken\n");
free(new_item);
return;
}
p = p->next; //go to the next node in the list
}
}
tail[h]->next = new_item;
new_item->next = NULL;
tail[h] = new_item;
}
You're de-referencing a null pointer.
I'm learning C data structures. I've the following code, which is resulting in a segmentation fault.
I've used the hash function from K&R C (2nd Ed.).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASHSIZE 101
typedef struct Details
{
char *name;
float checkTotal;
float tipTotal;
int numReciepts;
struct Details *next;
struct Details *prev;
} det;
static det *hashtab[HASHSIZE];
char *str_dup(char *);
det *lookup(char *);
det *insert(char *, float, float);
unsigned hash(char *);
void printData(char *);
int main()
{
printf("1. Enter details.\n");
printf("2. Print List of employees.\n");
char *s;
float cT; //checkTotal
float tT; //tipTotal
while (1)
{
int command = 0;
printf("Enter option: ");
scanf("%d", &command);
if (command == 1)
{
printf("Enter name: ");
scanf("%s", s);
printf("Enter check total: ");
scanf("%f", &cT);
printf("Enter tip total: ");
scanf("%f", &tT);
insert(s, cT, tT);
}
else if (command == 2)
{
char *p;
printf("Enter name of employee: ");
scanf("%s", p); //including this line causes seg fault.
printData(p);
}
else
break;
}
return 0;
}
unsigned hash(char *s)
{
unsigned hashval;
for (hashval = 0; *s != '\0'; *s++)
hashval = *s + 31 * hashval;
return hashval % HASHSIZE;
}
det *lookup(char *name)
{
det *ptr;
for (ptr = hashtab[hash(name)]; ptr != NULL; ptr = ptr->next)
{
if (strcmp(name, ptr->name) == 0)
return ptr;
}
return NULL;
}
det *insert(char *name, float cT, float tT)
{
det *new;
unsigned hashval;
if ((new = lookup(name)) == NULL)
{
new = (det *)malloc(sizeof(new));
if (new == NULL || (new->name = str_dup(name)) == NULL)
return NULL;
hashval = hash(name);
new->next = hashtab[hashval];
hashtab[hashval] = new;
new->checkTotal += cT;
new->tipTotal += tT;
new->numReciepts++;
printf("Details of '%s' inserted.\n", name);
}
else
{
new->checkTotal += cT;
new->tipTotal += tT;
new->numReciepts++;
printf("Details of '%s' updated.\n", name);
}
}
char *str_dup(char *s)
{
char *p;
p = (char *)malloc(strlen(s) + 1);
if (p != NULL)
strcpy(p, s);
return p;
}
void printData(char *p)
{
det *ptr;
if ((ptr = lookup(p)) != NULL)
{
printf("Emplyee Name : %s\n", ptr->name);
printf("Total amount : %6.2f\n", ptr->checkTotal);
printf("Total tip : %6.2f\n", ptr->tipTotal);
printf("Total reciepts: %6.2d\n", ptr->numReciepts);
}
else
{
printf("Employee '%s' does not exist.\n", p);
return;
}
}
Without the inclusion of scanf() in else if:main, every thing works fine. Calling printData() with a hard coded string also works.
Inclusion of scanf() in else if:main results in segmentation fault after prompting for name.
I have tried and can not think of the reason. As far as I know:
my code in if:main is not accessing anything in else if:main.
if should not break because of something wrong in else if even if it is wrong. (at least in this scenario, or as far as my understanding goes)
Thanks and any tips for future from experts are appreciated!
P.S: scanf():if is working perfectly.
We have a small program where the input comes from a text file (see text sample below) and is used to scan and write certain student information to different struct variables. However, when the add_student() function is called it gives this bizzare output (see screenshot below).
struct student_list sl;
struct teacher_list tl;
struct data {
char *name;
int number;
char index;};
struct student {
struct data *d;
struct student *next;};
struct student_list{
int size;
struct student *front;
struct student *tail;};
struct teacher{
struct data *d;
struct teacher *next;};
struct teacher_list{
int size;
struct teacher *front;
struct teacher *tail;};
void main()
{
readAndLoad();
print_students();
}
void readAndLoad()
{
int c;
int i=0;
char line[200];
int number, semNum;
char name[100];
char index;
while ((c=getchar())!=EOF)
{
if(c != '\n')
{
line[i++] = c;
line[i] = '\0';
/*printf("%c ", c);
printf("%s \n", line);*/
}else
{
//printf("\n");
int j, b;
b = 0;
for (j = 0; j < sizeof(line); j++)
{
if (line[j] == ' ')
++b;
}
//printf("%s \n", line);
if (b == 2)
{
if (line[0] == 'S')
{
sscanf(line, "S %d %s", &number, name);
struct student *studentnode;
studentnode = malloc(sizeof(struct student));
add_student(&studentnode, number, &name);
} else if (line[0] == 'T')
{
sscanf(line, "T %d %s", &number, name);
struct teacher *teachernode;
teachernode = malloc(sizeof(struct teacher));
add_teacher(&teachernode, number, &name);
}
}
memset(&line[0], 0, sizeof(line));
i=0;
}
}
//printf(line);
}
void add_student(struct student *n, int student_number, char *student_name)
{
//---------------------------------------------------
printf("%s\n", student_name);
n->d->name = student_name;
n->d->number = student_number;
n->d->index = 'S';
n->next = 0;
printf("%s\n", n->d->name);
//---------------------------------------------------
if (sl.size == 0)
{
sl.front = n;
sl.tail = n;
printf("%s %d \n", n->d->name, n->d->number);
} else
{
sl.tail->next = n;
sl.tail = n;
printf("%s %d \n", n->d->name, n->d->number);
}
sl.size++;
printf("Student added\n");
}
void add_teacher(struct teacher *n, int number, char *name)
{
n->d->name = name;
n->d->number = number;
n->d->index = 'T';
n->next = 0;
if (tl.size == 0)
{
tl.front = n;
tl.tail = n;
} else
{
tl.tail->next = n;
tl.tail = n;
}
tl.size++;
printf("Teacher added\n");
}
void print_students()
{
int i;
struct student *s = sl.front;
for (i = 0; i < sl.size; i++)
//while (s->next != 0)
{
if (i == (sl.size - 2))
{
printf("%c %s %d", s->d->index, s->d->name, s->d->number);
} else
{
printf("%c %s %d \n", s->d->index, s->d->name, s->d->number);
s = s->next;
}
}
}
Input text file sample
here is the output
Between the highlighted part //-------------------
in the code we can see a correct output of the name from the first printf() but when we go to the second printf() it only prints the blank space... Do you know what could be the problem?
Input text file:
S 123456 Ivan
S 654321 Georgi
T 123456 Jesper
T 123457 Ole
T 123458 Lars
T 123459 Erland
C 31 CALI1 3
C 11 WDDI1 1
C 21 SDJI2 2
E 123456 31
E 123456 11
E 654321 21
A 123456 31
A 123457 11
Console output:
Ivan
123456
Student added
Georgi
,▒( 654321
Student added
Teacher added
Teacher added
Teacher added
Teacher added
E 0▒( 2673448E 0▒( 2673448
studentnode = malloc(sizeof(struct student));
only allocates memory for an instance of student. The memory for studentnode->d has not been allocated. Therefore any n->d->something in add_student() is invalid, thus invokes undefined behavior.