I'm getting an Exception Error when using %S - c

int main()
{
int Age;
char Name;
//Age
printf("Type your age: ");
scanf_s("%d", &Age);
printf("Your age is %d\n", Age);
//Name
printf("Type your Name: ");
scanf_s("%s", &Name);
printf("Your name is %s", Name);
return 0; }
It's the 'Name' section which is throwing out an error. I can't figure out why.
UPDATE: I'm coding in Visual Studio. Therefore, "scanf_s" is essentially required.
The error is "Exception thrown at 0x5B49D4EC (ucrtbased.dll) in Project1.exe: 0xC0000005: Access violation writing location 0x001A0000. occurred"

Your problem is that char Name; can only store a single character. Your code is allowing the user to type in multiple characters which are being stored into Name causing a memory error.
Change char Name; to something like char Name[50] so that you can store up-to 49 characters plus the null byte.
Also you should use scanf_s() properly to avoid the error if the buffer (char array) ends up being too small.
Note, you should always check the return from scanf_s() so you know if the user entered valid data or not.
This code works correctly in Visual Studio:
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
int main()
{
int Age;
char Name[50];
printf("Type your age: ");
if(scanf_s("%d", &Age))
{
printf("Your age is %d\n", Age);
printf("Type your Name: ");
if (scanf_s("%s", Name, (unsigned)_countof(Name)))
{
printf("Your name is %s\n", Name);
}
else
{
printf("Name:: Invalid Input\n");
}
}
else
{
printf("Age:: Invalid Input\n");
}
return 0;
}

The problem is that you defined Name as a char - a single character - but you are trying to use it as a string (multiple characters).
To fix this you must either (a) define Name as an array of characters (which would be a string) - such as char Name[100]; or (b) as a pointer (such as char *Name;) - which would require you to malloc() the string before use and free() it after use.
Strings can be tricky, as they are basically just arrays of chars, but that requires you to either know, or find a way to know, how many characters will be in the string. You can read more about how to do that here, in the documentation for scanf_s, which gives this example:
char c[4];
scanf_s("%4c", &c, (unsigned)_countof(c)); // not null terminated

First off I would just use scanf(), not scanf_s().
Furthermore you need to cast your Name variable as a string, which is an array of characters as I have defined it below. Using just char Name, means you have created a variable with room for just one character.
Hope this helps :)
int main()
{
int Age;
char Name[10];
printf("Type your age: ");
scanf("%d", &Age);
printf("Your age is %d\n", Age);
//Name
printf("Type your Name: ");
scanf("%s", &Name);
printf("Your name is %s", Name);
return 0;
}

Fixed the problem by going to...
Tools->Options->Debugging->Symbols and select checkbox "Microsoft Symbol Servers", Visual Studio will download PDBs automatically.
Thanks for everyone's help :)

Related

printf will not print output of %d correctly for an int

Can't figure out why my printf output won't print the int data.age or addr.zip correctly. They're defined as int, so %d should work...but it doesn't. I get gibberish numbers for the output. All other fields work perfectly.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct BillingAddress {
char *street[50];
char *city[25];
char *state[3];
int *zip[6];
}address;
address addr;
typedef struct ContactInfo {
char *name[30];
int *age[3];
char *phone[15];
struct BillingAddress PersonalData;
}personaldata;
personaldata data;
int main()
{
printf("Enter your full name: ");
scanf(" %49[^\n]", &data.name);
printf("Enter your age: ");
scanf("%d", &data.age);
printf("Enter your Phone Number (xxx) xxx-xxxx: ");
scanf(" %14[^\n]", &data.phone);
printf("Enter your street address: ");
scanf(" %49[^\n]", &addr.street);
printf("Enter your city: ");
scanf(" %24[^\n]", &addr.city);
printf("Enter your state abbreviation: ");
scanf("%s", &addr.state);
printf("Enter your zip code: ");
scanf("%d", &addr.zip);
printf("Personal Data: \n %s\n %d\n %s\n %s\n %s\n %s\n %d\n", data.name, data.age, data.phone, addr.street, addr.city, addr.state, addr.zip);
}
Let's go step by step. In your BillingAddress struct definition, you intend to store the street, city, and state. It seems logical that you could represent all of those parameters as strings (which are character arrays in C). I believe that is what you tried to do, but the declaration:
char *street[50];
represents give you an array of 50 char * (i.e., char pointers) NOT 50 chars, which is what you actually want. So, the struct definition should instead be:
typedef struct BillingAddress {
char street[50];
char city[25];
char state[3];
int zip;
} address;
You also intend to store the zip. Note how I changed the type of zip to an int array rather than an int array. You could do an int array, but you would have to do more work to properly accept the user's input (simply using scan("%d", &addr.zip) will not work).
Now, let's take a looked at a different way to define your definition for ContactInfo struct:
typedef struct ContactInfo {
char name[30];
int age;
char phone[15];
address addr;
} personaldata;
You can see that I've removed the *'s and changed age to be a single int for the similar reasoning as what I mentioned above. I've also replaced struct BillingAddress with the simpler address. Why? Because you created a typedef linking the keyword address to struct BillingAddress. So, by using address alone, the code looks a bit cleaner and you are putting that typedef to good use :D (Note that there's nothing incorrect about using struct BillingAddress, I just think it looks cleaner to utilize the typedef).
Also, you'll see that I renamed the variable of type address (i.e., of type struct BillingAddress -- remember the typedef means these two are the same) to addr. This makes more sense than naming it PersonalData as you did, because well, it's an address, not arbitrary personal data.
Now moving onto your main() method. You should be aware of some of the pitfalls of using scanf(). Since it reads from the default input stream stdin (i.e., most likely your terminal), any characters not gulped up by scanf() will be left in the input stream. So, any subsequent calls to scanf() will also read in those unwanted characters. See this post for more info. You might not have run into this if you supplied the less than the max number of desired characters, but it is important to take care of this error case. So, after each scanf(), you should clear the input stream, which can be done using a method like:
void clear_input_stream()
{
int c;
while ((c = fgetc(stdin)) != '\n' && c != EOF);
}
You can call this method after each one of your scanf() calls.
You want to make sure that if you are writing into a char array you should not add the & in front of the variable you are writing to -- check this answer for an explanation (your compiler should warn you about that).
The last thing I want to mention is that you could also add a length to the %d specifier to limit reading an integer of a certain length. Your main() could look something like this:
int main()
{
printf("Enter your full name: ");
scanf(" %49[^\n]", data.name);
clear_input_stream();
printf("Enter your age: ");
scanf(" %3d", &data.age);
clear_input_stream();
printf("Enter your Phone Number (xxx) xxx-xxxx: ");
scanf(" %14[^\n]", data.phone);
clear_input_stream();
printf("Enter your street address: ");
scanf(" %49[^\n]", addr.street);
clear_input_stream();
printf("Enter your city: ");
scanf(" %24[^\n]", addr.city);
clear_input_stream();
printf("Enter your state abbreviation: ");
scanf(" %2[^\n]", addr.state);
clear_input_stream();
printf("Enter your zip code: ");
scanf(" %5d", &addr.zip);
clear_input_stream();
printf("Personal Data: \n %s\n %d\n %s\n %s\n %s\n %s\n %d\n", data.name, data.age, data.phone, addr.street, addr.city, addr.state, addr.zip);
return 0;
}

How can I print the registration number of student according to his/her department and school

Getting issue while solving this problem for assignment of C programming:
Need to create an app for college where there are 500 undergraduate students from which 250 are in School of Engineering (SOE) and 250 are in School of Science (SOE) , where suppose if a student belongs to Computer engineering (CE) batch 2020_21:
supposed output needs too look like:
SOEUNGCE0001 - SOEUNGCE0040
departments in school of engineering are:
chemical engineering -CHE
computer engineering -CE
mechanical engineering- ME
Environmental engineering -ENE
Electrical Engineering - EE
and in school of science:
Architecture -AR
computer science-CS
Biotechnology-BT
Pharmacy-PH
I tried printing with switch case statements but it's wasn't working with strings. also the below program is having some issue i.e. it doesn't take some inputs.
HELP ME SOLVE THIS.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char name;
int roll_no;
char department;
char school;
}students;
int main()
{
students student;
//inputs
printf("Enter Name : " );
scanf("%s", &student.name);
printf("\nRoll Number : ");
scanf("%d", &student.roll_no);
printf("\nDepartment : ");
scanf("%s",&student.department);
printf("\nSchool : ");
scanf("%s",&student.school);
if (student.department == 'Chemical')
{
printf("Name : %s \t",student.name);
printf("\n%sUNG%s00%d", student.school, "CHE", student.roll_no);
}
return 0;
}
You have 3 mistakes:
Logical Error: since name, department and school are strings, so they must be arrays of characters i.e char name[100]. So the structure should be modified as the following:
typedef struct{
char name[100];
int roll_no;
char department[100];
char school[100];
}students;
2- After editing the structure you will get warning from the compiler since scanf takes the address of the element to be scanned and student.name points to the first character of the string name. So Edit the scanf arguments to be :
scanf("%s", student.name);
.
scanf("%s", student.department);
.
scanf("%s", student.school);
Note: You can also use fgets instead of scanf to avoid buffer overflow but you have to consider that fgets includes the newline character, \n, within the string, so you have to replace the \n with \0. See tricks for how to replace the \n with \0
3- The last error is in comparing strings, you should use the strcmp function to compare between two strings, the function returns 0 if the two strings are typical. Also the string literals sholud be put inside double quotation marks "". So you should modify the last block to be :
if (!strcmp(student.department, "Chemical"))
{
printf("Name : %s \t",student.name);
printf("\n%sUNG%s00%d", student.school, "CHE", student.roll_no);
}
Try something like that:
typedef struct{
char name[100];
int roll_no;
char department[100];
char school[100];
} students;
int main() {
students student;
char input[100];
//inputs
printf("Enter Name : " );
fgets(student.name, 50, stdin);
printf("\nRoll Number : ");
fgets(input, 50, stdin);
sscanf(input,"%d", &student.roll_no);
printf("\nDepartment : ");
fgets(student.department, 50, stdin);
printf("\nSchool : ");
fgets(student.school, 50, stdin);
if (strcmp(student.department, "Chemical") == 0)
{
printf("Name : %s \t",student.name);
printf("\n%s %d", student.school, student.roll_no);
}
return 0;
}

Printing an int value obtained from user

The problem is at the age part, the compiler does not give me any errors but when I run it it prints a random number for int age
printf("Enter your name:");
scanf(" %s",&name1);
int age;
printf("\n\nHow old are you?");
scanf(" %d",&age);
char gender;
printf("\n\nEnter your gender[Male/Female]:");
scanf(" %s",&gender);
char confirmation;
printf("Confirmation: Your name is %s , you are %d years old , and you are a %s.\n\nAnswer[Y/N]:",&name1,age,&gender);
Here is your problem.
char gender;
scanf(" %s",&gender);
gender is a char. That is, it only has memory for a 1 byte character. But you are using it as a string. You probably have the same problem for name1 since you are using & for that as well but can't be sure as you don't show that.
Change that to be something like:
char gender[8] // Enough to fit "Female" and terminating NULL
scanf("%7s", gender);
Extra note: scanf is a bit awkward to use to prevent buffer safety. May consider something like fgets with sscanf instead.
There is also dynamic allocation, where you now do not have to specify the amount of storage to use. Using the length modifier %m with the string type modifier s:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *name = NULL
char *gender = NULL;
int age;
printf("Enter your name: ");
scanf("%ms", &name);
printf("\nHow old are you? ");
scanf("%d", &age);
printf("\nEnter gender: ");
scanf(" %ms", &gender);
printf("\n%s %d %s\n", name, age, gender);
free(name); // free the memory
free(gender); //
return 0;
}
In the last couple of lines you will notice a several calls to free. This is because you are left with the responsiblility to free the memory allocated by scanf.
As pointed out by #Matt McNabb if you are on a non-posix compliant system, this will not work. You can use a in place of m, while including #define _GNU_SOURCE on the first line.

Get text from user input using C

I am just learning C and making a basic "hello, NAME" program. I have got it working to read the user's input but it is output as numbers and not what they enter?
What am I doing wrong?
#include <stdio.h>
int main()
{
char name[20];
printf("Hello. What's your name?\n");
scanf("%d", &name);
printf("Hi there, %d", name);
getchar();
return 0;
}
You use the wrong format specifier %d- you should use %s. Better still use fgets - scanf is not buffer safe.
Go through the documentations it should not be that difficult:
scanf and fgets
Sample code:
#include <stdio.h>
int main(void)
{
char name[20];
printf("Hello. What's your name?\n");
//scanf("%s", &name); - deprecated
fgets(name,20,stdin);
printf("Hi there, %s", name);
return 0;
}
Input:
The Name is Stackoverflow
Output:
Hello. What's your name?
Hi there, The Name is Stackov
#include <stdio.h>
int main()
{
char name[20];
printf("Hello. What's your name?\n");
scanf("%s", name);
printf("Hi there, %s", name);
getchar();
return 0;
}
When we take the input as a string from the user, %s is used. And the address is given where the string to be stored.
scanf("%s",name);
printf("%s",name);
hear name give you the base address of array name. The value of name and &name would be equal but there is very much difference between them. name gives the base address of array and if you will calculate name+1 it will give you next address i.e. address of name[1] but if you perform &name+1, it will be next address to the whole array.
change your code to:
int main()
{
char name[20];
printf("Hello. What's your name?\n");
scanf("%s", &name);
printf("Hi there, %s", name);
getchar();
getch(); //To wait until you press a key and then exit the application
return 0;
}
This is because, %d is used for integer datatypes and %s and %c are used for string and character types

C prompt ordering for reading string with getchar() [duplicate]

This question already has answers here:
Why is getchar() reading '\n' after a printf statement?
(3 answers)
Closed 9 years ago.
This is a newbie question. I am new to C programming. I have the following code which does not prompt for 'Name' Onece the 'Age' is entered, it bypass the 'Name section.
#include <stdio.h>
int main()
{
char name[30],ch;
int age;
printf("Enter age : ");
scanf("%d", &age);
int i=0;
printf("Enter name: ");
while((ch = getchar())!='\n')
{
name[i]=ch;
i++;
}
name[i]='\0';
printf("Name: %s\n",name);
printf("Age : %d\n", age);
return 0;
}
After reading first prompt it bypass the second prompt which is using getchar() function. But if I change the order of prompt to ask for 'Name' first and then 'Age' it works fine.
The working code.
#include <stdio.h>
int main()
{
char name[30],ch;
int age;
int i=0;
printf("Enter name: ");
while((ch = getchar())!='\n')
{
name[i]=ch;
i++;
}
name[i]='\0';
printf("Enter age : ");
scanf("%d", &age);
printf("Name: %s\n",name);
printf("Age : %d\n", age);
return 0;
}
My coding IDE is CodeBlock and my compiler is GNU C Compiler (mingw32-gcc.exe)
Please help me to breakthrough.
A few improvements/advices to the code in the question:
the type of the return value of getchar() is int, so the type of ch also should be int
you could (and should, I believe) use format %s to read the name, this is easier and the leading white spaces in the input stream would not be a problem
the user of the code could give a name which contains more than 30 characters, and this input could crash your program, so you should protect your code for this possibility. You have two options:
a. use format '%29s" to read the name
b. change the definition of name to char *name, read it by scanf("%ms", &name);, and call free(name); after you do not need it anymore
Here is an example, in which the name can be very long and can include spaces:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
char *name;
int age;
printf("Enter name: ");
scanf("%m[^\n]", &name);
printf("Enter age: ");
scanf("%d", &age);
printf("Name: %s\n", name);
printf("Age : %d\n", age);
free(name);
exit(EXIT_SUCCESS);
}
And here is a run of it:
$ ./a.out
Enter name: a very looooooooooooooooooooooooooooooooooooooooooooooong name
Enter age: 12
Name: a very looooooooooooooooooooooooooooooooooooooooooooooong name
Age : 12
In first code the \n character left behind by the scanf is read by getchar. This makes the condition (ch = getchar())!='\n' in while loop false and the loop body never get executed.
You need to consume that \n character which comes up to the buffer along with the age you entered on pressing Enter key.
Putting the statement
while(getchar()!='\n');
after the scanf will consume all of the newline characters.
Your second code is working fine because %d skips white-space characters unlike %c specifiers.

Resources