I'm new to using fgets so I don't know what I'm doing wrong. I need to make a table of floats but I keep seg faulting during the standard input. I took out all the "unnecessary" code for readability so yes I do use all the arguments in the parameters. It seg faults even when I enter one number.
typedef struct row
{
int column;
float value[20];
}ROW;
//in main ROW table[100];
void makeTable2(ROW* table, int* row, int* column)
{
int counter = 0, counter2;
int y = 0;
char str[256], again;
printf("Enter in the table: ");
do{
fgets(str, 256, stdin);
while(sscanf(str, "%f", &table[*row].value[y]))
y++;
(*row)++;
printf("Add another row? (y or n)? ");
scanf("%c", &again);
}while(again == 'y' || again == 'Y');
}
in line
while(sscanf(str, "%f", &table[*row].value[y]))
you're reading your first number every time, NOT NEXT, only first, and get buffer overflow when y exceeds value 20.
Try scanf() every value separately.
while(sscanf(str, "%f", &table[*row].value[y]))
y++;
That's an infinite loop. You always read from the first float value present in the str buffer and eventually y become more than 19 and there is segmentation fault.
Related
For my homework, I am trying to code a calculator which can also calculate average of taken numbers. I don't want to ask for number of numbers because our teacher don't want it in that way. So I thought of scanning values until the user presses "p". But as you would guess, the numbers are float and "p" is a character. What I want to do is assigning the value scanned to both of them if it is possible. I tried different ways, played with the codes but it isn't working properly. So I am seeking your advice.
It prints a value when p is inputted as like 3rd, 5th, 7th (oddth) number (sometimes right, sometimes wrong but I can fix it if I figure this out). But it doesn't print a value in other occasions and expects infinite inputs from the user.
This is the code I have written for this. scanf("%f %c", &number1, &pause); command is where I want to know about, actually.
#include<stdio.h>
float number1, number2, i, result;
char pause;
int main() {
scanf("%f", &number1);
i = 0;
while (pause != 'p') {
number2 = number1 + number2;
scanf("%f %c", &number1, &pause);
i++;
}
result = number2 / (i - 1);
printf("%f", result);
}
Use double not floats if there is no specific reason to do so (like using uC without double FPU).
You do not initialize the variables
Always check the result of the I/O operation.
#include <stdio.h>
int main ()
{
double number1= 0, number2 = 0, i = 0, result = 0;
char pause = 0;
char line[128];
while (pause != 'p')
{
if(fgets(line, sizeof(line), stdin))
{
if(sscanf(line, "%lf %c",&number1, &pause) != 2)
{
printf("Wrong input - try again\n");
pause = 0;
continue;
}
number2 = number1 + number2;
i++;
}
else
{
// do something with I/O error
}
}
result = number2 / (i-1);
printf("%lf",result);
}
You can play with it yourself : https://onlinegdb.com/Hy3y94-3r
I noticed 3 problems with your code.
First I would advise you to use meaningful variables names. number1, number2, etc. and the i which represents the number of inputs given can be an int instead of a float.
Secondly, you lack of printing to the user what's going on in your program; it's better to have messages like "enter your number, do you wanna stop? the result is...etc".
Lastly, having two inputs in one line of code can make it hard to debug, knowing that reading strings and characters in C is already hard for beginners. For example, %c does not skip whitespace before converting a character and can get newline character from the previous data entry.
Here is my fix: I changed some variables' names, printed some messages and read the two inputs in two different lines with adding scanf(" %c") with the space to avoid that problem.
#include<stdio.h>
float sum, temp, result;
int nb;
char pause;
int main () {
pause='a';
while (pause != 'p'){
printf("Enter your number: ");
scanf("%f",&temp);
sum+=temp;
nb++;
printf("type 'p' if you want to stop: ");
scanf(" %c",&pause);
}
result = sum / nb;
printf("the average is : %f",result);
}
I tested it, should work fine
Edit: after explaining that you don't want to ask the user each time, here is how the code should work (the case that the user don't input a float is not treated, and just take it as zero
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
float sum, temp, result;
int nb;
char input[50];
int main () {
sum=0;
nb=0;
printf("Enter your numbers, then type 'p' to stop\n");
do{
printf("Enter your next number: ");
scanf("%s", input);
if(strcmp(input,"p")!=0)
{
float temp= atof(input);
sum+=temp;
nb++;
}
}while(strcmp(input,"p")!=0);
if(nb!=0)
result = sum / nb;
printf("\nThe average is : %f",result);
}
I am attaching the code for the same.Its working fine.But once i enter a number less than the previous one it stops giving desired output.Any help/suggestion shall be greatly appreciated.
int i=1;
int j=0;
int n;
char ch;
while(ch!='n')
{
printf("Enter the number upto which you want the sum of \n \n");
scanf("%d",&n);
while(i<=n)
{
j=j+i;
i++;
}
printf("%d \n",j);
printf("Do it with another number? Y/N \n \n");
scanf("%s",&ch);
}
return 0;
In your outer while loop, you're never resetting the value of the variable i back to 1, or j back to 0. That is why subsequent loops will produce an incorrect sum.
There are a smattering of bugs in this code, including:
Comparison to uninitialized value of of ch in the initial while expression.
Failing to reset i and j for each outer-loop iteration
Failing to test for data-read success in either scanf call to ensure proper input.
The continuation scanf("%s", &ch) is simply wrong for a single character with skipped whitespace (which you must do to avoid reading the newline after your list integer input). Unless EOF or an error state is reached, what you have now is guaranteed to invoke undefined behavior, as a string-read of at least one character requires at least two for storage (the character, and a subsequent terminator).
Addressing all of those:
#include <stdio.h>
int main()
{
char ch;
do
{
int n;
printf("Enter the number upto which you want the sum of \n \n");
if (scanf("%d", &n) != 1) // See (3)
break;
int j = 0; // See (2)
for (int i = 1; i <= n; ++i) // See (2)
j += i;
printf("%d \n", j);
printf("Do it with another number? Y/N \n \n");
if (scanf(" %c", &ch) != 1) // See (3) and (4)
break;
} while (ch != 'n' && ch != 'N'); // See (1)
return 0;
}
Everything here is self-explanatory when referred to the previous bug punch list, save for maybe the format string for reading the single character. You mentioned in comments that you tried %c but it skipped to another loop iteration. That's because you didn't have the leading whitespace " %c" that tells scanf to skip white space before extracting the next argument. With that, it should work as desired.
You need to reset i and j for every n.
i = 1;j=0;
while(i<=n)
{
Also your format specifer is wrong. For char, it should be %c and not %s
scanf("%c",&ch);
The simplest solution is to set i to 0 at the outer while:
int i=1;
int j=0;
int n;
char ch;
while(ch!='n')
{
i = 0;
printf("Enter the number upto which you want the sum of \n \n");
scanf("%d",&n);
while(i<n)
{
j=j+i;
i++;
}
printf("%d \n",j);
printf("Do it with another number? Y/N \n \n");
scanf("%s",&ch);
}
return 0;
Note that I have changed <= to < for your inner while, since you do not want to increment the value if the same n is inputted one after the other.
#include<stdio.h>
int main(){
int n;
char ch;
while(ch!='n')
{
printf("Enter the number upto which you want the sum of \n \n");
scanf("%d",&n);
int i=1;//it should be 1 in every loop of the number
int j=0;//the sum should also be initialized to zero to erase the previous value
while(i<=n)
{
j=j+i;
i++;
}
printf("%d \n",j);
printf("Do it with another number? Y/N \n \n");
scanf("%c",&ch);//this is a char not a string
}
return 0;
}
Due to the i is not initializing to 1 when the loop is coming for the second time there it is not going inside the loop and printing the previous value .
So I'm doing this problem where I need to calculate the average using pointers and without using strings. The user will input a letter and then a space followed by a number(an integer), the letter indicating if the number is positive(p) or negative(n) or if the user is done input-ing numbers(e).
I know I need a loop to continually read in number and add or subtract them from the sum until the letter "e" is input.
program should have and use the following function
// Precondition: value will be a pointer to where the input value is to be stored.
// Postcondition: returns true if a number was read, or false if
// it was the end of the list. The int pointed to by value will be
// set to the number input by this function, made negative or
// positive depending on the character before it. int read_number(int* value)Íž
A sample input being p 20 p 20 p 10 p 10 e
output: 15
My problem as of now is my loop is only reading for two cycles of input, and even then it isn't printing the average. Also I'm supposed to use a pointer but given the directions i'm still not sure what the context is, I'm not seeing where a pointer is useful.
#include <stdio.h>
//precondition: value will be a pointer to where the input value is to be stored.
int main(){
int sum;
int num;
int counter;
float avg;
char let;
scanf("%c %d", &let, &num);
for (counter=0;let == 'n' || let == 'p'; counter++){
scanf("%c %d", &let, &num);
if ( let == 'n'){
sum-=num;
}
if (let == 'p'){
sum+=num;
}
if ( let == 'e'){
avg=sum/counter;
printf("%f", &avg);
}
}
return 0;
}
Your input is:p 20 p 20 p 10 p
10 e.
The scanf before the loop scans 'p' and then skips the space and then scans 20. The next scanf in the loop reads the space as it is also a character and the %d fails to scan an int and the stops scanning. See the problem?
To fix it, change
scanf("%c %d", &let, &num);
To
scanf(" %c %d", &let, &num);//Note the space before %c
The space before %c gobbles up whitespace characters(if any) like newlines, spaces etc until the first non whitespace character.
Other problems include not initializing sum to 0 and using &avg instead of avg in the printf below
printf("%f", &avg);
I'm trying to cope with my exercise. I have to input n (up to 10^6) integers separated by space in single line and sum them.
For e.g. 0 1 541 10 54 100000000...
I tried scanf, but it takes to much time (Limit for this algorithm is only 1sec):
int n;
long long int sum;
scanf("%d\n", &n);
while(n--){
scanf(" %d", &value);
suma+= value;
}
I decided to read that line as char array, and then split using space as delimiter.
int n;
long long int sum;
scanf("%d\n", &n);
char tab[n];
scanf("%[^\n]s", tab);
char* split=strtok(tab," ");
while(split != NULL){
suma += atoi(split);
split=strtok(NULL," ");
}
But it doesn't work :/ Probably there is a problem with bounds of array, but I'm not sure and I can't repair this error.
Fix last call to strtok() to receive argument ++split instad of NULL
after printf line program ends itself but i didnt get it why.
#include<stdio.h>
int main ()
{
int Sum,multiply,divide,difference,num1,num2;
char i;
scanf("%d", &s1);
scanf("%d", &s2);
printf("Type initial of your operation : ");
scanf("%c", &i);
return 0 ;
}
There is no way you could compile that, since s1 and s2 are undefined variables.
Thus, any information about what happened when you ran it is moot, since there is no way you could run it.
You meant:
if(scanf("%d %d", &num1, &num2) == 2)
{
printf("Operands are %d and %d, now type initial of desired operation:\n");
if(scanf("%c", &i) == 1)
{
}
}
It's important to check that scanf() has succeeded before relying on the return value.
use scanf(" %c",&i);
there is new line character is present in buffer,so it is not asking for any input and storing it in i.
s1 & s2 are not declared which you are trying to read into them.
I feel they should be num1 & num2 which you been declared as integers.
After printf you just read a char value into i using scanf and main ends doing nothing.