I can't input values without an error popping up, even though the code is correct.
#include <stdio.h>
int main()
{
char name[100];
printf("Enter your name: ");
scanf_s("%s", name);
printf("Your Name is: %s", name);
return 0;
}
As soon as I input a value to the name and press enter, an error message pops up and says:
Unhandled exception at 0x0FC13FD4 (msvcr120d.dll) in Project8.exe: 0xC0000005: Access violation writing location 0x00D40000.
What is causing this and how can it be fixed?
You should use fgets instead
#include <stdio.h>
int main(void)
{
char name[100];
printf("Enter your name: ");
if (fgets(name, sizeof(name), stdin) == NULL)
return 1;
printf("Your Name is: %s", name);
return 0;
}
Try this
if (scanf_s("%99s", name, _countof(name)) == 1)
printf("Your Name is: %s", name);
Two things
scanf_s() is a buffer overflow safe function, and it expects a length argument for "%s" specifier.
You should only proceed to printf() if you actually succeeded scannig the value, for which the check (scanf(...) == 1) is there.
The 1 there, means one of the input parameters matched by the specifiers, since in this case there is only one of them, then it will mean a full match.
Also, I am almost sure that the _countof() macro, is defined as sizeof(x) / sizeof(x[0]) so this should also do it
if (scanf_s("%99s", name, sizeof(name)) == 1)
printf("Your Name is: %s", name);
since in this case sizeof(name[0]) == sizeof(char) == 1.
Your code could work if you used the standard scanf() function, i.e.
if (scanf("%99s", name) == 1)
printf("Your Name is: %s", name);
Related
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 :)
Yes ,I know that this question was already asked for many times ,but none of these helped me to discover the problem (duplicate...yeah). I want to read from input a series of strings into an array and then search from 'First Name'. If the name exist ,I want to display all the data stored in that element of array (I attached the code to undestand easily). When I run it ,I read from keyboard all the data ,but it returns me absolutely nothing.
#include<stdio.h>
typedef struct record {
char name[10],lname[10],phone[10],bday[10];
};
void main() {
struct record rec;
char search;
int i,nr;
printf("\nInput number of records: ");
scanf("%d",&nr);
for (i=0 ; i<nr ;i++) {
printf("First name: ");
scanf("%s",&rec.name[i]);
printf("Last name: ");
scanf("%s",&rec.lname[i]);
printf("Phone: ");
scanf("%s",&rec.phone[i]);
printf("Bday: ");
scanf("%s",&rec.bday[i]);
}
printf("Input the first name for searching: ");
scanf("%s",&search);
for (i=0 ;i<nr;i++) {
if (search == rec.name[i]) {
printf("First name: %s\nLast name: %s\nPhone: %s\nB-day: %s",rec.name[i],rec.lname[i],rec.phone[i],rec.bday[i]);
}
}
}
NOTE: I already replaced
scanf("%s",&rec.name[i]);
with
scanf("%s",rec.name[i]);
but no effect.
I believe there are a lot of problems with your code.
Firstly in this line:
scanf("%s",&search);
You have declared search as only a char, when really you want an array of chars. You also don't need & with search, as an array decays to a pointer to the first element.
It instead should be like this:
char search[10];
scanf("%9s", search); /* %9s to avoid buffer overflow */
You need to make this change to all your other scanf() calls, as this seems to be everywhere in this code.
It also seems that you want to create an array of records(structures), So you might need to make this after getting the value of nr. You can create it like this:
struct record rec[nr]; /* array of nr structures */
This also means calls like this:
rec.name[i]
Don't make sense, as you are iterating over the characters within a name, not over all the records in struct records.
This needs to be instead:
rec[i].name
Secondly, Your using == to compare strings, when you should be using strcmp instead. Using == will only compare the base address of the strings, not the actual contents of strings.
Your line should be this instead:
if (strcmp(search, rec[i].name) == 0) {
If you read the manual page for strcmp(), checking for a return value of 0 means that both strings are equal in comparison.
Lastly, in your first scanf() call:
scanf("%d",&nr);
You should really check the return value of this:
if (scanf("%d", &nr) != 1) {
/* exit program */
}
Note: For reading strings, you should really be using fgets instead. You can try upgrading to this later, but I think it is better to understand these basics first.
Here is working example of what your program should do:
#include <stdio.h>
#include <string.h>
#define STRSIZE 10
typedef struct {
char name[STRSIZE+1]; /* +1 to account for null-btye at the end */
char lname[STRSIZE+1];
char phone[STRSIZE+1];
char bday[STRSIZE+1];
} record;
int main() {
char search[STRSIZE+1];
int i,nr;
printf("\nInput number of records: ");
if (scanf("%d", &nr) != 1) {
printf("Invalid input.\n");
return 1;
}
record rec[nr]; /* array of records */
for (i = 0; i < nr ; i++) {
printf("First name: ");
scanf("%10s", rec[i].name);
printf("Last name: ");
scanf("%10s", rec[i].lname);
printf("Phone: ");
scanf("%10s", rec[i].phone);
printf("Bday: ");
scanf("%10s", rec[i].bday);
}
printf("Input the first name for searching: ");
scanf("%10s", search);
for (i = 0; i < nr; i++) {
if (strcmp(search, rec[i].name) == 0) {
printf("First name: %s\nLast name: %s\nPhone: %s\nB-day: %s\n",rec[i].name,rec[i].lname,rec[i].phone,rec[i].bday);
} else {
printf("Record not found.\n");
}
}
return 0;
}
The numeric input leaves a new line character in the input buffer, which is then picked up by the character input. when numeric input with scanf() skips leading white space, character input does not skip this leading white space.
Use a space before %c and it will help you cause if space is not used then a buffer added with value .so that use space before %c
scanf(" %c",&rec.name[i]);
I am trying to learn to program in C but am having trouble with manipulating strings as C treats strings as arrays.
My aim was to make a program that stores the users first name and surname.
Here is my progress:
#include <stdio.h>
int main(int argc, const char * argv[]) {
//defining the variables
char first_name[100];
char surname[100];
char ch[2];
// Asking for the first name and storing it
printf("What's your first name?\n");
scanf("%s", first_name);
// Prints the first name
printf("Hey %s!\n",first_name);
//Asks the user if they want to store their surname
printf("Would you like to tell me your second name? This is optional so type 'Y' for yes and 'N' for no.\n");
scanf("%s", ch);
//validate if they want to store it or not
if (ch == "Y"){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
return (0);
}
However, with this code, I get an error because my IDE(xCode) tells me to use the strcmp function. I then edited the code to become this:
if (strcmp(ch, "Y")){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
However variable ch is not a literal and so is not comparable.
Sidenote
I did try to compare two literals too, just to see how it works:
char *hello = "Hello";
char *Bye = "Bye";
if (strcmp(hello, Bye)){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
But even this gave an error:
Implicitly declaring library function 'strcmp' with type 'int (const *char, const *char)'
I believe I am not able to do this due to my lack of experience so it would be much appreciated if you could help me understand what I'm doing wrong and how I can fix the problem.
You need to include the appropriate header:
#include <string.h>
Also note that your desired logic probably calls for:
if (!strcmp(hello, Bye))
Instead of:
if (strcmp(hello, Bye))
Since strcmp returns 0 in case of equality.
There are several issues you should correct concerning how you handle input with scanf. First always, always validate the number of successful conversions you expect by checking the return for scanf. Next, as mentioned in the comment, there is NO need to include <string.h> in your code to make a one-letter comparison. Use a character comparison instead of a string comparison. Lastly, always limit your input to the number of characters available (plus the nul-terminating character.
Putting the bits together, you could do something like the following:
#include <stdio.h>
#define MAXN 100
int main (void) {
char first_name[MAXN] = "", surname[MAXN] = "";
int ch;
printf ("What's your first name?: ");
if (scanf ("%99[^\n]%*c", first_name) != 1) {
fprintf (stderr, "error: invalid input - first name.\n");
return 1;
}
printf ("Hey %s!\n", first_name);
printf("Enter surname name? optional (Y/N) ");
if (scanf("%c%*c", (char *)&ch) != 1) {
fprintf (stderr, "error: invalid input - Y/N\n");
return 1;
}
if (ch != 'y' && ch != 'Y') /* handle upper/lower case response */
return 1;
printf ("Enter your surname?: ");
if (scanf (" %99[^\n]%*c", surname) != 1) {
fprintf (stderr, "error: invalid input - surname\n");
return 1;
}
printf ("\nYour whole name is : %s %s\n", first_name, surname);
return 0;
}
Example Use/Output
$ ./bin/firstlast
What's your first name?: David
Hey David!
Enter surname name? optional (Y/N) Y
Enter your surname?: Rankin
Your whole name is : David Rankin
Look it over and let me know if you have any questions.
There are two problems here. Firstly you need to see what value is returned by the strcmp and secondly you must use the approprate hedder.
You must use:
#include <string.h>
Secondly, you must edit your if-else statement so it is like this:
if (strcmp(ch, "Y") == 0){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
We do this because the strcmp function returns a negative value if ch is smaller than "Y", or a positive value if it is greater than "Y" and 0 if both strings are equal.
I want to reference the input of name throughout the code I am writing, but for some reason after I use it successfully in the first printf(), the second printf() does not print the name.
int main()
{
char name[50];
char q1[1];
printf( " What is your name?\n");
scanf("%s", name);
printf( " Hi %s, Do you want to have some fun? [Y/N]\n",name);
scanf("%s",q1);
if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0)
{
printf("Awesome, let's play!\n");
}
else
{
printf("Fine"); goto endgame;
}
printf( "So %s, it's time to get started\n", name);
endgame:
getchar();
return 0;
}
The output for the entry 'Nick' is:
Hi Nick, do you want to have some fun? Awesome let's play So ,
let's get started
I would expect it to say:
So Nick, let's get started.
but for some reason char name is blank after it is used correctly the first time.
The problem, (as I assumed correctly) is with char q1[1]; and then using it like
scanf("%s",q1);
It is causing memory boundary overrun, because, a one-char array is not sufficient to hold a string of having only one element, as it lacks the space for the null-terminator required for the string. This invokes undefined behaviour.
Instead,
change char q1[1]; to char q1;
change scanf("%s",q1); to scanf(" %c", &q1);
change if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0) to if((q1 =='Y') || q1 == 'y')
That said, as a note,
The recommended signature of main() is int main(void).
To avoid the possibility of buffer overflow by longer input(s), it's better to limit the length of the input with scanf() by writing like
scanf("%49s", name);
Expand the size of your q1 buffer. scanf("%s", q1) doesn't have enough room to store the input. Remember that C uses a null character '\0' to terminate strings. If you don't account for that, the buffer could overrun into other memory causing undefined behavior. In this instance, it's probably overwriting memory allocated to name, so name ends up pointing to "\0ick". This causes printf(%s), which looks for '\0' to know when to stop printing, to think that the string is shorter than it really is.
The code works perfectly if you expand the buffer:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char name[50];
char q1[50];
printf( " What is your name?\n");
scanf("%49s", name);
printf( " Hi %s, Do you want to have some fun? [Y/N]\n",name);
scanf("%49s",q1);
if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0)
{
printf("Awesome, let's play!\n");
}
else
{
printf("Fine");
}
printf( "So %s, it's time to get started\n", name);
getchar();
return 0;
}
Output:
What is your name?
Nick
Hi Nick, Do you want to have some fun? [Y/N]
y
Awesome, let's play!
So Nick, it's time to get started
Note that I've added the qualifier %49s to avoid buffer overruns like this.
You could also circumvent the need for another string entirely by changing char q1[50] and scanf("%49s") to simply char q1 and scanf("%c%*c", &q1) (note the "address of" operator because q1 is no longer a pointer).
You'll probably even get a performance gain from this (albeit small), because strings are notorious memory hoggers. Comparing a single character is usually preferred over comparing strings.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char name[50];
char q1;
printf( " What is your name?\n");
scanf("%49s%*c", name);
printf( " Hi %s, Do you want to have some fun? [Y/N]\n",name);
scanf("%c%*c",&q1);
if(q1 == 'Y' || q1 == 'y')
{
printf("Awesome, let's play!\n");
}
else
{
printf("Fine");
}
printf( "So %s, it's time to get started\n", name);
getchar();
return 0;
}
if(q1 == 'Y' || q1 == 'y')
{
printf("Awesome, let's play!\n");
}
else
{
printf("Fine");
}
printf( "So %s, it's time to get started\n", name);
getchar();
return 0;
}
If you go this route, you have to ignore the enter key using the format specifier %*c because pressing enter sends a key to the stream as well.
What is wrong with the scanf() to get in the string on the second time, I can't input my string on the second time.
I am not sure with the error that occurs, I can't get this program function well
#include <stdio.h>
#include <stdlib.h>
int main()
{
//variables decleration
char staff_name1[31];
char staff_name2[31];
float sales1, sales2;
//input
printf("Enter staff name\t> ");
scanf("%[^\n]s", staff_name1);
printf("Enter sales amount\t> ");
scanf("%f", &sales1);
printf("\nEnter staff name \t> ");//ERROR,CAN'T INPUT MY STRING
fflush(stdin);
scanf("%[^\n]s", staff_name2);
printf("\nEnter sales amount\t> ");
scanf("%f", &sales2);
printf("\n");
//output
printf("Staff Name\t\t\t\tSales Amount\n");
printf("===================\t\t=============\n");
printf("%-20s \t%12.2f\n", staff_name1, sales1);
printf("%-20s \t%12.2f\n", staff_name2, sales2);
}
my output of this code is as below:
warning: this program uses gets(), which is unsafe.
Enter staff name > kh s
Enter sales amount > 134.14
Enter staff name >
Enter sales amount > 141243.14
Staff Name Sales Amount
=================== =============
kh s 134.14
141243.14
I can't input the second staff name. Can anyone please help me solve this??
fflush(stdin);
is undefined behaviour in standard C. To flush the newline character, you could simply use getchar() instead.
printf("\nEnter staff name \t> ");
getchar();
scanf("%[^\n]s", staff_name2);
I would also use fgets() instead of scanf to read a line and trim the newline if necessary, which offers better control over invalid inputs being entered by user and against buffer overflows.
You have three problems.
I see that you use %[^\n]s. It is wrong. The s isn't part of the %[ specifier. So use %[^\n] instead of %[^\n]s
After you enter the value for sales1, you press Enter. This character stays in the stdin(standard input stream). And when the next character for %[^\n] is \n, it will fail. Fix this problem by adding a space before %[^\n].
Using fflush on stdin invokes Undefined Behavior as per the C11 standard, although the behavior is well defined in some implementations. It is better to remove it so that your code will be more portable.
Additional notes:
You can limit the amount of characters to be scanned so that you can avoid buffer overflows.
You can check the return value of scanf to make sure it is successful. All the scanf in your program will return 1 on success.
Fixed Program:
#include <stdio.h>
#include <stdlib.h> //Unused header
int main()
{
char staff_name1[31];
char staff_name2[31];
float sales1, sales2;
printf("Enter staff name\t> ");
if(scanf(" %30[^\n]", staff_name1) != 1)
{
printf("Could not scan staff_name1");
return -1; //Exit main with a return value of -1
}
printf("Enter sales amount\t> ");
if(scanf("%f", &sales1) != 1)
{
printf("Could not scan sales1");
return -1; //Exit main with a return value of -1
}
printf("\nEnter staff name \t> ");
//fflush(stdin); UB!
if(scanf(" %30[^\n]", staff_name2) != 1)
{
printf("Could not scan staff_name2");
return -1; //Exit main with a return value of -1
}
printf("\nEnter sales amount\t> ");
if(scanf("%f", &sales2) != 1)
{
printf("Could not scan sales2");
return -1; //Exit main with a return value of -1
}
printf("\n");
//output
printf("Staff Name\t\t\t\tSales Amount\n");
printf("===================\t\t=============\n");
printf("%-20s \t%12.2f\n", staff_name1, sales1);
printf("%-20s \t%12.2f\n", staff_name2, sales2);
}