segmentation fault using scanf [duplicate] - c

This question already has answers here:
using scanf function with pointers to character
(6 answers)
Closed 3 years ago.
noob question here:
I'm trying to write a simple menu interface, but I keep getting a segmentation fault error and I can't figure out why.
#include <stdlib.h>
#include <stdio.h>
int flush(); int add(char *name, char *password, char *type); int delete(char *name);
int edit(char *name, char *password, char *type, char *newName, char *newPassword, char *newType);
int verify(char *name, char *password);
int menu(){
int input;
char *name, *password, *type, *newName, *newPassword, *newType;
printf("MAIN MENU \n ============\n");
printf("1. ADD\n");
printf("2. DELETE\n");
printf("3. EDIT\n");
printf("4. VERIFY\n");
printf("5. Exit\n");
printf("Selection:");
scanf("%d", &input);
flush();
switch (input){
case 1:
printf("%s\n", "Enter Name:");
scanf("%s", name);
flush();
printf("%s\n", "enter password" );
scanf("%s", password);
flush();
printf("%s\n","enter type" );
scanf("%s",type);
add(name, password, type);
menu();
break;
case 2:
printf("Enter Name:" );
scanf("%s",name);
flush();
delete(name);
menu();
break;
case 3:
printf("Enter Name:\n");
scanf("%s",name);
flush();
printf("Enter Password\n");
scanf("%s", password);
flush();
printf("enter type:\n");
scanf("%s", type);
flush();
printf("enter your new username:\n");
scanf("%s",newName);
flush();
printf("enter your new password\n");
scanf("%s", newPassword);
flush();
printf("enter your new type\n");
scanf("%s",newType);
flush();
edit(name, password, type, newName, newPassword, newType);
menu();
break;
case 4:
printf("Enter Name\n");
scanf("%s",name);
flush();
printf("Enter Password\n");
scanf("%s",password);
flush();
verify(name, password);
menu();
break;
case 5:
return 0;
default:
printf("invalid input, please select from the following:\n");
menu();
}
return 0;
}
int flush(){
int ch;
while ((ch = getchar()) != EOF && ch != '\n') ;
return 0;
}
I get the segmentation fault after entering two fields, in any menu option

You need to initialize your pointers. Alternatively, use stack-allocated arrays.
For example, instead of char *name, do char name[20]. (Note that this will limit your input to 19 characters; use a larger buffer if necessary.)
Right now, you are passing uninitialized pointers into scanf() which effectively means that scanf() is going to write to an undefined area of memory. It might work on one execution and then fail on the next. It might corrupt memory elsewhere in the process' address space.
Don't use uninitialized variables, and consider turning up your compiler warnings as high as they will go; the compiler can catch errors like this and emit a warning.

Instead of using *name, *password,.. use name[100], password[100],... If you want name, password, .. to be pointer then allocate memory using malloc or calloc before calling scanf.

Related

C - Passing Structure Parameters to Function By Reference and Value

Could I please have an explanation of what I am doing wrong.The program is for inputting and displaying student details. It must use a structure and have 2 functions; one to capture(which is to be passed by reference) and another to display (which is to be passed by value.
Here is my code:
#include <stdio.h>
struct Students{
int ID;
char name[50];
int age;
char address[100];
char course[30];
} aStudent[5];
void capture(char *name , int *age , char *address, char *course){
int i;
for(i=0; i<5; i++){
aStudent[i].ID = i+1;
printf("\nFor Student number %d:\n",aStudent[i].ID);
printf("Enter Student Name: ");
scanf ("%s", &aStudent[i].name);
printf("Enter Student Age: ");
scanf ("%d", &aStudent[i].age);
printf("Enter Student Address: ");
scanf ("%s", &aStudent[i].address);
printf("Enter Course: ");
scanf ("%s", &aStudent[i].course);
}
}
void display(char name, int age , char address, char course){
int i;
for(i=0; i<5; i++){
printf("\nStudent %d:\n",aStudent[i].ID);
printf("Name: %s\t\tAge: %d\t\tAddress: %s\t\tCourse:
%s",aStudent[i].name, aStudent[i].age, aStudent[i].address,
aStudent[i].course);
printf("\n");
}
}
void main()
{
int option, age;
char name, address, course;
printf("\t...Welcome to the Student Data System...\n\n");
printf("\nPlease Select An Option: \n1. Input Student Data\n2. View
Student Data\n3. Exit Syatem\n\n");
scanf("%d",&option);
switch(option){
case 1:
printf("Enter Student Details:\n");
capture(name, age , address, course);
break;
case 2:
printf("\nDisplaying Information:\n");
display(name, age , address, course);
break;
case 3:
close();
break;
default:
printf("\nSorry, your option is not valid.");
}
}
I have tested a number of times and it's working, but I'm getting these error messages:
Errors are shown for every argumety I've used
Also, is there a way or a line(s) of code i can use to return to the start of the switch when I am done with one of the cases - A "Return to Main Menu"?
First of all, variables you have tried to pass (either by value or by reference) when you are calling the two functions capture() and display(), haven't used anywhere because you are dealing directly with the members of the structure Students when you are capturing or displaying the results.
And the reasons you are getting syntax errors are because the capture() is expecting the addresses of the variables (&name,&age,&address,&course) and you are passing variables (name,age,address,course) themselves. And also you are using,
scanf ("%s", &aStudent[i].name);
instead of
scanf ("%s", aStudent[i].name);
In my opinion instead of making the Structure array global, declaring it inside main function and passing the whole structure array to the capture() as a reference and passing it by value to the display() is better to your objective as you need to use both call by value and reference in your code.
I have edited your code a bit and added the return to main menu option. It works for me and I apologize if my answer is long and hard to understand because this is my first answer in stackoverflow. Thanks!
#include <stdio.h>
struct Students
{
int ID;
char name[50];
int age;
char address[100];
char course[30];
};
void capture(struct Students *aStudent)
{
int i;
for(i=0; i<2; i++)
{
aStudent[i].ID = i+1;
printf("\nFor Student number %d:\n",aStudent[i].ID);
printf("Enter Student Name: ");
scanf ("%s", aStudent[i].name);
printf("Enter Student Age: ");
scanf ("%d", &aStudent[i].age);
printf("Enter Student Address: ");
scanf ("%s", aStudent[i].address);
printf("Enter Course: ");
scanf ("%s", aStudent[i].course);
}
}
void display(struct Students aStudent[])
{
int i;
for(i=0; i<2; i++)
{
printf("\nStudent %d:\n",aStudent[i].ID);
printf("Name: %s\t\tAge: %d\t\tAddress: %s\t\tCourse: %s",aStudent[i].name, aStudent[i].age, aStudent[i].address,aStudent[i].course);
printf("\n");
}
}
void main()
{
struct Students aStudent[2];
int option;
char choice = 'Y';
printf("\t...Welcome to the Student Data System...\n\n");
while(choice == 'Y' || choice == 'y')
{
printf("\nPlease Select An Option: \n1. Input Student Data\n2. View Student Data\n3. Exit Syatem\n\n");
scanf("%d",&option);
switch(option)
{
case 1:
printf("Enter Student Details:\n");
capture(aStudent);
printf("Return to main menu? (Y/N) :");
scanf(" %c",&choice);
break;
case 2:
printf("\nDisplaying Information:\n");
display(aStudent);
printf("Return to main menu? (Y/N) :");
scanf(" %c",&choice);
break;
case 3:
close();
break;
default:
printf("\nSorry, your option is not valid.");
}
}
}
You have not initialized your string instead you have initialized a character! char name, address, course; If you have used 'char *name, *address, *course;' or char name[100], address[100], course[100]; you might have got the answer ! If you use the above case you should scan using scanf("%s",name); ! Hope I answered your question !

.exe has stopped working (Cprogramming)

I am running this program and keep getting an error after I input my name
"program1.exe has stopped working"
have no idea why any help?
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
void create();
//void edit();
//void delete();
int main()
{
char choice;
printf("\n\t\t **********************\n\n");
printf("\n\t\t Train Booking Application\n");
printf("\n\t\t **********************\n\n");
printf("Select 1 to create a booking,\tSelect 2 to Edit booking,\tSelect 3 to Delete a booking\n");
scanf("%d",&choice);
if (choice == 1){
create();
}
return 0;
}
void create(){
char Fname,Sname;
printf("Please enter your First name:\n");
scanf ("%s",Fname);
printf("Please enter your Second name:\n");
}
char is used to read one character. Use string instead.
%d is used for reading integers but you defined . Either use
int choice;
or use
scanf("%s", &choice);
try to use a switch for your selection too
switch(choice){
case 1:
create();
break;
case default:
//default statement(s)
}
Please pay attention to the compiler warnings. It will discover problems for you. Suggestion for improvements in the program comments:
#include <stdio.h>
#include <stdlib.h>
//#include <iostream> // C++ include, not needed!
void create();
int main()
{
int choice; // changed to int to match scanf("%d", char is to small to hold an `int`
printf("\n\t\t **********************\n\n");
printf("\n\t\t Train Booking Application\n");
printf("\n\t\t **********************\n\n");
printf("Select 1 to create a booking,\tSelect 2 to Edit booking,\tSelect 3 to Delete a booking\n");
scanf("%d", &choice);
switch (choice){ // switch is a better choice than nested ifs
case 1:
create();
break;
default:
printf("not implemented yet...\n");
break;
}
return 0;
}
void create(){
char Fname[256],Sname[256]; // changed to arrays to match scanf ("%s"
// char Fname, Sname with %s would destroy memory
printf("Please enter your First name:\n");
scanf ("%s",Fname);
printf("Please enter your Second name:\n");
scanf ("%s",Sname);
}
As char just store one character and your name is longer than that, try using char Fname[], for storing your entire name.

Structure and fflush(stdin)

#include <stdio.h>
#include <stdlib.h>
struct Person{
char codeChacter[20];
char fullName[30];
int Iq, Eq;
};
int main(){
struct Person cha1, cha2;
printf("Enter detail of character 1: \n");
printf("code Character: ");
gets(cha1.codeChacter);
fflush(stdin);
printf("Full Name: ");
gets(cha1.fullName);
fflush(stdin);
printf("Enter Iq and Eq: ");
scanf("%d%d", &cha1.Iq, &cha1.Eq);
printf("Enter detail of character 2: \n");
printf("code Character: ");
gets(cha2.codeChacter);
fflush(stdin);
printf("Full Name: ");
gets(cha2.fullName);
fflush(stdin);
printf("Enter Iq and Eq: ");
scanf("%d%d", &cha2.Iq, &cha2.Eq);
printf("\n---------------------Detail------------------\n");
printf("%s\t%s\t%d\t%d\n", cha1.codeChacter, cha1.fullName, cha1.Iq, cha1.Eq);
printf("%s\t%s\t%d\t%d\n", cha2.codeChacter, cha2.fullName, cha2.Iq, cha2.Eq);
return 0;
}
This is my first program in structure. When I run this application, it work but it not right with my mind. So can you help me change my fail? Thanks very much!
scanf("%d%d", (pointers to read)); won't remove the newline character from the input stream, then the gets will read the newline character and won't work as "expected".
don't use fflush(stdin);, which is undefined behavior.
don't use gets(), which has risk of buffer overrun.
Possible fix:
#include <stdio.h>
#include <stdlib.h>
struct Person{
char codeChacter[20];
char fullName[30];
int Iq, Eq;
};
char* read_line(char *out, size_t bufsize){
char *lf;
if (fgets(out, bufsize, stdin) == NULL) return NULL;
/* remove the newline character because fgets store it while gets donesn't */
for (lf = out; *lf != '\0'; lf++){
if (*lf == '\n'){
*lf = '\0';
break;
}
}
return out;
}
int main(void){
char read_buf[1024];
struct Person cha1, cha2;
printf("Enter detail of character 1: \n");
printf("code Character: ");
read_line(cha1.codeChacter, sizeof(cha1.codeChacter));
printf("Full Name: ");
read_line(cha1.fullName, sizeof(cha1.fullName));
printf("Enter Iq and Eq: ");
read_line(read_buf, sizeof(read_buf));
sscanf(read_buf, "%d%d", &cha1.Iq, &cha1.Eq);
printf("Enter detail of character 2: \n");
printf("code Character: ");
read_line(cha2.codeChacter, sizeof(cha2.codeChacter));
printf("Full Name: ");
read_line(cha2.fullName, sizeof(cha2.fullName));
printf("Enter Iq and Eq: ");
read_line(read_buf, sizeof(read_buf));
sscanf(read_buf, "%d%d", &cha2.Iq, &cha2.Eq);
printf("\n---------------------Detail------------------\n");
printf("%s\t%s\t%d\t%d\n", cha1.codeChacter, cha1.fullName, cha1.Iq, cha1.Eq);
printf("%s\t%s\t%d\t%d\n", cha2.codeChacter, cha2.fullName, cha2.Iq, cha2.Eq);
return 0;
}
Using this code, you have to enter Iq and Eq in the same line and you can't insert any blank line before inputting Iq and Eq, while the program using scanf won't require that.

why my program stops working when type enter?

My main goal for this code is to capture the users input and do whatever he wants to do with the choices I have presented, but I'm stuck: when I compile, I can only type the word and the program stops working.
i have no idea where I'm making a mistake.
The is my code:
#include <stdio.h>
#include <string.h>
#define MAX_STRING_LENGTH 100
void grab_user_input(void);
void load_menu(void);
void Count_the_letters(void);
int main(void)
{
grab_user_input();
return 0;
}
void grab_user_input(void)
{
char word;
{
printf("Please enter a single word (25 characters or less): \n");
scanf("%s", &word);
printf("Thanks! The word you entered is: %s\n", word);
}
void load_menu(void)
{
int choice;
do
{
int choice;
printf("\n(:===Menu====:)\n");
printf("1. Count_the_letters\n");
printf("2. Count_the_vowels\n");
printf("3. Reverse_the_word\n");
printf("4. Check_if_palindrome\n");
printf("5. Enter_a_new_word\n");
printf("6. Exit\n");
scanf("%d", &choice);
switch (choice)
{
case 1: Count_the_letters();
break;
}
} while (choice != 3);
}
void Count_the_letters(void)
{
char S[MAX_STRING_LENGTH];
int count;
count = 0;
do {
printf("string:\t");
scanf("%s",S);
if (strcmp(S,"exit") != 0)
++count;
} while (strcmp(S,"exit") != 0);
printf("word count:\t%d\n", count);
}
return 0;
}
scanf("%s", &word);
needs an array of characters to read the data. &word only has space for one character.
You are running into undefined behavior.
Use
char word[26];
scanf("%25s", &word);
The reason is that you are passing the address to the char variable you declared and scanf() is trying to write two bytes where it only fits one.
char word
this declares a char variable, it can hold a single byte
scanf("%s", &word);
whill require at least one byte for an empty string the '\0'.
But also, you declared a lot of functions inside void grab_user_input(void), that is not valid standard c, it might work with some compiler, but it's not standard.

student info file handling

can you help me improve my code... this is all about student information... i'm having trouble in syntax... In editing menu... i try using strcmp but nothing happens, i first use fgets and store it at an array and then ask the user for an input and store it again in another array.. and then i'll compare... but it didn't work.. hope you can help me... this is my code..
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct student{
char name[30];
char id[8];
char course[5];
};
int main(void){
int option =0;
while(option!=6){
system("cls");
printf("Menu:\n");
printf("[1] Add Student.\n");
printf("[2] Display Student.\n");
printf("[3] Delete Student.\n");
printf("[4] Delete Student.\n");
printf("[5] Exit.\n");
scanf("%d",&option);
switch(option)
{
case 1:
addStudent();
break;
case 2:
displayinfo();
break;
case 3:
break;
case 4:
break;
default:
printf("That is not in the options!\nPlease Try again!\n");
break;
}
}
}
addStudent(){
int i;
FILE *stream = NULL;
stream = fopen("studentinfo.txt", "a+");
struct student s1;
struct student array[3];//here i wnt 2 apply d malloc but, still didn't know how 2start
for (i =0; i<1; i++){
printf("Enter Student ID: ");
scanf("%s", s1.id);
fflush(stdin);
printf("Enter Student Name: ");
gets(s1.name);
fflush(stdin);
printf("Enter Student Course: ");
scanf("%s", s1.course);
fprintf(stream, "\n%s,\t%s,\t%s", s1.id, s1.name, s1.course);
}
fclose(stream);
getch();
}
displayinfo(){
FILE *stream = NULL;
stream = fopen("studentinfo.txt", "rt");
char arr[100];
int i=0;
while(!feof(stream)){
fgets(arr, 100, stream);
printf("%s", arr);
}
fclose(stream);
getch();
}
here's my plan in EDITING MENU:
printf("enter details: ");
gets(arr2);
while(!feof(stream)){
fgets(arr, 100, stream);
if(strcmp(arr, arr2)==0){
//code here
}
}
will this work?
thanks guys hope you can help me ^_^
fgets() keeps the newline. gets() does not. Hence the strings will never match.
Try reading the manual for a function if you're not COMPLETELY sure what it is doing.
Instead of gets(arr2) try doing fgets(arr2, 100, stdin).
while(!feof(stream)){
fgets(arr, 100, stream);
use
while(fgets(arr, 100, stream) != NULL) {
...
}
if (ferror(stream))
printf("error in file" "\n");
feof() won't see an error while reading, so it may hang the loop

Resources