Why my program doesn't allow me to input b? - c

I want to input valors for a and b, being a an int and b a str. When I run my program I can input a valor, but then it ingnores printf() and gets() for b.
#include<stdio.h>>
int main()
{
int a;
char b[5];
printf("Write a:\n");
scanf("%i", &a);
printf("Write b:\n");
gets(b);
printf("a = %i, b = %s", a, b);
return 0;
}
In the end, it just prints:
a = (valor written), b =
I don't know what's wrong with this, neither if it's a different way to get this working. I'm pretty new with C. Thank you in advance. ;)

The function gets is unsafe and is not supported by the C Standard. Instead use either scanf or fgets.
As for your problem then after this call of scanf
scanf("%i", &a);
the input buffer contains the new line character '\n' that corresponds to the pressed key Enter. And the following call of gets reads an empty string by encountering the new line character.
Instead of using gets write
scanf( " %4[^\n]", b );
Pay attention to the leading space in the format string. It allows to skip white space characters as for example the new line character '\n'. And the call of scanf can read a string with maximum length equal to 4. If you want to read a larger string then enlarge the array b and the field width specifier in the format string.

Related

Output didn't include all of the characters

I was trying to input a string of characters and only output the last and the first character respectively. Below is the code I'm using.
#include<stdio.h>
int main(){
for(int i=0;i<3;i++){
int n; // length of the string
char string[101];
scanf("%d %s", &n, &string);
fflush(stdin); // sometimes I also use getchar();
printf("%c%c", string[n+1], string[0]);
}
printf("\n");
return 0;
}
I'm using for loop because i wanted to input the string 3 times, but when I ran the code the input isn't what I expected. If I input e.g.
5 abcde
output
a //there's space before the a
can you help me tell where I've gone wrong?
input:
5 abcde
6 qwerty
3 ijk
excpeted output:
ea
yq
ki
Few problems in your code:
In this statement
scanf("%d %s", &n, &string);
you don't need to give & operator with string. An array name, when used in an expression, converts to pointer to first element (there are few exceptions to this rule). Also, the size of string array is 101 characters but if you provide input more than 101 characters, the scanf() end up accessing string array beyond its size. You should restrict the scanf() to not to read more than 100 characters in string array when input size is more than that. (keep the remain one character space is for null terminating character that scanf() adds). For this, you can provide width modifier in the format specifier - %100s.
You are not validating the string length input against the input string from user. What happen, if the input string length is greater than or less than the actual length of input string!
fflush(stdin) is undefined behaviour because, as per standard, fflush can only be used with output streams.
I was trying to input a string of characters and only output the last and the first character respectively.
For this, you don't need to take the length of the string as input from user. Use standard library function - strlen(). This will also prevent your program from the problems that can occur due to erroneous length input from user, if that is not validated properly.
Putting these altogether, you can do:
#include <stdio.h>
#include <string.h>
int main (void) {
for (int i = 0; i < 3 ; i++) {
char string[101];
printf ("Enter string:\n");
scanf("%100s", string);
printf("Last character: %c, First character: %c\n", string[strlen(string) - 1], string[0]);
int c;
/*discard the extra characters, if any*/
/*For e.g. if user input is very long this will discard the input beyond 100 characters */
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
}
return 0;
}
Note that, scanf(%<width>s, ......) reads up to width or until the first whitespace character, whichever appears first. If you want to include the spaces in input, you can use the appropriate conversion specifier in scanf() or a better alternative is to use fgets() for input from user.
Line 11: string[n+1] -> string[n-1]

What is the specific reason for the runtime error I'm getting here?

#include<stdio.h>
#include<string.h>
void main()
{
char a,b,c;
printf("Enter alien names:\n");
scanf("%s\n%s\n%s\n",a,b,c);
printf("The alien names are %s, %s and %s. A meteor hit %s's spaceship. A star scratched %s\'s spaceship. But %s fixed %s and %s\'s spaceships. The three became friends and are from the planet BYG (which means BLUE YELLOW GREEN)",a,b,c,a,b,c,a,b);
}
What is the specific reason for the runtime error I'm getting here?
To solve this issue you should simply consider to use strings (arrays of chars) to contain the different names.
Here is an example how to do that:
void main()
{
// The string "a" can contain up to 100 symbols (chars).
char a[100];
printf("Enter an alien name:\n");
scanf("%s",a);
printf("The alien name is %s.", a);
}
The difference between "char a" and "char a[100]" is that in the first case the variable "a" corresponds to a single character and in the second it corresponds to a string - an array of chars which can contain up to 100 characters.
The posted code has undefined behavior, because the variables a, b, and c are of type char, while the %s conversion specifier in the call to scanf() is expecting a pointer to the first element of a character array that can hold the input string. Mismatched conversion specifers and arguments in a scanf() call lead to undefined behavior, and attempting to write too many characters into the receiving array causes undefined behavior.
The first problem can be fixed by declaring a, b, and c as arrays large enough to hold expected input:
char a[100], b[100], c[100];
...
scanf("%s\n%s\n%s\n", a, b, c);
Note that arrays decay to pointers to their first elements in most expressions, including function calls, so here a is a pointer to the first element of the character array a[]; this is equivalent to &a[0].
There is still a possibility for undefined behavior if the user enters too many characters. To avoid this, always specify a maximum width when using scanf() to read user input into a string. Note here that the specified width is the maximum number of characters that will be read for that input item, not including the null terminator, \0, which will be automatically added by scanf(), so the maximum width must be at least one less than the size of the receiving array:
scanf("%99s\n%99s\n%99s\n", a, b, c);
But if you compile and run this code, you will find that it does not behave as expected. After the third name is entered, the program will continue waiting for more input. This is because the \n character is a whitespace character, and when scanf() encounters a whitespace character in a format string, it reads and discards zero or more whitespace characters in the input until a nonwhitespace character is encountered, or until no more characters can be read. The %s directive tells scanf() to read characters until a whitespace character is encountered. So when the user presses Enter after the final name, scanf() completes matching input characters for the final name and returns the \n character to the input stream; then the \n is reached in the above format string, and scanf() matches the aforementioned \n character in the input stream, and any further whitespace characters that are encountered. This will end if the user enters another nonwhitespace character, or signals end-of-file from the keyboard (e.g., with Ctrl-D or Ctrl-Z).
To avoid this complication, remember that it is almost never correct to end a scanf() format string with a whitespace character. Also, there is no need to use \n rather than a space character, since both are simply interpreted as whitespace directives by scanf():
scanf("%99s %99s %99s", a, b, c);
It would further improve the posted code if the return value from the call to scanf() were checked before attempting to use the input. Since scanf() returns the number of successful assignments made, this value should be 3:
#include <stdio.h>
#include <string.h>
int main(void)
{
char a[100], b[100], c[100];
printf("Enter alien names:\n");
int ret_val = scanf("%99s %99s %99s", a, b, c);
if (ret_val == 3) {
printf("The alien names are %s, %s and %s. A meteor hit %s's "
"spaceship. A star scratched %s\'s spaceship. But %s "
"fixed %s and %s\'s spaceships. The three became friends "
"and are from the planet BYG (which means BLUE YELLOW GREEN)\n",
a, b, c, a, b, c, a, b);
} else {
puts("Input error");
}
}
What is the specific reason for the runtime error I'm getting here?
The function scanf using the format specifier %s expects to be passed the address of a char array, in which to place the input data. For example an array such as
char a[100];
However, you pass simple char variables a and b and c which can hold values in the range -128 to 127, or 0 to 255, depending on whether the implementation's char is signed or unsigned.
These variables were not even initialised, so indeterminate values were passed to scanf. But even if they had been initialised, it is very likely that the values passed will cause a segfault, when used as addresses.
My compiler issued 2 warnings for each of a, b and c passed to scanf.
warning C4477: 'scanf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'int'
warning C4700: uninitialized local variable 'a' used
Please enable and act on all compiler warnings.
//There are things that shoudn't be there. Im not a pro but this is what I think.
#include<stdio.h>
#include<string.h>//you have include this library but you didn't use a function from it.
//I think what you want to do is use the str functions like strcpy
//but in this case you don't need to use it.
void main()
{
char a[25],b[25],c[25];//Here you declared a character a, b and c. But if you want to store a string, you have to declare an array of characters. So instead of a, b, c, it's a[someValue], b[someValue] and c[someValue].
//Declare an array with a size that you think will cover the whole "alien name". e.g. a[25]..
//but i don't know, maybe you did it on purpose. Maybe you just want to name the aliens with one character like A, B, C. But if you want to name the aliens with a long name, you must declare an array.
printf("Enter alien names:\n");
scanf("%s\n%s\n%s\n",a,b,c);//You don't need to put the "\n" between those "%s". "\n" means "newline". It will work without it because scanf automatically reads next set of characters when it meets white space of newline.
//--so you can remove "\n" in there and replace it with space. But you can leave it there also but you really have to remove the last "\n" because scanf will search again for the next
//--new line before it will end asking for input and pressing enter will not work because you have to type another set of characters before scanf will read the last "\n" that you put at scanF.
//Another mistake here is the format specifier that you used (%s). It doesn't match declaration because you declare char a, b, c, that will only store one character each.
//In case that you're really just storing one character each alien's name, you have to use the "%c" instead of "%s" and you must pass the reference of the char variable in
//--scanf, e.g. scanf("%c %c %c", &a, &b, &c);
//Just remember that if you plan on storing a string or a long name there, you must declare an array like I said at the beginning.
//--and if it's an array, you don't need to include the '&' on every variable when you're passing it in scanF.
//There's nothing wrong here if you're alien's names are string.
printf("The alien names are %s, %s and %s. A meteor hit %s's spaceship. A star scratched %s\'s spaceship. But %s fixed %s and %s\'s spaceships. The three became friends and are from the planet BYG (which means BLUE YELLOW GREEN)",a,b,c,a,b,c,a,b);
}
The specific reason for the runtime error is this line:
scanf("%s\n%s\n%s\n",a,b,c);
The %s conversion specifier tells scanf to read a sequence of non-whitespace characters from the input stream (skipping over leading whitespace) and store that sequence to an array of char pointed to by the corresponding argument. The problem is that a, b, and c are not pointers to char; they're single char objects that haven't been initialized. The odds of any of them containing a value that corresponds to an address that scanf can write to is almost non-existant.
First, change the declarations of a, b, and c tochar a[SOME_LENGTH] = {0}; // initialize array contents to 01
char b[SOME_LENGTH] = {0};
char c[SOME_LENGTH] = {0};
where SOME_LENGTH is a number that's long enough to contain the longest string you expect to enter plus one extra space for the string terminator. IOW, if the longest string you intend to read is 10 characters long, then your declarations need to be
char a[11] = {0};
char b[11] = {0};
char c[11] = {0};
Secondly, change your scanf call to
scanf( "%(SOME_LENGTH-1)s %(SOME_LENGTH-1)s %(SOME_LENGTH-1)s", a, b, c );
where (SOME_LENGTH-1) is the length of your buffer minus 1. Again, assuming SOME_LENGTH is 11:
scanf( "%10s %10s %10s", a, b, c );
This will help prevent a buffer overrun in the event you enter a string longer than what the buffer is sized to hold.
Both the %s conversion specifier and a blank space in the format string tell scanf to consume and discard any leading whitespace. You can run into trouble specifying whitespace characters in the format string.
Additional notes:
main returns int, not void - change your main to
int main (void)
{
...
}
If there are fewer elements in the initializer than there are in the array, then excess elements are initialized to 0. So in this case, the first element is *explicitly* initialized to 0, and the remaining elements are *implicitly* initialized to 0.

read the data and skip parenthese with scanf

I write a C program to pick the data from the the std input, which starts with a number indicating the number of the data sets, then there are N pairs of data, in the form: (x y), so I write the code as below:
#include <stdio.h>
int main()
{
int n_sets;
scanf("%d", &n_sets);
int i;
for(i = 0; i < n_sets; ++i)
{
int m, n;
scanf("(%d %d)", &m, &n);
printf("%d\t%d\n", m, n);
}
return 0;
}
but it doesn't work. After I input the number of the data set, the program print the uninitialized m&n directly. But when I add a space before the (%d %d), it works fine. Somebody can explain this?
When you have character literals in your argument to scanf(), it expects to find those literals exactly as specified in the format string.
scanf("%d", &n_sets);
correctly reads n_sets, and stops at the newline or other whitespace character in the buffer. The next scanf() :
scanf("(%d %d)", &m, &n);
expects to find an open parenthesis at the beginning of the input, but finds a whitespace character instead. So it fails, and scanf() returns without having read anything. Consequently, your m and n remain uninitialized, and garbage results.
When you put in the space before the open parenthesis like so:
scanf(" (%d %d)", &m, &n);
it tells scanf() to skip any leading whitespace before the parenthesis in the input buffer, so the program works correctly.
change
scanf("%d", &n_sets);
to
scanf("%d\n", &n_sets);
and input your n_sets ending up with a [enter], it works.
Assuming your input is like this:
2 (1 2) (3 4)
There is a space(or new line?) after the first number, so change the scanf in the loop to:
scanf("\n(%d %d)", &m, &n);
// ^^
It sounds like the input into the program has some amount of whitespace before the value you want scanf to parse. The space in the string tells scanf to ignore whitespace. Without it, scanf is looking for an exact match immediately.

Getting Debug Error in C

i am a learner of 'C' and written a code, but after i compile it, shows a Debug Error message, here is the code:
#include<stdio.h>
void main()
{
int n,i=1;
char c;
printf("Enter Charecter:\t");
scanf("%s",&c);
printf("Repeat Time\t");
scanf("%d",&n);
n=n;
while (i <= n)
{
printf("%c",c);
i++;
}
}
Pls tell me why this happens and how to solve it
The scanf("%s", &c) is writing to memory it should not as c is a single char but "%s" expects its argument to be an array. As scanf() appends a null character it will at the very least write two char to c (the char read from stdin plus the null terminator), which is one too many.
Use a char[] and restrict the number of char written by scanf():
char data[10];
scanf("%9s", data);
and use printf("%s", data); instead of %c or use "%c" as the format specifier in scanf().
Always check the return value of scanf(), which is the number of successful assignments, to ensure subsequent code is not processing stale or uninitialized variables:
if (1 == scanf("%d", &n))
{
/* 'n' assigned. 'n = n;' is unrequired. */
}
scanf("%s",&c); should be scanf("%c",&c);
The %s format specifier tells scanf you're passing a char array. You're passing a single char so need to use %c instead.
Your current code will behave unpredictably because scanf will try to write an arbitrarily long word followed by a nul terminator to the address you provided. This address has memory allocated (on the stack) for a single char so you end up over-writing memory that may be used by other parts of your program (say for other local variables).
I'm not sure you understood the answer to your other question: Odd loop does not work using %c
These format specifiers are each used for a specific job.
If you want to get a:
character from stdin use %c.
string (a bunch of characters) use %s.
integer use %d.
This code:
char c;
printf("Enter Character:\t");
scanf("%c",&c);
Will read 1 character from stdin and will leave a newline ('\n') character there. So let's say the user entered the letter A in the stdin buffer you have:
A\n
The scanf() will pull 'A' and store it in your char c and will leave the newline character. Next it will ask for your int and the user might input 5. stdin now has:
\n5
The scanf() will take 5 and place it in int n. If you want to consume that '\n' there are a number of options, one would be:
char c;
printf("Enter Character:\t");
scanf("%c",&c); // This gets the 'A' and stores it in c
getchar(); // This gets the \n and trashes it
Here is a working version of your code. Please see inline comments in code for fixes:
#include<stdio.h>
void main()
{
int n,i=1;
char c;
printf("Enter Character:\t");
scanf("%c",&c);//Use %c instead of %s
printf("Repeat Time\t");
scanf("%d",&n);
n=n;//SUGGESTION:This line is not necessary. When you do scanf on 'n' you store the value in 'n'
while (i <= n)//COMMENT:Appears you want to print the same character n times?
{
printf("%c",c);
i++;
}
return;//Just a good practice
}

Inputting float into a program that only deals with ints

I have a program, but when I input float numbers whenever the program asks for inputs, the program abruptly skips a step and moves onto the end output. The program is below:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,b,c;
int i;
printf("Please enter a number: ");
scanf("%d", &a);
printf("Please enter a number: ");
scanf("%d", &b);
c = 0;
for(i=0; i < b; i++)
{
c = c + a;
}
printf("%d x %d = %d\n", a, b, c);
return 0;
}
When I input an int for a, and a float for b, the program will output the product as expected if the numbers after the decimal point for b is truncated. However when I input a float for a, the program doesn't take the value for the second number b and instead skips that step and outputs the integer version of a x -858993460 = 0.
For example:
a = int, b = float
Please enter a number: 3
Please enter a number: 5.6
3 x 5 = 15
a = float, b = skipped
Please enter a number 3.9
Please enter a number: 3 x -858993460 = 0
All the flaws in the code are deliberate, but I just wanted to know why it behaves the way I explained above. I know it's because of something to do with trying to input a float into a signed integer but I'm not sure what exactly is causing it to skip the second scanf("%d", &b). Can anyone explain why this happens?
Thanks.
It looks like scanf() is reading your "3" in the second case, and ignoring the "9".
Then when the second scanf() is called, there is already text in the input buffer (the ".9").
I can't tell exactly what it's doing with the ".9". It may have found the dot and just aborted there with b uninitialized. It should be a simple matter to determine what is happening by stepping through with the debugger.
But, basically, not all the input is being processed by the first call to scanf() and so that's what the second call is trying to read. And that's why it's not waiting for you to input any data for the second call.
Console input is line buffered; when you enter 3.9 into a %d format specifier, only the 3 is consumed, the remaining data remains buffered, so the second scanf() call attempts to convert it according to its specifier, it finds a '.' and aborts the conversion leaving b undefined.
scanf() will continue to "fall-through" until the '\n' at the end of the input data is consumed. You can do this thus:
printf("Please enter a number: ");
scanf("%d", &a);
while( getchar() != '\n' ) { /* do nothing */ }
printf("Please enter a number: ");
scanf("%d", &b);
while( getchar() != '\n' ) { /* do nothing */ }
Note that if the format specifier is %c, a modification of the "flush" code is required, because the converted character may already be '\n' :
scanf("%c", &c);
while( c != '\n' && getchar() != '\n' ) { /* do nothing */ }
If the next character that is to be read cannot be converted under the current format as specified by the Format Specifier, scanf stops scanning and storing the current field and it moves to the next input field (if any).
And that particular character is treated as unread and used as the first character of next input field or any subsequent read operation.
In the example given above, it is scanning 3 and then cannot resolve . to the format specifier "%d". Hence it stores 3 in variable a leaving .9 as unread. The control when passes to the next scanf statement, it scans ., but again as it cannot resolve . to format specifier "%d", it skips the input scanning for that field.
Now as variable b was not assigned, it contains some garbage value. And any arithmetic operation with garbage values result into garbage values.

Resources