0

This is part of a university lab and the TA tells me there is an error but I haven't a clue. When I run it it asks me for the first char but then runs through the program and doesn't ask me at the second scanf.

#include <stdio.h>

int main(void) {
    char sen, ben;

    printf("Type in a character: ");

    scanf("%c", &sen);
    printf("The key just accepted is %d", sen);

    printf("\nType in another character: ");
    scanf("%c", &ben);
    printf("The key just accepted is %d", ben);
}
Niall
  • 30,036
  • 10
  • 99
  • 142
Dale
  • 21
  • 5
  • 2
    That's not exactly C++. Or rather, you're not using anything from C++. –  Oct 03 '14 at 14:15
  • What is? During my lectures my prof only uses void main but that isn't correct either, right? – Dale Oct 03 '14 at 14:15
  • 1
    `'\n'` counts as another char and is consumed with the 2. `scanf()`. – πάντα ῥεῖ Oct 03 '14 at 14:15
  • 2
    i think 90% of c++ classes don't teach how to do things correctly in c++... – Rocky Pulley Oct 03 '14 at 14:15
  • Are you learning C or C++? If it's C++, then use the more convenient `std::cin` and `std::cout` rather than `scanf` and `printf`. If it's C, then don't tag it C++. – Mike Seymour Oct 03 '14 at 14:16
  • You could use `` instead of `` and `std::cout` and `std::cin` instead of `printf` and `scanf`. – wolfPack88 Oct 03 '14 at 14:16
  • removing '\n' didn't help – Dale Oct 03 '14 at 14:17
  • 1
    Also you've forgotten the return statement e.g. `return 0;` at the end. – Simon Oct 03 '14 at 14:18
  • Try `scanf("%c%c", &sen, &dummy);`? Where `dummy` is another `char`. As @πάνταῥεῖ points out, the "enter" is being consumed by the second `scanf`. – Niall Oct 03 '14 at 14:19
  • 1
    @TritonMan Seeing all theses comments makes me agree. This is the way I'm being taught. – Dale Oct 03 '14 at 14:19
  • @Dale I meant the `'\n'` you entered at the prompt of the 1st `scanf()` – πάντα ῥεῖ Oct 03 '14 at 14:20
  • 1
    @TritonMan You are right, 90% of the classes don't teach proper C++, but that's partly because they aren't _designed_ to do so. Universities are about teaching base concepts and principle ideas, which can be quite a shock to those who exit with expectations that they attended a job training camp. Dale, you will find that you will need to learn what they are teaching in class, __and learn how to program in C (or C++) properly__. Might as well start the latter non-school independent task now, it will pay off while you are in school. Start with -Wall (or equivalent) – Edwin Buck Oct 03 '14 at 14:25
  • This question is a duplicate of many others (but it will take me a while to find a good duplicate). Use `" %c"` to skip white space (such as the previous newline) before reading the character. Do not use `"%c "`; that is a really bad UI experience. – Jonathan Leffler Oct 03 '14 at 14:28
  • @EdwinBuck I agree, I was just talking with my boss about this who was complaining that his son wasn't learning useful stuff in his programming classes. I told him that the only thing he needs to learn in a programming class is how to think and how to learn. He won't use any of those specifics in a job anyway, things change too fast in this industry. – Rocky Pulley Oct 03 '14 at 14:39
  • @JonathanLeffler You are probably right, it is probably a duplicate; however, there is more than one way to solve this duplicate and a space before the %c solves it for a lot of use cases, but my "solution" solves it for other ones. Don't rush into duplicating it against _one particular solution_. – Edwin Buck Oct 03 '14 at 18:26

4 Answers4

1

Actually this is C not C++. Save it as file.c. Try this:

#include <stdio.h>

int main(void) {
    char sen, ben;
    printf("Type in a character: ");
    sen = getchar();
    printf("The key just accepted is %d", sen);
    printf("\nType in another character: ");
    getchar();
    ben = getchar();
    printf("The key just accepted is %d", ben);
}

Explanation: when you enter the first character and press enter it takes enter's ASCII code as the second. I suggest not to use scanf. But it works both ways if you put a getchar to "take" the enter.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
m0ur
  • 97
  • 2
  • 11
1

Adding a space before %c in the second scanf will solve the issue.

This is done because scanf does not consume the \n character after you enter the first character and leaves it in the stdin.As the Enter key(\n) is also a character,it gets consumed by the next scanf call.The space before the %c will discard all blanks like spaces.

When you are scanning a character(%c) using scanf,add a space before %c as it would help reduce confusion and help you. Therefore, in both the scanfs , you can add the space.

Spikatrix
  • 20,225
  • 7
  • 37
  • 83
0

When you pressed your key and then hit enter, you typed in two keys. The first was the desired key ,a for example, and the second was the key <enter> typically written as \n. So, your second scanf captures the result \n.

Since printing out the \n character doesn't result in something that is easy to see on the screen, it will appear like your program is just skipping the second scanf and printing out only the fixed parts of the printf without a easily viewable value.

One way to get around this problem is to consume all the key strokes just before the key you want to capture. This is done by accepting more input after the character up until you see a newline character \n. Once you see that character, then you do your next read.

// flush extra input up the to carriage return
char flush = 0;
while (flush != '\n') {
  scanf("%c", &flush);
}

// now read my desired input
scanf("%c", &ben);
Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
-1

that's because nobody accepts '\n'. call scanf like this scanf("%c%*c", &sen). %*c means you want to omit one character, which is '\n'.

btw, void main() is allowed. main function is not the real entry point of executable, so it's ok to do that. but it seems not everybody likes it.

Jason Hu
  • 6,239
  • 1
  • 20
  • 41
  • 1
    What do you mean by "btw, void main() is allowed. main function is not the real entry point of executable"? –  Oct 03 '14 at 14:31
  • @AlexM.: Read [What should `main()` return in C and C++](http://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c/18721336#18721336). Microsoft C explicitly allows `void main()` on Windows; it is a non-standard extension. The "is allowed" statement is too sweeping, but has a nugget of truth behind it, albeit a very exasperating one. – Jonathan Leffler Oct 03 '14 at 14:42
  • My question was referring more to "main function is not the real entry point of executable" –  Oct 03 '14 at 14:46
  • @AlexM.: OK, fair enough. Microsoft confuses that, too, but I'm not expert enough to disentangle the nuances of `main()` vs `wmain()` vs `WinMain()`. – Jonathan Leffler Oct 03 '14 at 14:52
  • Neither OP nor HuStmpHrrrr ever mentioned using Microsoft's compilers though. –  Oct 03 '14 at 14:56
  • @AlexM.: Yes, that's why the "is allowed" statement is too sweeping and the "not the real entry point" is also befuddling — it can only make sense in the MS environment or a freestanding (as opposed to hosted) implementation. None of the nuances necessary to justify the commentary are made — which is one reason I've left it down-voted. (The other is I don't much like the assignment suppression; I'd rather see `" %c"` used as the format. The assignment suppression will work — as long as the user doesn't type `abc` plus enter.) – Jonathan Leffler Oct 03 '14 at 15:01
  • @AlexM. `main` code is not the first instruction PC will point to right after the process gets created. the reason i "btw" is because i saw OP mention this in his comment and he considers it's not correct, which is not quite true. i am stressing this declaration is allowed in C and in executable's point of view. – Jason Hu Oct 03 '14 at 15:24
  • @JonathanLeffler i didn't say anything about MS standard. even though i use `int main()` as habit, but i would say there is nothing wrong to declare `void main()`. it works in gcc too. and it seems you are worrying about user may not obey the rule of input. but it's out of OP's problem. – Jason Hu Oct 03 '14 at 15:28
  • OK; you too should read the [What should `main()` return in C and C++](http://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c/18721336#18721336) answers. There is much that is wrong with `void main()` except on a MS platform. It is absolutely non-standard and not supported by the standard except as a documented extension by your compiler vendor. MS is a compiler vendor who has documented it as an extension. I'm not aware of a context other than MS Windows where `void main()` is documented as acceptable. – Jonathan Leffler Oct 03 '14 at 15:31