Practice.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ARR 32
int main(void){
int MEM=64;
char arr[ARR],*p=(char *)calloc(MEM,(sizeof(char))),*q=NULL;
int i=0,j=1;
printf("\nEnter String : ");
while(j){
scanf(" %[^\n]s " ,arr);
if(j==1)
strcpy(p,arr);
else
strcat(p,arr);
if((j*ARR)==MEM){
MEM=MEM+(j*ARR);
q=realloc(p, MEM);
if(!(q)){
printf("\nNOT ENOUGH MEMORY\n");
goto END;
}
p=q;
}
for(i=0;i<(strlen(arr));++i){
if(arr[i]=='\n')
break;
}
if(arr[i]=='\n')
break;
++j;
}
printf("\n %s\n",p);
END: free(p);p=NULL;q=NULL;
return 0;
}
I am trying to get multiple string inputs.
I am using scanf(" %[^\n]s",arr); to take the input instead of fgets(arr,ARR,stdin);, because with fgets the program execution stops as soon as I hit ENTER key. But with scanf(" %[^\n]s",arr); the program is unable to get out of the while() loop even after entering \n.
I would like to know the mistake or mistakes I have made while writing the code.
The canonical way of reading multiple lines of input in C is to use fgets in a loop, like
while (fgets(arr, sizeof(arr), stdin) != NULL)
{
if (arr_contains_special_input_to_exit_loop(arr))
break;
// Optionally check for and remove trailing newline from input
// Append `arr` to your data
}
The condition to exit the loop might be some special input or an empty line or something else completely.
One mistake is:
for(i=0;i<(strlen(arr));++i){
if(arr[i]=='\n')
break;
}
Looking earlier in you code you have:
scanf(" %[^\n]s " ,arr);
The [^\n] prevents any newlines \n from being contained in arr. So your loop that looks for (arr[i]=='\n') will never find any. Your next bit of code continues looking for non-existent newlines:
if(arr[i]=='\n')
break;
This last break also breaks out of your outer loop preventing you from asking for further input on finding a newline (which it shouldn't). Fix these issues and it should get much further allowing you to enter multiple items.
Edit:
With a bit of effort looking at what you were doing, I now have it taking multiple input and reallocating as necessary. The strings are all concatenated and printed at the end. It could still stand a bit of work, but this should give you a few hints:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ARR 32
int main (void) {
int MEM = 64;
char arr[ARR], *p = (char *) calloc (MEM, (sizeof (char))), *q = NULL;
int i = 0, j = 1;
while (j) {
printf ("\nEnter String : ");
scanf (" %[^\n]s ", arr);
printf (" you entered (arr): %s\n", arr);
if (strcmp (arr, "q") == 0) {
printf ("\n 'q' entered, exiting.\n\n"); // provide for exit if `q` entered
break;
}
if (j == 1)
strcpy (p, arr);
else
strcat (p, arr);
if ((j * ARR) == MEM) {
MEM = MEM + (j * ARR);
q = realloc (p, MEM);
if (!q) {
printf ("\nNOT ENOUGH MEMORY\n");
goto END;
}
else
printf ("\nMemory Reallocation - succeeded.\n");
p = q;
}
++j;
}
printf (" %s\n", p);
END:
if (p) free (p); /* always test pointer before calling free */
p = NULL;
q = NULL;
return 0;
}
output:
./bin/me
Enter String : fishinsea
you entered (arr): fishinsea
Enter String : alligators
you entered (arr): alligators
Memory Reallocation - succeeded.
Enter String : really_big_mosters
you entered (arr): really_big_mosters
Enter String : SuperSnake_Prudhome
you entered (arr): SuperSnake_Prudhome
Memory Reallocation - succeeded.
Enter String : 8_puppies
you entered (arr): 8_puppies
Enter String : q
you entered (arr): q
'q' entered, exiting.
fishinseaalligatorsreally_big_mostersSuperSnake_Prudhome8_puppies
Related
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.
This is to perform function of a phone book getting names and their phone number. For requested names it must print their phone number. The last out line prints infinitely for I cannot detect the end of input. I have used \n, ' ' and, " ", but nothing works. HELP!
#include <stdio.h>
struct ph_book{
char name[100000];
double ph;
}p[20];
int main() {
char temp[100000],ex[100000];
int n,i,flag=0;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%s",p[i].name) ;
scanf("%lf",&p[i].ph);
}
scanf("%s",temp);
while(temp[0]!='\n'){
flag=0;
for(i=0;i<n;i++){
if(strcmp(temp,p[i].name)==0){
printf("%s=%.lf\n",p[i].name,p[i].ph);
flag=1;
break;
}
}
if (flag==0){
printf("Not found\n");
}
strcpy(ex,temp);
scanf("%s",temp);
if (strcmp (temp, "\n") == 0)
break;
}
return 0;
}/* Enter your code here. Read input from STDIN. Print output to STDOUT */
The "\n" is not part of the input string of scanf function.
The following code will not enter the break (conditions is always be FALSE).
if (strcmp (temp, "\n") == 0)
break;
If you wish to terminate input by empty string (when user press enter),
The following should work:
Replace scanf with gets (or better use the safe version: gets_s).
Compare temp[0] to zero, for detecting end of input sequence.
Sample code:
gets_s(temp, sizeof(temp)); //Instead of scanf("%s",temp);
while (temp[0] != 0)
{
strcpy(ex, temp);
gets_s(temp, sizeof(temp)); //Instead of scanf("%s",temp);
if (temp[0] == 0)
break;
}
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.
I'm looking for a way to write an input loop that continues to print prompts until the user enters a blank line.
This is what I want to do:
Loop starts, prints prompt > to the command line. User enters a line that ends with '\n', my program does whatever with that line, and then prints > again. This continues until the user enters a blank line (\n), at this point the loop terminates.
Would something along these lines answer your needs?
int ret;
// Basically, in order, 1 to indicate the file descriptor of the standard output
// ">" as the string you want to print
// 1 as the number of characters you want printed.
write(1, ">", 1);
while ((ret = read(0, buff, SizeBuff)) > 0) {
buff[ret] = 0;
if (buff[0] == '\n' && strlen(buff) == 1)
return (0);
/*Do your stuff*/
write(1, ">", 1);
}
A very simple scanf version can also be used:
#include <stdio.h>
#define MAXL 64
int main (void) {
char str[MAXL] = {0};
printf ("\n Enter a string ([enter] alone to quit)\n");
while (printf (" > ") && scanf ("%63[^\n]%*c", str) == 1)
{
/* do whatever in your code */
printf (" result: %s\n", str);
}
return 0;
}
Use/Output
$ ./bin/scanf_enter_quits
Enter a string ([enter] alone to quit)
> string
result: string
> another
result: another
>
Note: MAXL-1 added as maximum width specifier for scanf to prevent write beyond end of array.
getline Example
getline by dynamically allocating the line buffer allows you to accept a line as long as you want to give it. It can be billions of characters (up to the extent of your memory). This is a strength and a weakness. If you need to limit the amount of data you accept, it is up to you to check/validate/etc....
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *str = NULL;
size_t n = 0;
ssize_t nchr = 0;
printf ("\n Enter a string ([enter] alone to quit)\n");
while (printf (" > ") && (nchr = getline (&str, &n, stdin)) > 1)
{
str[--nchr] = 0; /* strip newline from input */
printf (" (str: %s)\n", str); /* do whatever in your code */
}
if (str) free (str);
return 0;
}
Use/Output
$ ./bin/getline_enter_quits
Enter a string ([enter] alone to quit)
> string one as long as you want
(str: string one as long as you want)
> string 2 make it 1000 chars.........................................
(str: string 2 make it 1000 chars.........................................)
>
scanf Dynamic Allocation
You can also have scanf dynamically allocate the space for you by using the m conversion specifier (older versions of scanf use the a conversion specifier for this purpose). You must also provide a pointer-to-pointer to accept the address in this case. (e.g. scanf ("%m[^\n]%*c", &str) ).
#include
#include
int main (void) {
char *str = NULL;
printf ("\n Enter a string ([enter] alone to quit)\n");
while (printf (" > ") && scanf ("%m[^\n]%*c", &str) == 1)
{
printf (" (str: %s)\n", str); /* do whatever in your code */
if (str) free (str); /* you must free each loop */
str = NULL;
}
if (str) free (str);
return 0;
}
Use/Output
$ ./bin/scanf_dyn_enter_quits
Enter a string ([enter] alone to quit)
> some string as long as you want
(str: some string as long as you want)
> another string any length .......... ............. .............
(str: another string any length .......... ............. .............)
>
#include <stdio.h>
#define SIZE 5
void func(int*);
int main(void)
{
int i, arr[SIZE];
for(i=0; i<SIZE; i++)
{
printf("Enter the element arr[%d]: ", i);
scanf("%d", &arr[i]);
}//End of for loop
func(arr);
printf("The modified array is : ");
for(i=0; i<SIZE; i++)
printf("%d ", arr[i]);
return 0;
}
void func(int a[])
{
int i;
for(i=0; i<SIZE; i++)
a[i] = a[i]*a[i];
}
Output :::
While I'm entering integer elements the output is OK.But as I entered a float value like 1.5, it didn't ask for other elements and the O/P is as shown in the figure.I think it should implicitly typecast 1.5 to 1 but it didn't happen..can u plz tell why this happened ? All the info about the compiler is shown in the figure.
When you scanf("%d") a value like 1.5 the scanning will stop at the decimal point and return 1.
The next time you call scanf, the pointer will still point to the decimal point and your scan will return immediately because there are no digits there to scan.
You should be checking the return value from scanf - it gives you the number of items successfully scanned which will be 1 initially for the 1 before the decimal point, and 0 from then on.
As an aside, scanf stands for "scan formatted" and I'll guarantee you won't find anything more unformatted than user input.
Investigate looking into fgets for line input. Here's a copy of a function I often use for such purposes:
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
// Test program for getLine().
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
Once you get a line in with that function, you can sscanf it to your heart's content, handling errors much easier.
What's happening is that scanf stops reading an integer when it sees the '.' character, and leaves it in the input buffer. Then subsequent calls to scanf fail because the next character is '.' and not something parseable as an integer.
How do you fix this? The first step is to forget you ever heard of scanf and always use fgets to read whole lines of input, then process them after you read them into a string buffer. You can use sscanf for this purpose, but a robust function like strtol would be a lot better.
Problem with buffer - I think the remaining part (.5) remains on the buffer.
use flushall(); after your scanf("%d..