[c][explained] Problems with scanf

  Рет қаралды 65,109

theteachr

theteachr

3 жыл бұрын

I do my best to credit the sources and people that helped me with the content. For this one, I did get help from people on Reddit and Discord. :D
Some of the articles that I read to make this:
/ fun-with-scanf-in-c
stackoverflow....
I do know about the places where some of the lines are not consistent with the opacity, but meh, didn't do a retake, I apologize.

Пікірлер: 119
@theteachr
@theteachr 3 жыл бұрын
%s does not consume the whitespace ( ). It stops at one, and appends the null terminator. That explains why a space in a string doesn't get read into the buffer supplied to scanf. So, it's actually %d that discards the leading whitespace. Thanks to the redditor who pointed this out.
@maharun
@maharun 2 жыл бұрын
does float and double date types also discards the leading whitespace? please tell me...... and where is the reddit you are talking about?
@csbnikhil
@csbnikhil 11 ай бұрын
⁠@@maharunYes. They also discard the white space. The subreddit is C_Programming.
@Ramash440
@Ramash440 2 жыл бұрын
Wish I knew this years ago. When doing uni assignments which involved command line I/O this stuff was such a headache. Everybody in my class found a different way to reinvent the wheel and deal with this behavior.
@joaogabriels.f.5143
@joaogabriels.f.5143 2 жыл бұрын
You can use [^ ] to consume the ' ', like this: scanf("%[^ ]s", my_string); it reads: read everything that it's not ' '. the trick is that italso matches ' ' and consume it. So you can interpret it as "read eveything until new line, excluding the new line" this is great to read more than one word in a single sentence
@shadamethyst1258
@shadamethyst1258 2 жыл бұрын
I usually just `fgets` into a temporary buffer and then parse the value of that buffer. I don't like scanf's spurious behavior
@abhishek.rathore
@abhishek.rathore 2 жыл бұрын
@@shadamethyst1258 or just use a getline
@privileged6453
@privileged6453 2 жыл бұрын
@@abhishek.rathore getline is not a C standard library function, it’s a POSIX extension
@lembranaodesistaissonaoimp5762
@lembranaodesistaissonaoimp5762 2 жыл бұрын
Regex?
@joaogabriels.f.5143
@joaogabriels.f.5143 2 жыл бұрын
@@lembranaodesistaissonaoimp5762 meio que isso mesmo, o scanf aceita certas funcionalidades de regex.
@mitchellrose6865
@mitchellrose6865 3 жыл бұрын
Dude thank you so much. Every other solution I found online was crap. This is well explained and your editing is great. Very well made.
@diegoenriqueoviedollanes453
@diegoenriqueoviedollanes453 2 жыл бұрын
A good option also is to select what would be the maximum number of characters that scanf will read. char name[10]; scanf("%9s",name); So if the user writes more characters than 10, only the first 10 would be taken. Avoiding any buffer overflow.
@ramok1303
@ramok1303 2 жыл бұрын
Thanks
@NoNameAtAll2
@NoNameAtAll2 2 жыл бұрын
maybe only read 10-1 characters, and keep last one for guaranteed /0
@tomaszstanislawski457
@tomaszstanislawski457 2 жыл бұрын
Actually it **WILL** overflow the buffer for 10-letter input. It will place byte `0` at `name[10]` that does not exist overflowing a buffer. To fix it use "%9s" specifier
@diegoenriqueoviedollanes453
@diegoenriqueoviedollanes453 2 жыл бұрын
@@tomaszstanislawski457 I haven't programmed in c for a long time, I appreciate the correction if I wrote something wrong. Happy hacking!
@dipanjanghosal1662
@dipanjanghosal1662 2 жыл бұрын
@@diegoenriqueoviedollanes453 I'd advice you to edit your original comment to %9s because many people don't delve deeper into the replies.
@marshallbcodes
@marshallbcodes 11 ай бұрын
I was banging my head against the wall trying to figure this out. Thank you for the great explanation!
@claverbarreto5588
@claverbarreto5588 3 жыл бұрын
thanks for this, keep doing it, i found the video super helpful and it taught great things, the illustrations are amazing thank you.
@alexanderbarhoum5934
@alexanderbarhoum5934 8 ай бұрын
it's been 3 years and your video is still saving lives. thank you very much! ❤
@hiltonchapman4844
@hiltonchapman4844 Ай бұрын
Great explanation! It's great because it's CLEAR & CONCISE! May you travel a great distance into greatness! (I know.... after a 3 year lag!!!) HC-JAIPUR (30/06/2024) .
@ovutai363
@ovutai363 3 жыл бұрын
You're so cool, I love your "C explained" series
@desmondle4073
@desmondle4073 8 ай бұрын
This is an amazingly insightful video. Thankyou smmmm
@SloeElvis
@SloeElvis 2 жыл бұрын
This video is beautiful! May i ask what you used to animate it?
@theteachr
@theteachr 2 жыл бұрын
Thanks! It’s Keynote.
@DityoManob
@DityoManob 10 ай бұрын
Best explanation for the scanf issue.
@chimbwesa
@chimbwesa 3 жыл бұрын
how am i just finding this!? thank you commandah
@dharanishrahuls5705
@dharanishrahuls5705 3 жыл бұрын
Thank you so much. You were very clear in the explanation. Keep it up. U will reach the sky for sure.
@ishikani
@ishikani 2 жыл бұрын
One lovely trick that I have against this is literally a single macro which is #define CINFLUSH scanf("%*[^ ]");scanf("%*c"); Works every time, all the time.
@diegoenriqueoviedollanes453
@diegoenriqueoviedollanes453 2 жыл бұрын
I always used the space in the scanf, just because it works, thanks for explain that, now everything makes sense.
@ajtan2607
@ajtan2607 2 жыл бұрын
This is from my little "test" library (simplified): ``` void get_str(char *s, int n) { if (s != NULL && n > 0) { int len = 0, maxlen = n - 1; int c = getchar(); while (c != ' ' && c != EOF) { if (len < maxlen) { s[len] = c; len++; } c = getchar(); } s[len] = '\0'; } } ``` `s` is the storage and `n` is the storage capacity. The loop extracts all characters from `stdin` until a delimiter newline or `EOF` is found. The condition inside the loop makes sure that only the first `maxlen` characters (excluding the delimiter) are written to `s`. `maxlen` is `n - 1` because at least one element must be reserved for the null character. If you give the right arguments, you can type as much as you want without having to worry about buffer overflow. The function will get rid of the excess characters, including the delimiter. I think this is a nice little "training wheel" for beginners.
@shadamethyst1258
@shadamethyst1258 2 жыл бұрын
This is exactly what fgets does :)
@ajtan2607
@ajtan2607 2 жыл бұрын
@@shadamethyst1258 Not exactly. My function gets rid of the the other characters not stored in the array, including the delimiter newline. `fgets()` does not do this. Please read the description again carefully.
@reussunased5108
@reussunased5108 2 жыл бұрын
Me who only uses getline when reading input from user: *What is going on here ?*
@ramok1303
@ramok1303 2 жыл бұрын
Thank you for making this video you help me so much to understand problems with code you've made a really good job
@Reydriel
@Reydriel 2 жыл бұрын
I've been looking for info on why this happens in scanf for ages, thanks man
@ivanjermakov
@ivanjermakov 2 жыл бұрын
C is such a mess from a developer experience perspective (understandable, considering when it was introduced). I work as a software engineer for several years and have some C/C++ background, but I still watch the video open-eyed. Very good content and nice visuals.
@CrippleX89
@CrippleX89 2 жыл бұрын
Yeah C is really starting to show its age now. It’s been a good run but more modern languages are probably a better choice for most tasks. And with Rust being just as quick, capable, suitable as a systems programming language and becoming more and more mature, C and C++ probably will have to fight for its right to exist.
@bva0
@bva0 2 жыл бұрын
@@CrippleX89 Maybe C, but the new C++ standards have everything you'd want in a good language. Smart pointers, threading, softer typing, modular packages, among others...
@VeryAwesomeSheep
@VeryAwesomeSheep 2 жыл бұрын
@@bva0 C also supports threading
@c0smo709
@c0smo709 2 жыл бұрын
get good
@erek
@erek 2 жыл бұрын
@@bva0 maybe but all of the backwards compatibility in C++ makes the language very complicated and a horrible mess to deal with
@halbgefressen9768
@halbgefressen9768 Жыл бұрын
A good solution is using fgets in combination with another parsing method (strtol etc.)
@chaitanyasampara1169
@chaitanyasampara1169 2 жыл бұрын
Now I like C even more
@chaitanyasampara1169
@chaitanyasampara1169 2 жыл бұрын
Nice
@rishiktiwari
@rishiktiwari 2 жыл бұрын
I am pretty sure that this is the same problem as Java's scanner. Just write two scanner .nextLine() inputs one after the other and it skips the 2nd one when executed.
@theteachr
@theteachr 2 жыл бұрын
Yep, it suffers from the same thing.
@vikidprinciples
@vikidprinciples Жыл бұрын
Man I wasted so much time because of this problem! Thanks for the explanation
@xabe1
@xabe1 2 жыл бұрын
Thanks for tge video! I programming on C a lot of time and I never faced this problem, I sure that this knowledge will help me in the future.
@diegoenriqueoviedollanes453
@diegoenriqueoviedollanes453 2 жыл бұрын
Thanks for that useful way of asking for input, my programs were full of fflush, not anymore
@diegoenriqueoviedollanes453
@diegoenriqueoviedollanes453 2 жыл бұрын
Really nice quality, keep that good work
@dawaxd
@dawaxd 2 жыл бұрын
very good explanation! helped me a lot
@tamjidyetagain
@tamjidyetagain Жыл бұрын
Thanks it helps a lot
@hwstar9416
@hwstar9416 7 ай бұрын
2:01 actually the is still in stdin, however when you read the %d it consumes the looking for an integer
@theteachr
@theteachr 7 ай бұрын
Addressed in the pinned comment with a little more detail.
@krzysiu3991
@krzysiu3991 2 жыл бұрын
thank you so much, saved my time
@code-to-learn
@code-to-learn 2 жыл бұрын
Nice presentation
@maharun
@maharun 2 жыл бұрын
you made a mistake... %s doesn't consume new line.. it leaves the in the stdin buffer.. try taking a string then take a char1 input then take char2 input when you will run it 1. you enter the string 2. it SKIPS char1 input 3. goes to char2 input so %s never consumes new line
@theteachr
@theteachr 2 жыл бұрын
I address this in my comment.
@windowsxseven
@windowsxseven 2 жыл бұрын
@@theteachr "I address this in my comment" 🤓 screw off
@gianzindozap
@gianzindozap 2 жыл бұрын
You could also use %*c to clean the buffer
@kiitekogra4012
@kiitekogra4012 Жыл бұрын
Thanks😊
@obaodelana
@obaodelana 3 жыл бұрын
Great explanation!
@glewfw7989
@glewfw7989 2 жыл бұрын
im amazed this dude called noob to everyone that uses scanf lol
@bobmichael8735
@bobmichael8735 Жыл бұрын
Great video! What software did you use for editing this video?
@theteachr
@theteachr Жыл бұрын
Keynote :D
@GrandNecro
@GrandNecro 2 жыл бұрын
what software did you use to edit the video?
@chri-k
@chri-k 2 жыл бұрын
Apparently it was made using keynote
@sameerkulkarni8176
@sameerkulkarni8176 3 жыл бұрын
That's awesome.....👌👌
@Voltra_
@Voltra_ 2 жыл бұрын
This random youtuber succeeded where teachers have failed, thx. Although I just use C++ instead
@lakshanchamod1208
@lakshanchamod1208 11 ай бұрын
thnks
@edwardmacnab354
@edwardmacnab354 2 жыл бұрын
very enlightening
@matheusaugustodasilvasanto3171
@matheusaugustodasilvasanto3171 2 жыл бұрын
Excellent video, thank you for the explanation. What font is being used here?
@theteachr
@theteachr 2 жыл бұрын
DM Mono, iirc.
@Quzhisnadja128
@Quzhisnadja128 2 жыл бұрын
Thank you sir
@mohansivadhas
@mohansivadhas 2 жыл бұрын
Thanks Dude!!! u r great!
@nihildicit4217
@nihildicit4217 2 жыл бұрын
char str[101]; scanf("%100[^ ]", str); while(getchar() != ' '); This solves some of the problems but not all of them.
@tadiwrr
@tadiwrr 3 жыл бұрын
thank you
@demnyan
@demnyan 2 жыл бұрын
cin cout one love 🦊💖
@theteachr
@theteachr 2 жыл бұрын
If you do a cin on an int, but the user entered something that could not be parsed as one, the variable would be set to 0. I had no idea how to differentiate between a valid input of 0 and an invalid input, as in both the cases the variable would have the same value. It sets some global error flag (I think). IMO, it should have been something that the programmer couldn’t skip.
@demnyan
@demnyan 2 жыл бұрын
@@theteachr for int you can use atoi( ) and there will be no errors )
@avastorneretal
@avastorneretal 2 жыл бұрын
std::cout
@sahil1307
@sahil1307 2 жыл бұрын
Can you please tell me from where you learnt this Any book, website, playlist
@carloscapitinealexandremut8898
@carloscapitinealexandremut8898 3 жыл бұрын
Thanks for the explanation, but i coud't get the problem solved. is there any other way to get out of this?
@theteachr
@theteachr 3 жыл бұрын
Having `while (getchar() != ' ');` before scanning a sequence of characters should work just fine. Join the Discord and post the query for a more elaborate explanation specifically tailored to your use case. discord.gg/ANUEGSZPvn
@sadhmansarker9133
@sadhmansarker9133 Жыл бұрын
can smn explain the while (getchar() != ' '; part i dont get it
@theteachr
@theteachr Жыл бұрын
I shall.
@dhawan177
@dhawan177 Жыл бұрын
Thank you so much i am new to coding and this was soo annoying to see even when i write the code correctly it will just stop. Thak you
@oanminhkhoi6584
@oanminhkhoi6584 7 ай бұрын
But why adding that weird space before %c would make it work ?
@theteachr
@theteachr 7 ай бұрын
A space in the format string for `scanf` means any amount of whitespace (newlines, spaces, tabs, ...). `scanf("%c %d", &gender, &age)` would read the input `m 45` and assign `m` to `gender` and `45` to `age`.
@oanminhkhoi6584
@oanminhkhoi6584 6 ай бұрын
​@@theteachr Appreciate the reply. Thanks alot
@yooyo3d
@yooyo3d 2 жыл бұрын
scanf("%[^ ] ", name); Read everything til new line into name then consume new line.
@techeadache
@techeadache 11 ай бұрын
I tried this! The function scanf(_s) never returns. It's an infinity loop for string input. Although, it works for anyting that is NOT a string. For example, scanf_s("%c ", &gender, 1u); // WORKS AND RETURNS
@cyrileo
@cyrileo 2 жыл бұрын
+10 social creit score ⬆
@alejandroalzatesanchez
@alejandroalzatesanchez 2 жыл бұрын
and we have problems with like python/java/lua/etc this is worse
@katsumikougen8351
@katsumikougen8351 3 жыл бұрын
Bisqwit brought me here.
@theteachr
@theteachr 3 жыл бұрын
This sent me to Bisqwit.
@eldiablo9541
@eldiablo9541 2 жыл бұрын
You would think that after all this time something as simple as this would have been "fixed". I wonder why they haven't changed that
@floskater99
@floskater99 2 жыл бұрын
Pretty sure Scanner.nextLine() and Scanner.nextInt() in Java have exactly the same problem xD
@theteachr
@theteachr 2 жыл бұрын
Yes, it does.
@23trekkie
@23trekkie 2 жыл бұрын
Name: Genie Age: six Age: Age: Age: Age: Age: Age: Age: Age:....
@leoleo10xd
@leoleo10xd Жыл бұрын
does this problem have a name?
@theteachr
@theteachr Жыл бұрын
I wouldn’t think so. It’s expected behavior after all. The programmer is expected to know of the subtlety and that’s what is the problem.
@CurrentlyObsessively
@CurrentlyObsessively 3 жыл бұрын
These fixes are not effective. You should test input at each input. You can even write a small input check function to consolidate your code. I recommend Hacking the Art of Exploitation by Jon Erickson. The chapter on programming is strictly C programming and has numerous examples of input and error checks.
@theteachr
@theteachr 3 жыл бұрын
Thanks for the input and the recommendation!
@samuelwaller4924
@samuelwaller4924 2 жыл бұрын
Your first problem was only having two genders lol
@theteachr
@theteachr 2 жыл бұрын
I want more reactions than just being able to ❤️ the comments.
@johnjcb4690
@johnjcb4690 3 жыл бұрын
VERY NICE explaining and work , great. But It is not working in Eclipse. First Scanf processes, the second to last not, And it would only print PRintfs. All correct include int main() { char name[20]; float greutate; int ziua; int luna; int an; //scanf("specificatori de format", adresele_din_memorie);// printf("Name of sir: :"); fflush(stdout); scanf(" s", nume); printf("Cat este de greu domnul:[kg] "); fflush(stdout); scanf(" %f", &greutate); printf("Dati ziua: "); fflush(stdout); scanf(" %d", &ziua); printf("Dati luna: "); // windows fflush(stdout); scanf(" %d", &luna); // afisare ziua si luna an = 2020; printf("Astazi este %d/%d/%d!", ziua, luna, an); return 0;
@theteachr
@theteachr 3 жыл бұрын
scanf("%s", nume); I think the missing % is causing you an issue.
@blushy9215
@blushy9215 2 жыл бұрын
its pronounced char as in charcoal not care........ 👎👎👎 boo
@ivanborsuk1110
@ivanborsuk1110 2 жыл бұрын
so unnecessary
@chri-k
@chri-k 2 жыл бұрын
What exactly?
@leoleo10xd
@leoleo10xd Жыл бұрын
" %[^ ]s " worked for me. printf(" Name: "); scanf(" %[^ ]s ", vec[i].name);
Master Pointers in C:  10X Your C Coding!
14:12
Dave's Garage
Рет қаралды 297 М.
why do void* pointers even exist?
8:17
Low Level Learning
Рет қаралды 351 М.
小丑和奶奶被吓到了#小丑#家庭#搞笑
00:15
家庭搞笑日记
Рет қаралды 8 МЛН
Son ❤️ #shorts by Leisi Show
00:41
Leisi Show
Рет қаралды 10 МЛН
Dear Game Developers, Stop Messing This Up!
22:19
Jonas Tyroller
Рет қаралды 703 М.
Naming Things in Code
7:25
CodeAesthetic
Рет қаралды 2,1 МЛН
Scanf Basics: the good, the bad, and why so many pointers?
15:07
Jacob Sorber
Рет қаралды 23 М.
fgets is unsafe! So what’s the alternative?
11:32
Code With Huw
Рет қаралды 2,8 М.
Premature Optimization
12:39
CodeAesthetic
Рет қаралды 787 М.
Giving Personality to Procedural Animations using Math
15:30
t3ssel8r
Рет қаралды 2,5 МЛН
why do hackers love strings?
5:42
Low Level Learning
Рет қаралды 405 М.
31 nooby C++ habits you need to ditch
16:18
mCoding
Рет қаралды 763 М.
Arenas, strings and Scuffed Templates in C
12:28
VoxelRifts
Рет қаралды 82 М.
Be Careful When Using scanf() in C
12:22
NeuralNine
Рет қаралды 127 М.
小丑和奶奶被吓到了#小丑#家庭#搞笑
00:15
家庭搞笑日记
Рет қаралды 8 МЛН