input array of unknown floating signed numbers in C [duplicate] - c

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 1 year ago.
So I want to read user input array of UNKNOWN number of values ,eg: 1.0 3.0 -2.0.... etc, naturally I did scanf("%s", array) first and realized that it would only read until first space, and then I attempted the following:
#include <stdio.h>
int main()
{
printf("enter array: ");
char str[100];
fgets(str, 100, stdin);
printf("%s", str);
return 0;
}
That itself works, however when I incorporated it into the rest of my code it does not work it just skips the input of the array
#include <stdio.h>
int main()
{
float a, b;
int t;
printf("A: ");
scanf("%f",&a);
printf("B: ");
scanf("%f",&b);
printf("T: ");
scanf("%d",&t);
printf("enter array: ");
char str[100];
fgets(str, 100, stdin);
printf("%s", str);
return 0;
}
What am I doing wrong please help

This seems to be because of a trailing newline in the stdin stream, when you do a scanf("%d",variable) and input some integer and press enter, only the integer is read and the trailing newline from the pressing of the return key is left in the input stream. So when you call fgets() this newline gets read and the function immediately exits. You can find an explanation for it in the C Faq.
There are multiple solutions for this, for one you can simply eat up the newline using
while(getchar()) != '\n') {
/* do nothing and discard the character */};
printf("enter array: ");
you can also see this question and this one for some more details.

Related

How to de-allocate an array of characters in c?

I'm writing a program that asks the number of strings which i'll then count how many spaces it has.
My problem is when I start a new cycle I can't allocate the array of characters I use to count the spaces.
Thanks in advance.
#include <stdio.h>
#include <string.h>
int main(){
char a[20];
int x, z, esp=0, num;
scanf("%d\n", &num);
int array[num];
for (int i=0;i<num;i++){
scanf("%[^\n]", &a);
z =strlen(a);
for (x=0; x<=z; x++){
if (a[x] == ' '){
esp++;
}
}
array[i] = esp;
esp =0;
}
for (int i=0;i<num;i++){
printf ("%d\n", array[i]);
}
return 0;
}
Problems:
Not having all warnings enabled. Save time, enable them all.
'\n' blocks for more input in scanf("%d\n", &num);
Not checking scanf() return value.
Not limiting input with a width in scanf("%[^\n]", &a);
Wrong type passed in scanf("%[^\n]", &a);
Big one: not consuming the end-of-line with repeated scanf("%[^\n]", &a); calls.
Perhaps more.
Repaired code:
// scanf("%d\n", &num);
if (scanf("%d", &num) != 1) { // '\n' removed
puts("Error1");
return -1;
}
// scanf("%[^\n]", &a);
if (scanf(" %19[^\n]", a) != 1) { // ' ' consumes white-space like \n
puts("Error2");
return -1;
}
On the first scanf, remove \n character, after the first scanf, add getchar() to consume new line character.
Replace second scanf with gets;
Then it will work correctly.
By the way, since gets is unsafe, you can use fgets with stdin parameter and max character count parameter instead of gets.
Thanks to everyone who commented and answered my question, I think I wasn't able to explain myself properly. It's a code which reads a number, the number of the lines of characters which then it'll count the spaces of; my problem started when the code executes a new cycle in which this scanf didn't let me enter the string of characters again: scanf("%[^\n]", &a), but did everything else in the cycle while using the same string.
I'm really new to this, coding and the page itself so thanks for the advices. I was able to find a solution: scanf("%[^\n]%*c, &a)
%*[^\n] scans everything until a \n, but doesn't scan in the \n. The asterisk(*) tells it to discard whatever was scanned.
%*c scans a single character, which will be the \n left over by %*[^\n] in this case. The asterisk instructs scanf to discard the scanned character.
And here is the updated code:
#include <stdio.h>
#include <string.h>
int main(){
char a[20];
int x, z, esp=0, num;
scanf("%d\n", &num);
int array[num];
for (int i=0;i<num;i++){
scanf("%[^\n]%*c", &a);
z =strlen(a);
for (x=0; x<=z; x++){
if (a[x] == ' '){
esp++;
}
}
array[i] = esp;
esp =0;
}
for (int i=0;i<num;i++){
printf ("%d\n", array[i]);
}
return 0;
}

A user types a word and a number on a single line. Read them into the provided variables. Then print

It takes in a word and a number, I can't seem to understand why the number variable won't receive the input, help please.
#include <stdio.h>
int main(void) {
char userWord[20];
int userNum;
scanf("%s", userWord);
printf("%s_", userWord);
scanf("%s", userNum);
printf("%d\n", userNum);
return 0;
}
Should be:
Input: Stop 7
Output: Stop_7
What I get:
Input: Stop 7
Output: Stop_0
Change
scanf("%s", userNum);
to
scanf("%d", &userNum);
You used format %s for reading in an integral value; it should have been %d.
Once having fixed this (i.e. by writing scanf("%d", &userNum);, note that your code will read in a string and a number even if the string and the number were not in the same line (cf., for example, cppreferene/scanf concerning format %s and treatment of white spaces). Further, you will run into undefined behaviour if a user enters a string with more than 19 characters (without any white space in between), because you then exceed your userWord-array.
To overcome both, you could read in a line with fgets, then use sscanf to parse the line. Note that you can parse the line in one command; the result of scanf is then the number of successfully read items. Further, note the %19s, which limits the input to 19 characters (+ the final string termination character '\0'):
int main() {
char line[100];
if (fgets(line,100,stdin)) {
char userWord[20];
int userNum;
if (sscanf(line, "%19s %d", userWord, &userNum) != 2) {
printf("invalid input.\n");
} else {
printf("word:'%s'; number: %d", userWord, userNum);
}
}
}

fgets() doesn't function as expected [duplicate]

This question already has answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
scanf() leaves the newline character in the buffer
(7 answers)
Closed 5 years ago.
This is my code
int main(){
int N,i,radius,diameter,count =0;
char str[20];
char color[N][20];
printf("Get the num : ");
scanf("%d",&N);
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
}
for(i=0;i<N;i++){
printf("%s",color[i]);
}
return 0;
}
Given inputs are:
N = 3
red 50,
50 green,
blue 50
Here the problem is fgets inside for loop gets executed only twice if N is 3. This problem doesn't arise if I comment the scanf statement. Can somebody explain me what is causing this problem and how it can be solved?
After a few hours of scratching my head, I realized the following:
Avoid using scanf. Managing buffer overflows is not easy.
Always try to use fgets to get user inputs.
Try this code here:
#include<stdio.h>
#include<stdlib.h>
int main(){
int N,i,radius,diameter,count =0;
char str[20];
printf("Get the num : ");
char buffer[64];
fgets(buffer, 64, stdin);
N = strtoul(buffer,NULL,10);
char color[N][20];
printf("%d\n",sizeof(color));
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
if(color[i][strlen(color[i])-1]=='\n'){
color[i][strlen(color[i])-1]='\0';
}
else{
while((getchar())!='\n');//this is just to prevent an overflow for the size of char arrays
}
}
for(i=0;i<N;i++){
printf("%s\n",color[i]);
}
return 0;
}
Notice that I first input a number inside a char array. Convert that into a number using strtoul(string to unsigned long). Now inside the for loop I again use fgets to take inputs. The problem was, if you enter a string greater than 19 chars, the remaining part will be left inside the input buffer and shall be assigned to the subsequent input. To manage that I used getchar inside a while loop, which consumes all the unnecessary characters and the newline character from the input stream. Avoid using fflush as it may result in undefined behavior as answered here
-fflush(stdin) function does not work
-http://www.geeksforgeeks.org/clearing-the-input-buffer-in-cc/
Also note that you are using Variable Length Arrays which may not always be a good choice. Older versions of c compiler prohibit them. You had declared color[N][20] first before initializing N. That was wrong.
I suggest you to read this too
-C - scanf() vs gets() vs fgets()
After using scanf you'd need to clean the buffer. I suggest to never use scanf, just use fgets and then convert the output to a number:
int main(){
int N,i,radius,diameter,count =0;
char str[20];
char color[N][20];
printf("Get the num : ");
char buffer[64];
fgets(buffer, 64, stdin);
N = atoi(buffer); // you need to include stdlib.h
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
}
for(i=0;i<N;i++){
printf("%s",color[i]);
}
return 0;
}
Due to this reference:
https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm
this will be correct:
int _tmain(int argc, _TCHAR* argv[])
{
int N, i, radius, diameter, count = 0;
char str[10];
char color[20];
printf("Get the num : ");
scanf_s("%d", &N);
printf("Enter the mesage\n");
//for (i = 0; i<N; i++){
fgets(color, 20, stdin);
//}
//for (i = 0; i<N; i++){
printf("%s", color);
//}
return 0;
}
I changed scanf to scanf_s for VC++.

Problems with functions

I have two problems with the code, the first one being that the program wants me to enter my number twice and the second one being that the program closes down immediately after it has finished its process.
I have tried to use the getchar() statement to stop it doing so but it doesn't seem to work.
#include <stdio.h>
int square(int); /*function prototype*/
main()
{
int x; /*defining the function*/
printf("Enter your number\n");
scanf_s("%d \n", &x); /*reading the users input*/
printf("Your new answer is %d \n", square(x)); /*calling the function*/
getchar();
getchar();
}
int square(y) /*actual function*/
{
return y * y;
}
Fix the issue by changing
scanf_s("%d \n", &x);
to
scanf_s("%d", &x);
The problem was that a whitespace character (space, newline etc) in the format string of scanf insructs scanf to scan and discard any number of whitespace characters, if any, until the first non-whitespace character.
As for the problem with getchar(), replace the first getchar() with:
int c;
while((c = getchar()) != '\n' && c != EOF);
This will scan and discard everything until a \n or EOF.
Also, change
main()
to
int main(void)
and
int square(y)
to
int square(int y)
I would recommend using scanf("%d", &x); to read your number. Your problem is that your argument looks like this:"%d \n" so the program expects you to enter your number AND \n. This way, you say how you want your x to look, and in your case, it expects it to be a numeric value, a space and end of line.
As for the closing one, use getch();. For this function, you need to include the conio.h like you did with stdio, meaningly: #include <conio.h>.

Unexpected output of scansets in C

as expected this prog. should accept a number until it encounters a 4 but it gives some garbage value. why?
int main(void)
{
int a;
printf("Enter a number: ");
scanf("%[^4]d", &a);
printf("You entered: %d\n", a);
return 0;
}
As far as I know scansets are meant to be used with strings (which makes the d not act as an integer placeholder specification). One way to write it is to read the input into a string and then parse it:
int main(void)
{
int a;
char b[255];
printf("Enter a number: ");
scanf("%254[^4]", &b);
a = atoi(b);
printf("You entered: %d\n", a);
return 0;
}
I'm keeping the modified code to a minimum, you'd definitely need some extra checks for input sanity.
To clarify: The 254 prefix limits the amount of data that scanf will capture, so as to not exceed the size of the buffer (strings are terminated with an extra null character, so the read length must be smaller than the actual size)1.
The scanset working with only characters.
Here is my sample code. (but, I don't know what you really want.)
#include <stdio.h>
int main(void) {
char buffer[128];
printf("Enter a number: ");
scanf("%[^4]s", buffer);
printf("You entered: %s\n", buffer);
return 0;
}
The result is,
Enter a number: 12345678
You entered: 123
Additionally, if you want integer value, use atoi().

Resources