Why aren't my strings printing the proper value? - c

Here is my code to print the string
char accname[MAX][MAXSTRING], transname[MAX][MAXSTRING];
printf ("Enter title for new account: ");
accname[i][i] = validatestring();
printf ("\n");
printf ("Enter title for transaction: ");
transname[i][i] = validatestring();
printf ("\n");
printf ("%s %s", accname[i], transname[i]);
my code for validatestring()
char validatestring() {
int keeptrying = 1, rc;
char i[31];
do
{
rc = scanf("%30[^\n]", &i);
if (rc == 0)
{
printf (" **Invalid input try again: ");
clear();
}
else if (getchar() != '\n')
{
printf (" **Title is longer than 30 characters: ");
clear();
}
else
{
keeptrying = 0;
}
} while (keeptrying == 1);
return i;
}
at the printf stage for accname[i] / transname[i] i don't get the value I entered, I get weird conversion string types, sometimes I got the first character of my input but now I get something completely different. Can anyone figure out why?

Your validatestring function is hopelesely broken.
Firstly, you declared validatestring as returning char. Yet you attempt too return a char * from it (see return i, where i is char [31]). This should not even compile.
Secondly, if you intend to return a string from validatestring, you have to make sure that you are not returning a pointer to a local buffer from it. i is a local array. A pointer to i cannot be returned from validatestring.

Yeah that is because what you are doing is trying to store everything in one char.
array[i][i]
which is a character position in which you are trying to store everything in it
I think what you intend to do is
*array[i] // It is a pointer to that location which you referring to.
This will store your string in array[i] from which you can access your characters using
array[i][i]
I hope this solves your problem.Also your function should return a char pointer char*.
This should do it:
*accname[i] = validatestring();
Also change the return type of your function to char*

Related

Strings in a FOR loop

I got a question.
I want to have a FOR loop that prints back text many strings. Lets say I type my forename and last name. And a FOR loop produce the strings.
#include <stdio.h>
int main(){
char str1 [12];
char str2 [12];
char wordarray [2]={str1,str2}; // error here
int i;
printf ("Type your forname : ");
scanf ("%s",&str1);
printf ("\nType your last name : ");
scanf ("%s",&str2);
printf ("\n\nYour name is : ");
printf ("%s\t%s",str1,str2);
printf ("\n");
for (i=0;i<3;i++){
printf ("%s",wordarray [i]); // Error here .
} // end FOR
return 0;
} // end MAIN
You need to validate each read with scanf (or whatever function you use for user input) to insure you have valid data to work with. You should also provide a width limitation for the read to insure you do not read beyond the end of your array. (e.g. scanf ("%11s", str1)). You should look into using fgets for user input and remove the '\n' included by fgets in your buffer. This will help you avoid a number of pitfalls with scanf that usually plague new users, especially when taking mixed string and numeric input.
Other than that, you should also look to avoid using magic numbers in your code (e.g. char str1[12]). If you need a constant 12, then define one or declare an enum to create it.
Putting those pieces together, you could do something like:
#include <stdio.h>
#define LEN 12
int main (void) {
char str1 [LEN] = "";
char str2 [LEN] = "";
char *wordarray[] = {str1, str2};
int i, nwords = sizeof wordarray/sizeof *wordarray;
printf ("Type your forname : ");
if (scanf ("%11s", str1) != 1) {
fprintf (stderr, "error: invalid input.\n");
return 1;
}
printf ("Type your last name : ");
if (scanf ("%11s", str2) != 1) {
fprintf (stderr, "error: invalid input.\n");
return 1;
}
printf ("\nYour name is : %s %s\n", str1, str2);
for (i = 0; i < nwords; i++){
printf ("%s", wordarray [i]);
}
putchar ('\n');
return 0;
}
Example Use/Output
$ ./bin/name
Type your forname : david
Type your last name : rankin
Your name is : david rankin
davidrankin
Look things over, and consider the other answers and let me know if you have further questions. Also take my comment regarding zero input or input beyond 12 characters into consideration. This will help build robustness into your input handling.
If you would like to approach the input using fgets, you can improve your input handling a bit with the following:
#include <stdio.h>
#include <string.h>
#define LEN 12
int main (void) {
char str1 [LEN] = "",
str2 [LEN] = "",
*wordarray[] = {str1, str2};
size_t i, len = 0, nwords = sizeof wordarray/sizeof *wordarray;
printf ("Type your forname : ");
if (!fgets (str1, LEN, stdin)) { /* read with fgets/validate */
fprintf (stderr, "error: invalid input.\n");
return 1;
}
len = strlen (str1); /* get length of str1 */
if (str1[len-1] == '\n') /* test for trailing '\n' */
str1[--len] = 0; /* overwrite with nulbyte */
printf ("Type your last name : ");
if (!fgets (str2, LEN, stdin)) {
fprintf (stderr, "error: invalid input.\n");
return 1;
}
len = strlen (str2);
if (str2[len-1] == '\n')
str2[--len] = 0;
printf ("\nYour name is : %s %s\n", str1, str2);
for (i = 0; i < nwords; i++){
printf ("%s", wordarray [i]);
}
putchar ('\n');
return 0;
}
You don't understand how array and pointer work. You should read this answer.
#include <stdio.h>
int main(void) {
printf("Type your forname : ");
char str1[12];
{ // we open a scope because ret don't need to be in function scope
int ret = scanf("%11s", str1); // scanf need to know how many bytes are
// available without count `\0` and you must send the array itself not the
// address
if (ret != 1) { // scanf don't set str1
fprintf(stderr, "Error in input\n"); // stderr is the error stream
return 1;
}
}
printf("\nType your last name : ");
char str2[12];
{
int ret = scanf("%11s", str2);
if (ret != 1) {
fprintf(stderr, "Error in input\n");
return 1;
}
}
printf("\n\nYour name is : ");
printf("%s\t%s", str1, str2);
printf("\n");
char *word[2] = {str1, str2}; // we need an array of pointer
for (size_t i = 0; i < sizeof word / sizeof *word; i++) { // size of array
printf("%s", word[i]);
}
return 0;
}
Shure I dont know how everything functions. That why I ask :) Thanks for the reply. I will investigate. With this information I will try to build a larger FOR-loop , so I can insert values in a 2D array. The user can add values to a 2d array then change the information text or numbers in the slots.
#include <stdio.h>
#define lenght 12 // corrected, define string format lenght
int main(){
char str1 [lenght]; // corrected, strings should have format lenght
char str2 [lenght]; // corrected, strings should have format lenght
char *wordarray [2]={str1,str2}; // corrected, add a * to wordarray[2]
int i;
printf ("Type your forname : ");
scanf ("%s",str1); // corrected, skip the & in ("%s",&str1);
printf ("Type your last name : ");
scanf ("%s",str2); // corrected, skip the & in ("%s",&str2);
printf ("\n\nYour name is : %s\t%s\n",str1,str2);
for (i=0;i<2;i++){ // corrected, i<2 must match the array elements
printf ("%s\t",wordarray [i]);
} // end FOR
return 0;
} // end MAIN
Ok. Had another go.
Havent worked much with strings. This program has both strings and numbers in arrays and printed in FOR loops. I also tried to get the indevidual elements in the arrays available to the user, so he could change the values.
I guess my style is pretty wretched. but ... its what I got.
Now concerning the GETS (str1), obtaining a string from the user. At the first use in the program it behaves normal. but the second time in the program I had to use GETS ("%s", str1) so it behaved proper. also an issue was to add specific numbers from a array detremined by the user. displayed in a for loop...
Another issue is to CLEAR the console screen after the JUMP . so the text doesnt flood the screen.
Comment : I agree David C. Rankin that validation of user data is important. Only tolerate character inputs on string requests, and numbers on integer request. Also return false input if "special characters" like slash or dots. I tried to read the origonal K&R C book and they talked about it, topics like turning all letters to small case or big case. but I had troubles getting the example code to run, maybe a C89 C11 compiler issue, I dont know.
#include <stdio.h>
//#include <string.h> // GCC32-C . mingw . compile
#define lenght 20 // Orbit_L75.Apartment_9
int main(){
int i,j,k,select,select2,*ptr;
char str1 [lenght];
char str2 [lenght];
char *wordarray [2]={str1,str2}; // character array must have a * asterix pointer .
int numarray [2];
printf ("Type your forname : ");
gets (str1); // gets (wordarray[0]) // alternative syntax
printf ("Type your last name : ");
gets (str2);
printf ("Enter your telephone number : ");
scanf ("%d",&numarray[0]); // assign a value to numarray slot 0
//scanf ("%d",(numarray+0)); // alternative syntax
printf ("Enter your age : ");
scanf ("%d",&numarray[1]); // assign a value to numarray slot 1
printf ("\n\n");
jump1 :
printf ("=========================\n");
for (i=1;i<5;i++)
{printf ("%d\t",i);}
printf ("\n");
for (j=0;j<2;j++)
{printf ("%s\t",wordarray[j]);}
//printf ("%s\t",*(wordarray+j));} // alternative syntax
printf ("\n");
for (k=0;k<2;k++)
{printf ("%d\t",numarray[k]);}
printf ("Sum = %d\n",(numarray[0]+numarray[1])); // add numarray slot 0 and slot 1.
//printf ("Sum = %d",*(numarray+0)+*(numarray+1)); // alternative syntax
printf ("=========================\n");
printf ("\n\nSelect\n1: Change Telephone \n2: Change Age \n3: Change First Name \n4: Change Last Name \n5: RAM location\n");
scanf ("%d",&select);
if (select == 1)
{printf ("New number : ");
scanf ("%d",&numarray[0]);
//scanf ("%d",(numarray+0)); // alternative syntax
printf ("\n");}
else if (select == 2)
{printf ("New age : ");
scanf ("%d",&numarray[1]);
printf ("\n");}
else if (select == 3)
{printf ("New First Name : ");
scanf ("%s",str1); //problems with the display using GETS on the second run.
printf ("\n");}
else if (select == 4)
{printf ("New Last Name : ");
scanf ("%s",str2);
printf ("\n");}
else if (select == 5)
{ // select2
{printf ("\nRAM location of : \n\t1. Telephone number\n\t2. Age\n\t3. First Name.\n\t4. Last Name\n");}
scanf ("%d",&select2);
if (select2 == 1)
{ptr = &numarray[0];
printf ("\nTelephone number\nValue in Decimal\t: %d\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}
else if (select2 == 2)
{ptr = &numarray[1];
printf ("\nAge\nValue in Decimal\t: %d\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}
else if (select2 == 3)
{ptr = &wordarray[0];
printf ("\nFirst Name\nValue in Text\t: %s\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}
else if (select2 == 4)
{ptr = &wordarray[1];
printf ("\nLast Name\nValue in Text\t: %s\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}
else if (select2 <1 || select2 > 4)
{printf ("\nValue is out of range, Try again .\n\n");}
} // end IF select2
else if (select <1 || select > 5)
{printf ("\nValue is out of range, Try again .\n\n");}
goto jump1;
return 0;
} // end MAIN
str1 and str2 are effectively pointers.
wordarray is an array of chars. It should be an array of pointers to char.
Also in your scanf you're passing address of str1 and str2, but you should just pass str1 and str2.

Using a user-inputted string from one function to another in C

So... the main question is how I can use the string that the user entered in another function? I know it would be a lot easier to do it all in the main function but we are forced to use as many separate ones as possible. Thanks in advance.
Following on from the comment, you most likely want to declare the str in a scope available to both functions:
int enterWord (char *str) {
...
scanf("%24s", str);
...
return str[0];
}
int menuScan (char *str) {
...
}
int main (void) {
char str[25] = {0};
int someint;
...
someint = menuScan (enterWord (str));
return 0;
}
or
int main (void) {
char str[25] = {0};
int someint, someotherint;
...
someint = enterWord (str);
...
someotherint = menuScan (str);
return 0;
}
You may want to employ a bit of additional error checking on the user input as well, e.g.:
int enterWord (char *str) {
printf ("Please enter a single word that is no more than 25 characters: ");
if (scanf ("%24s", str))
printf ("\nThanks! You entered: %s", str);
else
return -1;
return str[0];
}
...
int main (void) {
char str[25] = {0};
int someint, someotherint;
...
if ((someint = enterWord (str)) = -1) {
fprintf (stderr, "enterWord() error: input failure.\n");
return 1;
}
...
someotherint = menuScan (str);
return 0;
}
Remaining Issue With '\n' Left In Input Buffer
Your remaining problems come from the fact that after you call scanf, you are leaving the '\n' (cause by pressing [Enter]) in the input buffer stdin. The next time your program calls scanf it takes the '\n' left in the input buffer as the user input. (if you check, you will find it is using the value 0xa (or 10) which is the value for newline)
You have two options. You can use a loop to empty stdin:
int c;
while ((c = getchar()) != '\n' && c != EOF) {}
You can also use the assignment suppression operator of scanf to read and discard the newline, e.g.:
scanf ("%24[^\n]%*c", str)
Where %24[^\n] read upto 24 chars (not including the '\n' into str) and %*c which reads and discards a single character (the newline). That way your input buffer is empty before the next user input.
Here is a short working example:
#include <stdio.h>
int enterWord (char *str);
void menuOptions ();
int menuScan (char *str);
int main (void) {
char str[25] = {0};
if (enterWord (str) == -1) {
fprintf (stderr, "enterWord() error: input failure.\n");
return 1;
}
do {
menuOptions();
} while (!menuScan (str));
return 0;
}
int enterWord (char *str)
{
printf ("Please enter a single word that is no more than 25 characters: ");
if (scanf ("%24[^\n]%*c", str))
printf ("\nThanks! You entered: %s", str);
else
return -1;
return str[0];
}
void menuOptions ()
{
printf("\n\n========= MENU =========\n\n");
printf("Key Function\n");
printf("=== ========\n");
printf(" C Count the letters\n");
printf(" V Count the vowels\n");
printf(" R Reverse the word\n");
printf(" P Check if the word is a palindrome\n");
printf(" W Enter a new word\n");
printf(" Z Exit\n\n");
}
int menuScan (char *str)
{
/* always initialize variables */
char *p = str;
char menuChoice = 0;
int c = 0;
int charcnt = 0;
printf ("Please enter a character from the options above: ");
if (!scanf ("%c%*c", &menuChoice)) {
fprintf (stderr, "menuScan() error: input failure.\n");
return -1;
}
printf ("\nYou entered: %c\n", menuChoice);
c = menuChoice; /* I don't like to type */
/* validate input */
if (c < 'A' || ('Z' < c && c < 'a') || 'z' < c) {
fprintf (stderr, "menuChoice() error: input is not [a-z] or [A-Z]\n");
return -1;
}
/* convert to lowercase */
if ('A' <= c && c <= 'Z') c += 32;
switch (c) {
case 'c':
for (; *p; p++) charcnt++;
printf ("\n\nThere are '%d' letters in '%s'\n", charcnt, str);
break;
case 'z':
return -1;
default : printf ("(%c) invalid choice -> try again.\n", c);
}
return 0;
}
Compile
gcc -Wall -Wextra -finline-functions -O3 -o bin/menuscan menuscan.c
Example/Use
$ ./bin/menuscan
Please enter a single word that is no more than 25 characters: 0123456789
Thanks! You entered: 0123456789
========= MENU =========
Key Function
=== ========
C Count the letters
V Count the vowels
R Reverse the word
P Check if the word is a palindrome
W Enter a new word
Z Exit
Please enter a character from the options above: c
You entered: c
There are '10' letters in '0123456789'
========= MENU =========
Key Function
=== ========
C Count the letters
V Count the vowels
R Reverse the word
P Check if the word is a palindrome
W Enter a new word
Z Exit
Please enter a character from the options above: z
You entered: z
There are a lot of problems with your code, but I will address only the actual question you posed.
When you have a function which creates a result value to be used somewhere else, you need to return that value when the function ends. The 'return' keyword will do this, but you must bear in mind that the thing being returned must continue to exist after the function has ended (as noted by #David C. Rankin in the comments).
Locally declared variables will cease to exist when the function ends, so the solution is to declare them in a wider scope.
// declare the string in a wider scope
// provide one extra character space for the string terminator \0 character
char inputStr[25 + 1];
// pass the string to the function which will fill it with the entered string
// NOTE: to avoid risk of someone entering too many letters in the string, we
// also pass in the length of the string buffer
enterWord(inputStr, 25);
The changes to the enterWord function would be:
void enterWord(char* str, int length){
printf("Please enter a single word that is no more than %d characters: ", length);
// this should verify the length of the entered text to make sure it isn't too long... but that's not your question
scanf("%s", str);
printf("\nThanks! You entered: %s", str);
}
In the scope where you declared inputStr, the string will now contain the data entered by the user.
In this case we are returning the string from the function by a different mechanism than the 'return' keyword. Here we are passing a pointer to the first letter of the buffer space, so that the function will fill the original inputStr buffer from inside the function.
If you must use a more 'functional' coding paradigm, you might want to consider allocating space for the buffer on the heap using 'malloc', you would then need to remember to use 'free' at a later point in the code to release that allocated memory and avoid a memory leak, which is why that would not be my preferred solution in this case.

Trouble with strchr in C

I can't work out why Strchr() is not working in my function. I need to see if the users guess matches any of the letters in a hidden word. It is a Hangman game.
int guessLetter(char* word, int* guessedLetters)
{
char guess[20];
char *s;
printf("Enter your guess: ");
scanf("%s", &guess);
s = strchr (word, guess);
printf("%s", s);
if (s != NULL) {
printf ("Good Guess\n");
} else {
printf ("Bad Guess\n");
}
}
No matter if the guess is right or wrong, my else statement is being activated. My printf shows that s is being given the value of Null no matter if the character is in the word or not.
So I guess my problem is with this part of the code:
s = strchr (word, guess);
I am new to C, so I am sure I am just missing something very basic. I have tried to search the web as much as I can, but I don't really seem to be able to understand what I am doing wrong.
strchr takes an int as 2nd argument but you are passing a char*. You Turn on your compiler warnings.
What you wanted is to loop over the word to see if any of the characters are in guess.
s = 0;
for(size_t i=0; word[i]; i++) {
s = strchr (guess, word[i]);
if(s) break; //Found a match
}
This would break on the first match and you can modify it if you want to check for all characters in word.
There's an argument mismatch in scanf call too:
scanf("%s", &guess);
should be
scanf("%s", guess);
scanf expects a char* for format string %s but you are passing char(*)[20] i.e. &guess is of type char (*)[20].

C application skips my scanf calls

I'm trying to write code to count how many times a string repeats inside another one. (If there is some easier approach, please let me know.)
Here is the code that I have now:
int getStringLenght (char str[]) {
int lenghtOfTheString;
int i;
for (i = 0; i < 100; i++) {
if(str[i] == '\0') {
lenghtOfTheString = i;
break;
}
}
return lenghtOfTheString;
}
int main()
{
printf("Type a string: ");
char T[1024];
scanf("%s",&T);
char P[100];
printf("Type a substring: ");
scanf("%s",&P);
printf("%s",P);
int stringSize = getStringLenght (P);
int occurences = 0;
int i;
for (i = 0; i < 10; i++) {
int j;
if(T[i] == P[0]) {
for (j = 0;j<10;j++) {
char c1 = T[i+j];
char c2 = P[j];
if(c1 != c2) {
break;
}
if(j == stringSize-1) {
occurences++;
//printf("string iguais em i = %d",i);
}
}
}
}
printf("\nThe substring %s was found %d times", P, occurences);
return 0;
}
The app compiles. When I type "banana", for example, on the first scanf, and then "na" on the second, the app comes out with the right answer. But, if I type "banana and milk" on the first scanf, it automatically interprets the second scanf as "and", even when I don't type anything but "banana and milk ENTER"
What's happening?
scanf's "%s" conversion only reads characters until it encounters white-space (e.g., space, new-line, or tab). When you enter more than one word, it reads the first. The second call reads the second, and so on.
If you want to read an entire line, you usually want to use fgets instead (scanf can do the job as well, but it's a little trickier, and uses a feature of which many are unaware, so they often find it difficult to understand).
You don't understand how scanf works. http://www.cplusplus.com/reference/clibrary/cstdio/scanf/ %s will only read one string, terminated by white space. If you want to keep reading strings, or read a line, you have to keep using scanf until one of your strings ends in a new line or EOF, or use another function, like fgets.
You have to remember that many functions are already implemented. This is why your getStringLength (you have typo in it's name) is needless. You can simply check the string's length using strlen function from string.h. What is more when you import this file you also have access to strstr function which finds the first occurrence of a given substring in a string. Try to use them instead of reinventing the wheel ;)
That is a standart problem with scanf. There are 3 ways to fix this:
1: Call fflush after each scanf:
scanf("%s", some_string); // you don't need to write &some_string because giving a array to a function automatically converts it to a pointer
fflush(stdin);
fflush() isn't available on every system.
2: Putting scanf in a loop:
do
scanf("%s", somestring);
while (getchar() != '\n');
3: Don't use scanf! Use fgets and sscanf!
char buffer[100]; // buffer for fgets()
fgets(buffer, 100, stdin); // read a line from stdin (standart input) into buffer
sscanf(buffer, "%s", some_string); // convert buffer in any format you want

Program terminating abnormally if input is very large

#include<stdio.h>
#include<stdlib.h>
#define n ((sizeof(char)) * 100 )
int stringlength(char * str)
{
int count=0;
while(*str)
{
if(*str == '\n')
{
*str=0;
}
else
count++, str++;
}
return count;
}
int palin1(char *str, int k)
{
char * pend = str + k - 1;
if(*pend != *str)
return 0;
else
palin1(str+1, k-1);
return 1;
}
int palin(char *str)
{
int length = stringlength(str), f=0;
char *pend = str + length - 1;
while(str <= pend)
{
if(*str == *pend) f=1;
else
return (f = 0);
str++, pend--;
}
return 1;
}
main()
{
char * ps = (char *)malloc(n);
int flag;
if(ps == NULL) printf("Malloc Fail\n");
else
{
printf("Malloc Succeeded, you have memory of %d bytes\n", n);
printf("This program checks if String is Palindrome or not\n\
\nEnter your String: ");
fgets(ps, 100, stdin);
printf("You entered: %s of length %d", ps, stringlength(ps));
int i = 0;
printf("\n\nEnter:\n1.Using iteration\n2.Using Recursion ");
scanf("%d", &i);
switch(i)
{
case 1:
flag=palin(ps);
break;
case 2:
flag=palin1(ps,stringlength(ps));
break;
default:
printf("Invalid input");
}
if(flag) printf("\nYou entered a Palindrome");
else printf("\nNot a Palindrome");
}
free (ps);
return 0;
}
Why does the above program http://www.ideone.com/qpGxi does not give any output on putting the input:
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
I know fgets(ps,100,stdin) will take only 100 characters and not more than that, but why does the program halt execution?
You should check for fgets failure, as recommended by the fgets spec.
if ( fgets(ps,100,stdin) == NULL ) {
printf("Input failed.");
//check for 'feof' or 'ferror' here
return -1;
}
printf("You entered: %s of length %d",ps,stringlength(ps));
I don't see why fgets would be failing, but you would get an uninitialized character buffer back, which would crash printf.
EDIT: You should really pay attention to your compiler warnings, too.
prog.c:49: warning: return type defaults to ‘int’
prog.c: In function ‘main’:
prog.c:59: warning: ignoring return value of ‘fgets’, declared with attribute warn_unused_result
prog.c:63: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
prog.c: In function ‘palin’:
prog.c:46: warning: control reaches end of non-void function
prog.c: In function ‘main’:
prog.c:52: warning: ‘flag’ may be used uninitialized in this function
You can see that even your compiler recommends checking fgets for null. Also, flag should be set to 0 in the default case, otherwise you will get undefined behavior if the user enters something other than 1 or 2.
EDIT 2: Oh for Christ's sake! your program works fine! You forgot to check "run program" in Ideone!!!
http://www.ideone.com/7ecZd
You cannot break a string literal just like that
printf("%s\n", "string literal **WRONGLY**\n
broken right after the line break.");
What you can do is use the preprocessor feature of joining successive string literals to make just one
printf("%s\n", "string literal **CORRECTLY**\n"
"broken because the preprocessor joins these 2 parts.");
It's terminating because there are characters left in the input stream if the input is too large. For example, if you wish to take only 5 characters using fgets but have given the input as -
StackOverflow
Overflow are left in the input stream. They need to be removed from the stream for further input operations to succeed. So, remove those extra characters from the stream using -
fgets(ps,100,stdin);
while (getchar() != '\n');
Since the input stream is struck with offending characters, the scanf statement that actually takes the user input is not working and jumping to subsequent operations.
Also initialize the flag variable to 0 other wise it has garbage values.

Resources