Exception thrown in strings input output - c

I had been having an issue with string in school project and couldn't manage to fix it, made a test program to troubleshoot but haven't had any luck. I'm trying to just make a simple program to take a string value and then print it to the console. When it tries to print the string the program crashes with an exception being thrown I don't understand I think it is trying to save the string data to a memory address it doesn't have access to but im not sure cuz I tried it on both my laptop and pc with the same issue.
"Exception thrown at 0x00007FFAACA60369 (ucrtbased.dll) in tokenizing.c.exe: 0xC0000005: Access violation writing location 0x0000001F1F100000."
#include <stdio.h>
int main() {
char string[100];
printf("Enter a string: ");
scanf_s(" %s ", &string);
printf(" %s ", string);
return 0;
}

scanf_s(" %s ", &string); fails as it is missing a parameter. %s obliges a pointer and size.
scanf_s(" %s ", string, (rsize_t) 100);
Review your compiler details on scanf_s() as the C standard is not followed in details by some compilers.
Alternative: Review fgets() to read a line into a string.
A space before "%s" serves no purpose. Best to drop it.
A space after "%s" blocks until following non-white-space detected. Best to drop this space too.

Related

Visual Studio Code and C programming

I'm attempting to learn C and decided to use Visual Studio as a base for where I can practice my code. I have everything set up already and have started writing up code as well but I seem to be running into a problem where I cannot see the user input.
Here is my program:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char string[] = "";
char reversed[] = "Placeholder";
printf("Please enter an input string.\n");
scanf("%s", &string);
printf("Your original string is %s\n", string);
printf("The string reversed is %s", reversed);
return 0;
}
When I run this program, the first printf statement is never printed nor is the user input ever shown
anywhere (not in the terminal either). All it says is that the program is running. When I force stop it,
it will say 'Done!' and that's all that ever happens (I have to force stop because I never see the place to input the string therefore the program just keeps running waiting for an input). I just set up Visual Studio so it is possible I missed something and this is an easy fix but not quite sure what it is.
The string you're inputting is empty. First avoid naming variables "string" as in standard libraries there might already be defined one. And try to allocate more space for your string to be able to input data.
`
char str[128];
char reversed[] = "Placeholder";
printf("Please enter an input string.\n");
scanf("%s", &str);
printf("Your original string is %s\n", str);
printf("The string reversed is %s", reversed);
return 0;
`
Also, be sure to read more about arrays, strings and functions in c. The code you've written is probably not gonna work as you've intended.
There are a couple of problems.
You're not allocating any memory for string, so when the user inputs something, its written into memory it doesn't own, resulting in undefined behavior.
Your scanf is wrong,, kind of. You must provide it a pointer to the memory where the input should go, you're providing the address of the pointer. In this case, they're one in the same, but if that was a pointer to heap memory, for instance, &string would not point to the memory you've reserved.
Instead, try something like this:
int main()
{
char string[64] = ""; // string can now hold 63 user-input characters plus
// one for the NUL terminator, which scanf will add
// automatically.
char reversed[] = "Placeholder"; // This reserves at least 12 bytes, 11 for the text plus the NUL terminator.
printf("Please enter an input string.\n");
scanf("%s", string); // string decays to a pointer to where its memory is allocated.
printf("Your original string is %s\n", string);
return 0;
}
Note, you can still overflow your string buffer if you enter (in this case) more >= 64 characters, and you'll be back where you started. I believe there is a way for scanf to limit the amount of input accepted, but will need to look up how. Another option is to use fgets to accept limited input.

scanf and printf not printing right values

What is going on here?
The code goes like:
#include<stdio.h>
#include<string.h>
int main()
{
char name[15];
char name_[15];
char answ[1];
printf("What's your name?\n");
scanf("%s", name);
strcpy(name_, name);
printf("Yes / No: ");
scanf("%s", answ);
printf("Hello! %s\n", name_);
printf("You said: %s\n", answ);
return 0;
}
With input "name" and "yes" the expected output is that it says:
Hello! name
You said: yes
Instead I get:
Hello! es
You said: yes
I also tried adding spaces before %s with no results.
So what exactly am I missing here?
answ can contain only 1 character. So currently, the extra character "es" + '\0' gets written into the memory assigned to name_.
So, "es" gets printed.
You've only allocated space for a one-character yes/no answer, but are writing more characters into it.
This results in undefined behaviour.
You need to allocate more space for answ, not forgetting about the NUL terminator.
You have created a classic exploitable buffer overrun but in your code. This is why most modern compilers would advise you to swap sscanf to sscanf_s or similar. As other people have pointed out, you overwrite the next variable on the stack.
I wanted to provide this answer to basically say: never ever use sscanf or any of the obsolete, insecure C functions. Even if this is probably just a toy example, get the practice in to write modern C code. You’ll benefit from this in the long run.

How to get string from input in C language

This is what i have try:
printf("Please venter first string\n");
char str[127];
scanf_s("%s", &str);
And got this exception:
Exception thrown at 0x0FD2C700 (ucrtbased.dll) in strcmp.exe:
0xC0000005: Access violation writing location 0x00500000.
I also try this:
printf("Please venter first string\n");
char str[127];
scanf_s("%d", &str);
In this case no exception but i got long and strange string.
Let's start by considering the use of the standard scanf. If you write
scanf("%s", &str);
that will be incorrect (although it might work). When passing an array to a function it decays to a pointer to the first element, which is what scanf requires, so the line should be
scanf("%s", str);
If you want to restrict the input length to prevent buffer overflow it can be like this (one less than the array length to allow for the nul terminator)
scanf("%126s", str);
The allegedly safer function scanf_s requires an additional size argument to be passed for each format type %c and %s and %[] so the next line (after correcting the &)
scanf_s("%s", str);
lacks that argument, and the compiler should issue a warning about it. The code should be
scanf_s("%s", str, sizeof str);
but even that is inadequate. The Xscanf family of functions returns the number of values successfully entered. Since users (even myself) are notoriously bad at entering correct input (which may even be malicious) you must always check if the data was correctly entered. Such as
if(scanf_s("%s", str, sizeof str) != 1) {
// inform user and retry etc. etc.
}
As mentioned by #chux it is better to obtain input by using fgets, and then process it by various means, such as sscanf or strtok or strsep or by more direct analysis of the string. In that case, and with sscanf, you can make multiple attempts to process the input, but with scanf you only get one chance. Note that strtok and strsep modify the string, so you would need to work with a copy if you need to make more than one attempt to decode it.
In your second example
scanf_s("%d", &str);
you got "no exception but a long and strange string", but you should have got a compiler warning:
warning C4477: 'scanf_s' : format string '%d' requires an argument of
type 'int ', but variadic argument 1 has type 'char ()[127]'
Note that you did not initialise str to the "empty string" and if you go on to process what you imagine to be a good string after a faulty input, bad stuff can happen.

Please tell me where I've gone wrong

#include <stdio.h>
main()
{
char name1[15],name2[15],name3[15];
int no;
printf("Enter the serial number and name one\n");
scanf("%d %15c',&no, name1");
printf("%d %15s\n\n",no,name1);
printf("Enter serial number and name two\n");
scanf("%d %s",&no,name2);
printf("%d %15s\n\n",no, name2);
printf("Enter serial number and name three");
scanf("%d %15s",&no,name3);
printf("%d %15s\n\n",no,name3);
}
Hi, I'm new to programming, I've started with C for some reasons. The code I've typed above is my program that I want to execute. When I execute it with Code::Blocks it runs till Enter the serial number and name one and then if I enter a number it become not responding. Then I tried compiling using Visual Studio 2013 it again stops responding.
After that I tried debugging using Visual Studio 2013 debugger it said this First-chance exception at 0x7575B790 (msvcrt.dll) in temp.exe: 0xC0000005: Access violation writing location 0x00000000. after pressing continue it said this Unhandled exception at 0x7575B790 (msvcrt.dll) in temp.exe: 0xC0000005: Access violation writing location 0x00000000.
I have programmed before this one in Code::Blocks they all worked well. Please tell me where I've gone wrong. Also please explain the use of %s.
Thanks
scanf("%d %15c',&no, name1");
Should be replaced with:
scanf("%d %14s",&no, name1);
Use double quotes since the single quote doesn't terminate a String in C.
Use %14s (as suggested by chux) so that you do not overflow the buffer for the string and cause a seg fault
%s is used to read in a space delimited string. If you want to read an entire line, you must make use of fgets function

problems with scanf and conversion specifiers

Here you can see my source code:
#include <stdio.h>
int main()
{
char yourname;
char yoursex;
int yourage = 0;
printf("Hey, what's your name?\n");
printf("My name is: ");
scanf("%s", &yourname);
printf("Oh, hello %s! \n\n", &yourname);
printf("Are you a boy or a girl?: ");
scanf("%s", &yoursex);
printf("Nice to know you are a %s! \n\n", &yoursex);
printf("How old are you %s? I am ", &yourname);
scanf("%d", &yourage);
printf("I see you are %d, you have many years then!", &yourage);
return 0;
}
I was trying things that I didn't knew, and strangely it is not working for me. What's the problem? Also, why it needs to be %s and not %c? If I use %c instead it does not work!
Where it says:
How old are you %s? instead of putting my name, it says ''oy''
and instead of showing my age in the last line, it shows a big number.
These are the very basics of C Programming, and I strongly advise you to get a decent book - The C Programming Language by Dennis Ritchie would be a good start.
There are numerous errors in your code.
A char can contain only one character, like 'A', or 'a' or something like that. When you're scanning a name, it is going to be a group of characters, like 'E', 'd', 'd', 'y'. To store multiple characters, you need to use a character array. Also, the format specifier used to scan/print characters is %c, %s is for when you need to scan a group of characters, also called a string into an array.
When you use printf, you do not supply a pointer to the variable you are trying to print (&x is a pointer to variable x). The pointer is a 32/64-bit integer, which is likely why you see a random integer when trying to print. printf("%c\n", charVar) is sufficient.
scanf does not need an & while using %s as the format specifier, assuming you have passed a character array as the argument. The reason is, scanf needs to know where to store the data you are reading from the input - and that is given by a pointer to the memory location. When you need to scan an integer, you need to pass an &x - which means, pointer to memory location of x. But when you pass a character array, it is already in the form of a memory address, and doesn't need to be preceded by an ampersand.
I once again recommend you look up some decent tutorials online, or get a book (the one I mentioned above is a classic). Type the examples as given in the material. Experiment. Have fun. :)
%s is for reading a string -- multiple characters delimited by whitespace. %c is for reading a single char.
You declare your yourname and yoursex vars as characters, and then try to read strings into them. The string read will overwrite random other things in the stack frame and misbehave or crash.
You want to declare yourname and yoursex as character arrays, so they can hold strings:
char yourname[32];
char yoursex[32];
then, when reading into them, you want to include a length limit so they don't overflow:
scanf("%31s", yourname);
This is a single character:
char yourname;
But %s indicates that the variable is a string (i.e., an array of characters terminated by a NUL). That's why you need %c. If you really did mean to use a string, then define the variable like
char yourname[32]; /* just pick a big enough size */
Also, you are correct to use the address of the variable with scanf(), but printf() needs the value. So instead of
printf("I see you are %d, you have many years then!", &yourage);
use
printf("I see you are %d, you have many years then!", yourage);
The "big number" is the memory address.
Make sure you read the comments in code!
#include <stdio.h>
int main()
{
char yourname[10];
char yoursex[5]; // boy or girl + null terminator
int yourage = 0;
printf("Hey, what's your name?\n");
printf("My name is: ");
scanf("%s", &(*yourname)); // & and * cancel each other out,
// thus take a look at the next scanf()
printf("Oh, hello %s! \n\n", yourname); // yourname is now an array
printf("Are you a boy or a girl?: ");
scanf("%s", yoursex);
printf("Nice to know you are a %s! \n\n", yoursex);
printf("How old are you %s? I am ", yourname);
scanf("%d", &yourage); // ok
printf("I see you are %d, you have many years then!", yourage); // here you don't
// need the address of the variable!
return 0;
}
The expression char yourname; only holds space for a single character, so quite likely you end up corrupting the memory space when scanning for yourname. You should allocate a bigger buffer and make sure that you don't overrun its length by setting a maximum number of characters to be read with the scanf function; as described in some of the other answers.
The fact that the following printf print correctly the name doesn't mean that the memory doesn't get corrupted; as C/C++ don't really check the boundary of any strings or arrays used at runtime.
As suggested by others, starting by reading a good book about C and/or C++ wouldn't a bad idea.

Resources