There are a few potential causes, some of which have been mentioned in the comments (I won't cover those). It's hard to say which one (or more) is the cause of your problem, so I guess it makes sense to iterate them. However, you may notice that I cite some resources in the process... The information is out there, yet you're not stumbling across it until it's too late. Something needs to change with how you research, because this is slowing your progress down.
On input/output dynamics, just a quick note
printf("%s",input1);
Unless we include a trailing newline, this output may be delayed (or "buffered"), which may have the effect of confusing you about the root of your issues. As an alternative to using a trailing newline (which I'd prefer, personally) you could explicitly force partial lines to be written by invoking fflush(stdout)
immediately after each of the relevant output operations, or use setbuf
to disable buffering entirely. I think this is unlikely to be your problem, but it may mask your problem, so it's important to realise, when using printf
to debug, it might be best to include a trailing newline...
On main
entry points
The first potential culprit I see is here:
int main()
I don't know why our education system is still pushing these broken lessons. My only guess is the professors learnt many years back using the nowadays irrelevant Turbo C and don't want to stay up-to-date with tech. We can further reduce this to a simple testcase to work out if this is your segfault, but like I said, it's hard to say whether this is actually your problem...
int main() {
char input1[30];
memset(input1, '\x90', sizeof input1);
return 0; // this is redundant for `main` nowadays, btw
}
To explain what's going on here, I'll cite this page, which you probably ought to go and read (in its entirety) once you're done here:
A common misconception for C programmers, is to assume that a function prototyped as follows takes no arguments:
int foo();
In fact, this function is deemed to take an unknown number of arguments. Using the keyword void within the brackets is the correct way to tell the compiler that the function takes NO arguments.
Simply put, if the linker doesn't know/can't work out how many arguments are required for the entry point, there's probably gonna be some oddness to your callstack, and that's gonna occur at the beginning or end of your program.
On input errors, return values and uninitialised access
#include <assert.h>
#include <stdio.h>
#include <string.h>
int main(void) {
char input1[30];
memset(input1, '\x90', sizeof input1);
scanf("%s",input1); // this is sus a.f.
assert(memchr(input1, '\0', sizeof input1));
}
In my testcase, I actually wrote '\x90'
to each byte in the array, to show that if the scanf
call fails you may end up with an array that has no null terminator. If this is your problem, this assertion is likely to throw (as you can see from the ideone demo) when you run it, which indicates that your loop is likely accessing garbage beyond the bounds of input1
. On this note I intended to demonstrate that we (mostly) cannot rely upon scanf
and friends unless we also check their return values! There's a good chance your compiler is warning you about this one, so another lesson is uto pay close attention to warning messages, and strive to have none.
On argument expectations for standard library functions
For many standard library functions it may be possible to give input that is outside of the acceptable domain, and so causes instability. The most common form, which I also see in your program, exists in the form of possibly passing invalid values to <ctype.h>
functions. In your case, you could change the declaration of current
to be an unsigned char
instead, but the usual idiom is to put the cast explicitly in the call (like isdigit((unsigned char) current)
) so the rest of us can see you're not stuck in this common error, at least while you're learning C.
Please note at this point I'm thinking whichever resources you're using to learn aren't working, because you're stumbling into common traps... please try to find more reputable resources to learn from so you don't fall into more common traps and waste more time later on. If you're struggling, check out the C
tag wiki...