I'm new to C (programming in general). I was working on this for a while, my school assignment. I'm getting an output of many random numbers (e.g. 1xxxxxxxxx) instead of printed displays of input entered.
Here's the code in question:
#include<stdio.h>
int main()
{
char item[5][20];
double ppu[5], total, price[5], quantity[5];
int i;
for(i = 0; i < 5; i++)
{
printf("Enter item, price and quantity: ");
scanf("%s %f %f", &item[i], &ppu[i], &quantity[i]);
price[i] = ppu[i]*quantity[i];
total += price[i];
}
printf("ITEM\t\tPRICE PER UNIT\t\tQUANTITY\t\tPRICE\n");
for(i=0; i < 5; i++)
{
printf("%s\t\t%.2f\t\t%.0f\t\t%.2f\n", item[i], ppu[i], quantity[i], price[i]);
}
}
Change the format specifier to %lf. Don't forget to assign total with an initial value.
total hasn't been assigned (or initialized with) a relevant value.
Also, item[i] (a pointer to 20 chars) is converted to a pointer to char (what scanf expects) in the context of scanf. The & is wrong
scanf("%s %f %f", &item[i], &ppu[i], &quantity[i]);
// wrong ^^ ^^ ^
scanf("%s %lf %lf", item[i], &ppu[i], &quantity[i]); // thanks to Bpaul
Even better is making sure scanf did the right thing:
if (scanf("%s%lf%lf", item[i], &ppu[i], &quantity[i]) != 3) /* error */;
None of these variables and array members are initialized.
char item[5][20];
double ppu[5], total, price[5], quantity[5];
int i;
That means that they will contain random garbage values.
Now, the ones that you assign to with either scanf or the assignment operator will contain (possibly) useful data, but you are also missing out checking the return value of scanf, which will tell you how many values could be successfully read.
Also look at the way you use the 2-D array item. There is something wrong there.
Related
I'm trying to create a simple converter that will ask a user to input data n times. The scanf() in the loop ideally should allow user to input a response in the terminal, press enter, then pass an output, then ask again....n times. But the program so far, just asks one time and never allows user to ask again.
There are many posts about scanf in loops I've seen, but I wasn't able to connect my issue with any of them.
I'm new to C, coming from Java.
#include <stdio.h>
double feet(double m);
double lbs(double g);
double f(double c);
//double askInput(int num);
int main()
{
int num, i;
i = 0;
printf("how many?\n");
scanf("%i\n", &num);
for(i = 0; i < num; i++)
{
double input = 0.0;
double output;
char unit = NULL;
printf("num to convert, units to convert?\n");
//scanf("%lf %c\n", &input, unit);
if(input == 0.0 && unit == NULL)
{
//input = askInput(num);
scanf("%lf %c\n", &input, unit);
}
//meters to feet
if(unit == 'm')
{
output = feet(input);
}
}
I've tried a number of things. I've tried using a while loop, I've tried putting scanf in a separate function and then also using if statements. I imagine I am not quite understanding how scanf works.
You have a couple issues here.
You're assigning NULL (of type void*) into a char as well as comparing these values later. Don't do this. If you want to use some sort of canary value you could instead use the character '\0' (or any other non-readily enter-able character).
You've given scanf a parameter that it expects to be a char* as a char. In order for the line scanf("%lf %c\n", &input, unit); to work as intended, you should have an ampersand in front of unit in order to pass a pointer to the local variable unit.
Giving scanf trailing whitespace requires it to read all subsequent whitespace until it can determine a block of whitespace has ended (see man 3 scanf for some more info, but note that any whitespace character in the format string is treated equivalently). In this instance having a newline on the end of your scanf calls will require them to read some amount of whitespace and then a non-whitespace character (see also the accepted answer here: white space in format string of scanf()). Just leave off the \n.
Some of your braces (namely the block for the function main) aren't closed. I'm assuming this is just a function of copying-and-pasting into SO though.
Most of this could be avoided with a stricter compilation command. If you're using gcc with the C99 standard you could try
gcc -Wall -Werror -Wextra -Wshadow -pedantic -std=c99 source_file.c.
First of all, I recommend using the _s functions instead of the regulars (for example printf_s and not printf). Second, I wrote down a version of the code that is working. I noticed that whenever I added some text to scanf_s (for example a \n) the program didn't stop but when I printed it with printf the program stopped.
FYI: For initialization, you need to put a number that the user won't enter - If the user doesn't put a value num won't store 0 but -9.2559631349317831e+61. And you should use || instead of && because you want that num and unit will store a value! :)
Here's my code:
#include <stdio.h>
#include <string.h>
int main()
{
int amount;
printf_s("How many numbers would you like to recive?\n");
scanf_s("%i", &amount);
for (int i = 0; i < amount; ++i)
{
// Initialization of all variables.
double convertedNum;
double rawNum;
char unit[3] = "";
// Getting the variables.
printf_s("Please enter the number that you\'d like to convert and the unit to
convert to.\n");
printf_s("Number: ");
scanf_s("%lf", &rawNum);
printf_s("Units (m/ft): ");
scanf_s("%s", &unit, 3);
// To make sure that we're getting right input & the wanted amount of
// numbers.
if (rawNum == -9.2559631349317831e+61 || unit == "")
{
printf_s("Please enter a number and a unit!");
--i;
}
else if (strcmp(unit, "m") == 0)
{
convertedNum = rawNum * 3.2808399;
printf_s("\n\nAfter convention, the number is %f\n", convertedNum);
}
else if (strcmp(unit, "ft") == 0)
{
convertedNum = rawNum / 3.2808399;
printf_s("\n\nAfter convention, the number is %f\n", convertedNum);
}
}
return 0;
}
i'm attempting to create a program that asks the user to firstly enter the amount of values they would like to convert from lowercase to uppercase. The for loop then assigns each value into an array. The array then goes through another for loop to convert the values into uppercase using LowerToUpper function.
When i go to run the program, it will take in values and then start doubling them on the command window, and will cease when you have completed entering the values, rather than printf the results. Could you please explain why. Thank you in advance
#include<stdio.h>
#include <string.h>
#include <ctype.h>
void LowerToUpper(char* array)
{
toupper(*array);
}
int main(void)
{
int i, amount;
printf("How many values?\n");
scanf("%d", &amount);
char *d;
char array1 [amount];
printf("Please enter the values\n");
for(i=0; i<amount; i++)
{
scanf("%c", &array1[i]);
}
for(i=0; i<amount; i++)
{
d=&array1[i];
LowerToUpper(d);
scanf("%c", &array1[i]);
printf("%c", array1[i]);
}
return 0;
}
You are not using toupper() properly. The function returns the converted value in case of success. You need to make use of the returned value. The supplied argument is not changed.
That said, the program structure is unnecessarily complicated. you can simplify it like
for(i=0; i<amount; i++)
{
int result = toupper (array1[i]);
if (result != array1[i]) printf("%c", result); //just checkin', if converted
}
That said, you have many other issue which you don't see at this moment, like
scanf("%c", &array1[i]);
this will, to your surprise, only ask you for half the number of inputs. Why? You forgot to ignore the newline entered by RETURN key.
Then, you did not check for the success of scanf("%d", &amount); call. In case, the scanning fails, you'll end up with undefined behavior.
The second scanf() inside the last for loop is probably something you don;t want, it's useless, at best.
Change this:
toupper(*array);
to this:
*array = toupper(*array);
since toupper ref's mentions:
Return Value
The uppercase equivalent to c (*array in your case), if such value exists, or c (unchanged) otherwise. The value is returned as an int value that
can be implicitly casted to char.
PS: Defining a function LowerToUpper() for this operation (one line of code) is an overkill, and you could call that one line of code inside main() instead (I mean the body of the function to be moved into main()).
So I'm trying to find the sum of an unknown amount of user-input numbers. Here's my code
int main()
{
int tmp1 = 1;
int tmp2 = 1;
int total = 0;
printf("Enter numbers for a sum: ");
tmp2 = scanf(" %d", &tmp1);
while(tmp2 > 0){
total+=tmp1;
tmp2 = scanf(" %d", &tmp1);
}
printf("total is %d", total);
return 0;
}
It gets stuck in an endless loop, and then once i hit ctrl-c to end it, it prints the correct sum. So what I'm doing wrong is how will i know when it's done scanning all the integers, and for the loop to end; since i'm not doing it correctly now
Decided to make it stop via ctrl d, and its acceptable. thanks
In your question, it is not clear how you expect your programme to understand that there won't be anymore numbers to input. Shall it be through a specific character? Or shall it just get a line of space-separated numbers and respond with a sum?
From your code, my most sensible guess is: You want it to understand that there won't be any more numbers to add, whenever it encounters a non-digital character. My guess is so, because this is almost exactly what your code does by checking the return value from scanf.
First of all, you have to change that tmp inside your loop into tmp1 because there isn't such a variable as tmp declared. edit: well, never mind
Then try running your programme, putting in any amount of white-space (space, tab or new-line) separated numbers, and then any non-digital character you like. May be a T for example, or ThoAppelsin, it won't matter. Programme won't get beyond the first character, in fact, not even beyond the first character. After that, you shall see that the numbers have been properly added together.
Since you're confused about a non-existent infinite-loop, my second guess is that you might be actually hoping it to get a single line of space-delimited numbers, and have the sum printed; and misinterpret your programme as "in infinite loop" while it merely expects further input from you, just like it does at the very beginning.
You won't get a 0 from non-redirected scanf("%d", &var);, unless you feed it with something that doesn't match to the format string to cause abnormal termination. If there's nothing left in the input stream to consume, it will just wait for more input. But say you give an 'a' to it, then all it can do is to give up and return zero, because it couldn't do a single assignment.
If you really are hoping to have a single line of numbers, then the minimal change I could offer would be something like this:
int main(void)
{
int tmp1 = 1;
char tmp2 = 0;
int total = 0;
printf("Enter numbers for a sum: ");
scanf("%d%c", &tmp1, &tmp2);
while(tmp2 == ' '){
total+=tmp1;
scanf("%d%c", &tmp1, &tmp2);
}
printf("total is %d", total);
return 0;
}
Of course, this approach has many vulnerabilities. However, if user is to input strictly a sequence like:
3 66 2 10 6
// mind the new-line
It will work fine. But if I'm allowed to change more than minimal, this is how I would do it:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int main(void)
{
int LastNumber = 0;
int UpcomingCharacter = 0;
int Total = 0;
printf("Enter numbers for a sum: ");
while(scanf("%d%*[ \t]", &LastNumber) == 1)
{
Total += LastNumber;
UpcomingCharacter = getchar( );
if (!isdigit(UpcomingCharacter)) // eliminates a possible EOF return as well
break;
if (ungetch(UpcomingCharacter, stdin) != UpcomingCharacter)
{
fprintf(stderr, "%d: unexpected error with ungetch\n", __LINE__);
return EXIT_FAILURE;
}
}
printf("total is %d", Total);
return EXIT_SUCCESS;
}
Which should work fine on any whitespace-delimited sequence of numbers, excluding the new-lines of course.
Hello I'm trying to make simple program that will check if student assessment is greater than 5.50. When I try to enter the var "number in class" I get SEGFAULThere is my code:
#include <stdio.h>
typedef struct student{
char name[100];
int number_in_class;
double assessment;
}student;
int main(void){
student corrective[25];
int i;
for(i = 0; i < 25; i++){
printf("Ime na uchenika:\n");
scanf("%s", corrective[i].name);
printf("Nomer v klas:\n");
scanf("%i", corrective[i].number_in_class);
printf("ocenka:\n");
scanf("%f", corrective[i].assessment);
}
for(i = 0; i < 25; i++){
if(corrective[i].assessment >= 5.50){
printf("Ime: %s\nNomer v klas: %i\nOcenka: %i\n",corrective[i].name, corrective[i].number_in_class ,corrective[i].assessment);
}
}
return 0;
}
Any idea why?
You need to pass the address of the objects to scanf(), not their values
for(i = 0; i < 25; i++){
printf("Ime na uchenika:\n");
scanf("%s", corrective[i].name); // array converted to pointer to 1st element (an address)
printf("Nomer v klas:\n");
scanf("%i", &corrective[i].number_in_class); // use & to pass the address
printf("ocenka:\n");
scanf("%lf", &popravitelni[i].assessment); // same as before
}
As other posters have noted, you need "%lf" for addresses of objects of type double.
Use %lf to read a double object and not %i or%f. For printf, use %f to print a double. Also you need to pass pointers for scanf arguments. Enable all your compiler warnings and fix them.
The parameters to scanf() are incorrect. You have to pass them as pointers.
scanf("%s", corrective[i].name); is correct, because corrective[i].name is an array therefore a pointer by definition, but you cannot do the same with the other primitive data types. Head then with & to get its pointer.
...
scanf("%i", &corrective[i].number_in_class);
...
scanf("%f", &corrective[i].assessment);
In addition you should check the types you are reading as mentioned in ouah's answer.
You are using %i in this statement:
scanf("%i", corrective[i].number_in_class);
while the number_in_class is a double. Use %lf, thats used for double. Also correct %f to %lf in this statement too:
scanf("%f", popravitelni[i].assessment);
Also use &-the address-of operator to pass the address instead of value in the scanf() function.
Corrected Code:
scanf("%lf", &corrective[i].number_in_class);
.
.
scanf("%lf", &popravitelni[i].assessment);
I am working on what I thought would be a simple program to try and familiarize myself with C style code (vs. the C++ I'm used to), and have hit a roadblock.
I have allocated memory for an array using calloc, and want the user to simply enter a number, and have that number put into the array (this repeats until the array is fully populated). The array seems to have been created, but my code is not writing to the array. The program, when run, accepts an input, stores that input to a temporary variable,q (used for debugging purposes), but will not write the value of that temporary variable to the array.
Here is a snippet of code that I believe holds my issue:
//e is the size of array as indicated by user
values = (double *)calloc(e , sizeof(double));
double q = 0; // holds input just to make sure it works
for (int i = 0; i < e; i++)
{
printf("Please enter value %d: ",i+1);
scanf("%d", &q);
printf("%d", q); // confirms q = "input"
values[i] = q; //This isn't happening for me
}
I would really appreciate it if someone could please correct (and ideally explain) my error as to why values[i] is never equal to q.
The %d format specifier is for ints. For doubles use %lf with scanf and %f or %lf with printf.
scanf("%lf", &q);
printf("%f", q); // confirms q = "input"