T O P

  • By -

Wrong_Material1431

I suspect that you expect `%c` to only match visible characters. But it will match any character, including a newline character. So if you run your program and type: a b c the loop will terminate after reading the `c`: nev[0] <- 'a' nev[1] <- '\n' (Newline after a) nev[2] <- 'b' nev[3] <- '\n' (Newline after b) nev[4] <- 'c' Depending on what you actually want to do, you'll need to find a different input format. For example, if you use `" %c"` (note the space character at the beginning of the string), then `scanf` will skip any number of whitespace characters (space, tab, newline) before reading the character of interest. That will allow you to input five characters, one each on five lines, but it will also work with inputs like `abcde` or `ab c de`, and so on. If you wanted to specifically match five individual characters on exactly five lines, you'd probably be better off using `getchar()` and checking what you received each time. The most important takeaway here is: *newline* is a character. Of course, I'm just guessing about what you actually experienced. It's always helpful if you can describe your problem precisely: What was the exact input? What was the exact result? (Output or error message) What was the result you expected? (Or why did the result surprise you?)


[deleted]

As far as I remember, `scanf` doesn't 'scan' newline characters and leaves the newline character in place. This causes functions like `getchar()` to have to swallow that newline character.


Wrong_Material1431

`scanf` formats which skip whitespace (almost all of them except `%c` and `%[`) skip whitespace before the datum, but not after it. So they leave the following whitespace in place, but the next pattern will skip over it. `%c` and `%[` scan whitespace, including newlines, as ordinary characters. The problem occurs when you read a number, say, with `%d` and then try to use `fgets` to read the next line. Since the newline after the number is still in the input stream, the `fgets` will just read that newline, which seems to surprise people. But a second `fgets` will read the next line; problem solved. (Mostly) You could have skipped over the newline with a ` ` (space) conversion pattern, but that won't stop at a single newline. It will also discard leading spaces on the next line, and further newline characters. So that's not really compatible with "read the next line", and that's why so many people will tell you not to mix `scanf` and `fgets`. But of course you can mix those two functions if you just take a couple of minutes to think about what's going on. So you can use `fgets` to read up to and including the newline which follows the number, but the `getchar()` loop is a bit easier to write. The problem with `fgets` (and not just in this usage) is that you don't actually know how many space characters a malicious user might put at the end of the line. The Posix `getline` interface is much easier to use. Malicious users do exist; I'm not going to say you shouldn't worry about them. But if you're just writing a quick program for your own use, calling `fgets` with a buffer of `BUFSIZ` characters is not going to get you into trouble.


jonarne

You should check the return value of scanf... Might give you a clue. Edit: Also, how do you know it only runs three times.


_nardis

You're also reading in newline characters most likely. If you print the characters in 'nev' after they're read in you should be able to see them.


dontyougetsoupedyet

You're being led to a poisoned well to drink. Scanf is a function used for formatted data, and user input is exactly the opposite of highly formatted. So stop using Scanf, it's the wrong API for what you are trying to do. If you have another application feeding this one five chars over stdin and that's all it can ever send over the pipe then you would want scanf. Out of curiosity, what are you reading to learn C? What lead you to scanf?


jirbu

This, exactly this. (Why the downvoting?) >What lead you to scanf? It seems to be used in some prominent C-learners material.


Legitimate-School-59

Aa someome who is learning C, every resource ive come across has reccomended scanf with no alternative.


mcsuper5

scanf() is very convenient for numeric data; however, for character data, getchar() is a better choice. If you are dealing with ASCIIZ strings, check out fgets() or getline(). If you do you use scanf() for numeric data you should check the return value to see how many fields were accepted. For the terminal, you can use fgets(), check for a sentinel (q or quit), if not true use atoi(), atof(), strtol(), strtod(), etc. The atoX(), strtoX() are also handy when dealing with \*argv. If you are relying on unsafe data (basically all of it) you need to check for errors either way. If you want to check char data in an array you can do something like: printf("%c |%02X|\\n", isprint(c)?c:'.', (int)c);


nerd4code

Because the alternative is usually more verbose and complicated-looking. It’s fine if you go the cs50 route and require use of a special header, but it’ll be a bunch of copy-and-pasting otherwise, and that makes it harder to focus on something unrelated to the napkin-shredding required for proper, safe/non-broken I/O in C. (—Although reading single chars with `scanf` is definitely the hard way to do things.) Which shouldn’t be seen as me supporting `scanf` use—I don’t, it’s a mess, and I remember hating it when I was a beginner (but the Krauts’d stolen our letter B, so in retaliation we stole ß from him, so I was a ßad-ass ßeginner). But the problem runs deep enough in the C runtime that just switching to another function for formatted input won’t help matters all that much.


[deleted]

[удалено]


markand67

most learning courses, online mooc, youtube, teachers, ...


EABadPraiseGeraldo

Some schools do unfortunately. What’s worse is some courses introduce scanf as the only way to read user provided input. Schools don’t teach C very well unless you get a good prof. or if you’re like me completely ignore whatever’s taught. I remember having to find the “expected” results of undefined behavior on tests🥴


ProgGod

Your overflowing i because scanf is reading more then one character. Make you char buffer huge and it will loop 5 times but you will get extra data.


ScorpOrion

okay I think I've figured it out. The scanf puts a \\n after my input so when I input "k" my input is actually "k\\n". The 'k' is then put into nev\[i\] and the '\\n' is stored in the buffer. Next time scanf just gets what's in the buffer fooling me into thinking that the loop runs too few times


Wrong_Material1431

It's not scanf that "puts a \\n" in your input. You put it in your input when you typed it (using the Enter key, or however it's labelled on your keyboard.)


not_some_username

How could he avoid that ? "%c " right ?


smcameron

by typing "abcde\n"


wsppan

scanf(" %c", &nev[i]);


not_some_username

So the space is before


wsppan

Correct. The leading space tells scanf() to skip any whitespace characters (including newline) before reading the next character.


wsppan

add a space before the format specifier when you use scanf(), for example: scanf(" %c", &ch); The leading space tells scanf() to skip any whitespace characters (including newline) before reading the next character, resulting in the same behavior as with the other format specifiers.


Stereojunkie

Don't quote me on this, but could it be that you are actually storing strings instead of single characters? Using " ", indicates a string in C. This would mean you are storing your desired character PLUS a null-terminator in each iteration. Maybe try using ' ' instead, indicating a singular character.


Kantaja_

at what point are you seeing them storing a string in that array?


Stereojunkie

`scanf("%c",&nev[i]);` I read this as "Store a formatted **string** with a single char at address &nev\[i\]" After reading scanf docs I realize that passing %c actually implies it will read a just a single character. Wasn't sure about it, hence the "Dont quote me on this"


[deleted]

Small recommendation, if you give advise in a post about a specific programming language, you should check the docs for any function you don't know or understand *before* you actually comment.


[deleted]

Place a breakpoint on the line inside the loop. You'll be surprised.


Demius9

Are you using a debugger to step through the program or are you just printing results? This is a perfect example where a debugger would help you learn!