You scanf format specifier "%[^105]s" uses a character class [...] which is a stand-alone specifier in and of itself and does not requires 's' at the end. By placing 's' at the end you are forcing scanf to look for a literal 's' following an unlimited number of characters NOT including 1, 0, 5.
It appears you intended to use the number to protect your arrays bounds -- which is a good thing, but the proper format in that case is "%104[^\n]" which will read up to 104 characters that do not include a '\n' (preserving space for the nul-character).
For example:
if (scanf("%104[^\n]",z) == 1)
printf("%s %s\n",s,z);
(note: ALWAYS validate ALL user-input by at minimum checking the return)
Also note: by NOT reading the '\n' above, it is left in your input buffer (stdin) unread, and if your next attempted input is "%c" or "%[...]", you will take the '\n' as part of your input as nether "%c" or `"%[...]" consume leading whitespace.
Putting it together in an example you could do:
#include <stdio.h>
int main (void) {
char s[] = "Apple";
char z[105];
printf ("enter z: ");
if (scanf("%104[^\n]",z) == 1)
printf("%s %s\n",s,z);
else
fputs ("error: stream error or user canceled.\n", stderr);
return 0;
}
(note: instead of scanf for reading lines, fgets() is recommended, then simply trim the '\n' included in the filled buffer)
Example Use/Output
$ ./bin/oneline
enter z: is a fruit
Apple is a fruit
Use fgets() Instead
Instead of using scanf for line input, use a line-oriented input function like fgets() which will consume an entire line (including the line ending). The ensures your input buffer is left in a consistent state that does not depend on the previous format specifier user, e.g.
...
#include <string.h>
...
printf ("enter z: ");
if (fgets (z, sizeof z, stdin) != NULL) {
z[strcspn (z, "\n")] = 0; /* trim '\n' from end of z */
printf("%s %s\n",s,z);
}
Edit Per-Question in Comment
Your Problem With Your New Code Is scanf("%lf",&y); leaves the '\n' in stdin unread, you then attempt to read scanf("%[^105\n]",z); which reads nothing because you have excluded reading '\n' in the inverted character class and you then read stdin as input where the first character is '\n'. "%[^105\n]" means : read an unlimited number of characters and only stop the read if a 1, 0, 5 or '\n' character (or EOF) is encountered.
Taking mixed input with scanf is full of Pitfalls for new C programmers because of what is left in stdin, and how leading whitespace is handled depends on the format-specifier used. This is why fgets() (or POSIX getline()) are recommended for user input, and then parsing the needed information from the filled buffer with sscanf. With a line-oriented input function, the line is completely consumed on each input (given a sufficient buffer size -- don't skimp), eliminating the problems with scanf.
To make your current code work, you could do:
#include <stdio.h>
/* simple function to empty remainder of line in stdin */
void empty_stdin (void)
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
int main (void) {
int i = 4, x;
double d = 4.0, y;
char s[] = "Apple ", z[105];
scanf("%d",&x);
scanf("%lf",&y); /* leaves '\n' as next char in stdin */
empty_stdin(); /* empty extraneous characters */
scanf("%104[^\n]",z); /* read up to 104 chars, \n, or EOF */
printf("%d\n",i+x);
printf("%0.1lf\n",d+y);
printf("%s %s\n",s,z);
return 0;
}
(validate each call to scanf -- that is left to you)
Let me know if you have further questions.