Scanf Basics: the good, the bad, and why so many pointers?

Scanf Basics: the good, the bad, and why so many pointers?

Jacob Sorber

1 год назад

22,033 Просмотров

Ссылки и html тэги не поддерживаются


Комментарии:

Skeleton_craft (the skeleton king) Gaming
Skeleton_craft (the skeleton king) Gaming - 30.10.2023 00:04

Regarding the last question, at least , because C doesn't have C++ style references... In C++ you should always use std::cin (or std::ifstream for places where you would use fscanf) partially because of the aforementioned pointer issues...

Ответить
Marios P.
Marios P. - 18.08.2023 13:42

I am really glad I found your channel, very useful information and well presented. Thank you!

Ответить
Kase
Kase - 31.07.2023 00:03

So I should better stop using scanf in favor of fgets? at least for strings, in case of numbers I guess I'm stuck with scanf

Ответить
Leandro Calil
Leandro Calil - 30.07.2023 16:03

Yet another great video ❤

Ответить
Marcin Pasternacki
Marcin Pasternacki - 09.07.2023 20:08

Typing in letter when program expects a number:
Python - throws an error and ends 😎
Pascal - throws an error and ends 😎
Commodore 64 basic - just asks again 😎
Go - assigns 0 to the variable 😎
C - infinite loop until your CPU is on fire🤬
(yes, I know I can walk around this using char array and fgets and sscanf functions, but still...)

Ответить
ZeroCool2211
ZeroCool2211 - 03.07.2023 13:58

Just one note, fflush has an undefined behaviour when it is being used for stdin because it is originally was made for stdout

Ответить
Charan Koppineni
Charan Koppineni - 29.05.2023 22:27

Where can I buy this t shirt ?

Ответить
Bryan Chance
Bryan Chance - 10.05.2023 04:31

This explain so well why I love C. I initially had all the problems you described here with using scanf(). But when I read up on the function details, I found a solution which you described here (with the nextchar , buffer flush, and while loop). Now, some would say that's a lot of work for such a simple thing. Well, I've never written a C program that only use scanf(). SO there's a little bit of setup, putting this in a functio and call it from the rest of your code. What it gives you a the building blocks to read an input. Let's say my input a huge file and I've pre-checked and data is clean, then it's faster to use scanf() without all the error checking. And it makes sense why scanf() works the way it does, not some kind of magic. And the buffer overflow, again put it your custom "input function" or something. LOL modern programmers.. (err developers rather). At least with my experience, it takes some time to figure out C.. it's not Python where you can't just slurp an entire text file into an array, even if the file is 10gb. LOL

Ответить
The Habsburg
The Habsburg - 06.04.2023 20:28

Tokenizing free knowledge.

No

Ответить
1873Winchester
1873Winchester - 14.02.2023 22:08

Newbie to C here but I think I would try and use the isdigit function, it only checks a char at a time, but you can write a new function using isdigit, or just copy the one on stackoverflow. So if (0 == (isdigits(result))) or something like that.

Ответить
Ukase
Ukase - 13.02.2023 22:51

hi jacob can u make a video about register level programming in embedded systems would be a nice topic. love so much your content

Ответить
aaaowski
aaaowski - 10.02.2023 22:28

>write my own scanf
thats the first thing that came to my mind

why not just use "read (1, buff, buffsize)"?

Ответить
Un Perrier
Un Perrier - 02.02.2023 23:39

A way to workaround buffer overflows is to use "%ms" and provide the address of the string variable. scanf will allocate the string for you (similar to asprintf)
It is part of the POSIX standard so not a problem on Linux, but not available on Windows (which is compliant with the old POSIX-1 standard) and likely not on embedded.
Note that it used to be "%as" (very old compilers/libc)

Ответить
AIN ectroniC.
AIN ectroniC. - 02.02.2023 18:50

Hey, can you maybe make a video about filesystems?

Ответить
Arun Kumar A.J
Arun Kumar A.J - 02.02.2023 14:42

thanks jacob. i now understand why my scanfs didnt work in college days... <3

Ответить
Bertrand
Bertrand - 01.02.2023 22:18

Scanf is full of amazing stuff when you consider it, especially when you consider its behavior when treating non-format specifier. For example something like:

result = scanf(" %*dinput%d%c", &x, &trailing_char);
Which is probably the closest thing standard C got to regex.

When starting with C, I tought that the best part of printf and scanf was print and scan but when I started to understand what they did, I realized that the best part of it is actually the f.

Ответить
ure mom
ure mom - 01.02.2023 18:20

fgets master race

Ответить
Aye Whistle
Aye Whistle - 01.02.2023 15:48

really love someone who addresses scanf and printf as function and further explain pass by value n pass by reference , as many tutorials just call them this is the way to get input and display output ! ,!!

Ответить
Coders Tube
Coders Tube - 01.02.2023 10:32

This video on Scanf Basics is an absolute game-changer! It's exactly the type of content I've been searching for. I'm so glad I stumbled upon this video. It has inspired me to create more programming content on my channel. Thank you for sharing your knowledge, I can't wait to see more from you! 🦾

Ответить
nunyobiznez
nunyobiznez - 01.02.2023 03:17

fflush(stdin) on an input stream, is undefined behavior. It works on WIndows, where there's poor standards compliance. But MSYS2, Cygwin, BSD, and Apple all should use fpurge(stdin) and Linux uses __fpurge(stdin) from Solaris, defined in stdio-ext.h. They really need to ISO standardize fpurge(), or even POSIX, but neither board likes moving too quickly and it hasn't yet been 40 years yet 🤣. It's a bit of a mess. I just took the time to write my own header, so I can use a fpurge() macro that'll select the correct function for the system, that can be dropped in and used everywhere, when I need to write portable code. Or there's also the minimally flawed alternative: while((getc(stdin) != '\n'));

Ответить
Zaphod Beeblebrox
Zaphod Beeblebrox - 01.02.2023 01:12

scanf() has the ability to take length as a parameter.

Ответить
Tshaka Lekholoane
Tshaka Lekholoane - 31.01.2023 22:14

There's also the bounds checked scanf_s from C11.

Ответить
zxuiji
zxuiji - 31.01.2023 21:02

Can avoid the whole pointer issue and verify input by just making a custom function:

uintmax_t parseju( FILE *file, char *stopped )
{
uintmax_t value = 0;
unsigned int c = 0;
int was = 0;
while (1)
{
was = fgetc();
c = was - '0';
if ( c > 9 )
break;
value *= 10;
value += c;
}
if ( stopped ) *stopped = was;
return value;
}

Don't remember how to "put back" the read character but you get the gist

Ответить
redorange
redorange - 31.01.2023 20:32

Why doesn't it skip the second scanf when there's apparently still the '\n' in the buffer?

Ответить
Chris Kelling
Chris Kelling - 31.01.2023 20:25

This is cool. I can think of several instances where I want mixed input say like the value then units like 13' 4" or 37F.

Ответить
Hans Bezemer
Hans Bezemer - 31.01.2023 20:21

I've been programming in C since 1987 and I can honestly say I NEVER used scanf() in any of my programs. Its behavior is simply too murky for my taste. Like you said, I'd rather read in the whole shebang using fgets() and tokenize the whole bunch myself (not necessarily using strtok() for that).

Just for fun, I've been doing a sscanf() like routine for my own Forth compiler - and still: some behavior of scanf() was baffling me. A few changes I made:

(1) My ”SSCANF” really doesn't like whitespace - neither in the buffer nor in the format string. When it encounters it, it will vehemently look for the first ”non-white space” character and resume parsing from there. Which means that these format strings are equivalent: "%c %c %c" and "%c%c%c".

(2) When parsing it takes a real good look at the delimiters you defined in the format string. If you define: "%s" and your buffer contains ”Hans Bezemer”, it will parse the entire string. However, if you define: "%s ", it will only parse ”Hans” and leave the rest of the buffer unparsed.

The upside of all this is, is that strings in the buffer are not automatically delimited by whitespace. Take "Invoice issued by [%s] on %u-%u-%u". If we feed ”SSCANF” this buffer: "Invoice issued by [Hans Bezemer] on 2022-04-03", it will happily read the entire ”Hans Bezemer” - and not just ”Hans”.

Still - although it was lots of fun to develop, I've never used it (yet) in my own Forth programs. I still don't trust it with real world data ;-)

Ответить
Kiyotaka
Kiyotaka - 31.01.2023 19:33

using FORTIFY_SOURCE with gcc prevents some simple buffer overflows, This would be a cool trick to show

Ответить
xCwieCHRISx
xCwieCHRISx - 31.01.2023 19:31

I use fgets compined with sscanf to read user input.

Ответить
Thwy
Thwy - 31.01.2023 19:25

as far as i know, fflush(stdin) has undefined behavior and it doesn't work with GCC on Linux.

You're living dangerously there.

Ответить
pavi2410
pavi2410 - 31.01.2023 18:00

Do you Rust?

Ответить
Abdelrahman Emad
Abdelrahman Emad - 31.01.2023 17:11

Awesome ❤️❤️❤️
Could you tell us the name of font you are using in vs code?

Ответить
Benjamin Rich
Benjamin Rich - 31.01.2023 17:10

Jacob, these 'deeper look at the basics of C' kind of videos are really useful. Great stuff.

Ответить
FeFi
FeFi - 31.01.2023 17:03

Your videos are awesome
Huge thanks

Ответить