Hey I don't understand why my its taking two inputs while taking the element as input . I tried this code on TurboC compiler , GCC but got the same error .
#include <stdio.h>
int menu();
void bubble_short();
void selection_short();
int main()
{
int ch,j,n,a[100];
ch=menu();
switch (ch)
{
case 1:
{
bubble_short();
break;
}
case 2:
{
selection_short();
}
default :
break;
}
}
void bubble_short()
{
int i,j,n,a[100];
printf("Elements");
scanf("%d",&n);
for (j=0; j<n;j++)
{
scanf("%d",&a[j]);
}
for (i=0;i<n;i++)
{
for (j=0;j<n-1-i;j++)
{
if (a[j]>a[j+1])
{
a[j]=a[j]+a[j+1];
a[j+1]=a[j]-a[j+1];
a[j]=a[j]-a[j+1];
}
}
}
printf("the sorted elements are :\n");
for ( i = 0; i < n; i++)
{
printf("%d\n",a[i]);
}
}
void selection_short()
{
int i,j,n,a[100],min;
printf("Elements");
scanf("%d",&n);
for ( i = 0; i <n-1; ++i)
{
min=i;
for ( j = 1+i; i < n; ++i)
{
if(a[min]>a[j])
min=j;
}
if(i!=min)
{
a[i]=a[i]+a[min];
a[min]=a[i]-a[min];;
a[i]=a[i]-a[min];;
}
}
printf("the shorted elements are :\n");
for ( i = 0; i < n; ++i)
{
printf("%d\n",a[i] );
}
}
int menu()
{
int k;
printf("Enter the choice \n 1. bubble short \n 2. selectionshort");
scanf("\n %d ",&k);
return k;
}
Hey I don't understand why my it's taking two inputs while taking the element as input. I tried this code on TurboC compiler, GCC but got the same error.
Output
Got your problem!
Never use newlines, whitespace, tabs and return carriages inside scanf as to avoid such problems and maintaining good coding guidelines! These act as delimiters for it and you have provided 3 of them.
Edit your menu scanf to this:-
scanf("%d",&k);
A basic logic behind it:- Taking a basic example :-
scanf("%d %d", &i, &j);
Notice that space between two placeholders. When you run this, it will take the first input and then it will wait for that delimiter to be read from the keyboard and afterwards it will read the second parameter of the input.
I think the rest of the program should run fine.
In the menu() function, you have:
scanf("\n %d ",&k);
The leading white space characters (the '\n' and the ' ') are not needed; %d skips leading white space anyway, and one is sufficient. Note that each white space character in a format string for scanf() et al maps to zero or more white space characters in the input.
The trailing white space is bad. It means skip zero or more white space characters (newlines, blanks, tabs) and keep going until you see something that isn't a white space character (or until EOF). Trailing white space in a format string is a bad idea — doubly so when the input is supposed to be interactive. You have to predict what the next input should be before you can terminate the current input, which is not easy for people to do.
There are multiple other issues, too. Your function declarations are not prototypes (you must write int menu(void); etc to make it a prototype in C). You're missing a break after case 2: — it happens to be harmless at the moment, but when you put an error message or another sort option into the system, it becomes a problem. You haven't used enough functions: you should have an array reading function and an array printing function and should use them. You've left the data reading loop out of your selection_short() function. Normally, the term used is sort, not short — the function names seem anomalous to most people.
Your swap algorithm is contorted:
a[i]=a[i]+a[min];
a[min]=a[i]-a[min];;
a[i]=a[i]-a[min];;
You don't need the double semicolons. And you run the risk of overflows if the values are large enough. It's simpler, and far more orthodox — and ultimately safer — to use:
int tmp = a[i];
a[i] = a[min];
a[min] = tmp;
You should check each and every scanf() call to ensure that it succeeded, taking appropriate action if it fails. Note that it can fail by returning 0 or EOF; you should test:
if (scanf("%d", &n) != 1)
…oops…
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;
}
So I'm basically trying to make a for loop that scans the input line. The input is always one double float number and then one string. It continues scanning until the string = is reached. Each number value is stored to an array of double and each string to an array of char.
Problem is that the input line can be arbitrarily long and I don't know how to make it
The program should work as a basic calculator which reads one double float, then one operator as a string, and performs operation. If another number follows, then perform the operation with this number. If the equal sign = is reached, the program outputs the result.
int main() {
double res;
double in[10];
char *op[10][5];
int arrCheck[10];
for(int i=0; i<=5; i++) {
scanf("%lf %s ", &in[i], op[i]);
arrCheck[i] = opCheck(op[i]);
}
return 0;
}
This is the main section of my program so far. I managed to get it working and storing the data correctly. Although it always works only on predefined limit (i<=5, for instance). Is it legal to write condition like:
for(i = 0; i<'\n'; i++), or i<=?
I would expect it to continue scanning and storing the data until it reaches the equal sign =.
Try this:
for(int i = 0; (i <= 5) && (strcmp(op[i], "=") != 0); i++) {
...
}
And on your question, it is not legal to compare integers with strings. This is why string comparing functions exist.
You can also break from for loop like this:
int main()
{
double res;
double in[10];
char op[10][5];
int arrCheck[10];
for(int i=0;i<=5;i++){
scanf("%lf %s ", &in[i], op[i]);
if (strcmp(op[i], "=") == 0)
break;
arrCheck[i] = opCheck(op[i]);
}
return 0;
}
Which is even better solution than the one posted previously.
Since you are reading with scanf and the "%s" conversion-specifier, you will consume leading whitespace before each operator stored in op[n]. There is no need to call strcmp, you can simply check the first character by dereferencing the pointer, e.g.
if (scanf ("%lf %s", &in[i], op[i]) != 2 || *op[i] == '=')
break;
A short example omitting opCheck(op[i]) not included in your question, you could do something similar to:
#include <stdio.h>
int main (void) {
double in[10];
char op[10][5];
int i = 0, n;
while (i < 10) {
if (scanf ("%lf %s", &in[i], op[i]) != 2 || *op[i] == '=')
break;
i++;
}
n = ++i;
puts ("\nequation: ");
for (i = 0; i < n; i++)
printf (" %g %s", in[i], op[i]);
puts (" res");
}
(note: the use of while (i < 10) rather than a for (i = 0; i < 10; i++). You do not want to increment i in case of a matching or input failure. You only increment i after validating both conversions succeeded)
Example Use/Output
$ ./bin/eqnread
5.1 + 6 - 2 + 25 * 4 =
equation:
5.1 + 6 - 2 + 25 * 4 = res
So I'm basically trying to make a for loop that scans the input line. The input is always one double float number and then one string.
If you care about lines specifically (which are ended by \n -or by \r on some operating systems), you cannot use scanf alone, because scanf deals with all kind of space characters (including the space, the tabulation, the newline, the formfeed characters) in the same way, so ignores the specificity of end of line characters (\n and/or \r).
So the good way is to read the entire line first with fgets (or getline(3) on Linux) and later to parse that line. Be careful about very long lines, they could happen.
How would you parse that read line is a different question: manual lexing and parsing, or sscanf, or strtok or strtod, etc... come to mind.
And you did not define what a string is for you. What about spaces inside it? What about input lines that are longer than what you expect (e.g. a line of a thousand characters)? The %s for scanf would stop at the first space.
Don't forget to read carefully the documentation of every used function. Learn How to debug small programs.
Be also aware that, practically speaking, in 2019 UTF-8 is used everywhere, and that may add complications to your scheme (and to what strings are in practice).
The program should work as a basic calculator
It seems that you then should care about operator precedence. Then, recursive descent parsing comes to mind.
Trying to take strings as input and place it in 2d array. Why is this given code showing different behavior. The last for loop "arr[i][j]" is not printing the string.It is not even printing a character also.
Why this code does not work.only this code.Not a new way to write it
This code takes input just fine(or at least the way needed.each row a single string no white space)And when a short string is stored remaining are filled with null after carriage return. When the arr[] is passed in last for loop everything seems fine only when arr[][] is passed ,the problem arises.But again arr[][] is initialized as arr[1][0] then arr[2][0] so should not it work!
#include <stdio.h>
#include <stdbool.h>
int main(void){
int i,j,m;
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
for(j=0;j<50;j++){
printf("please enter a string");
scanf("%s",&arr[i][j]);
/*j is always 0. arr[i] takes string without space and store ending with null*/
break;
}
}
//Everything fine upto this,including storing a small continuous string in arr[i](where i<50) and null terminating*/
for(i=0;i<m;i++){
for(j=0;j<50;j++){
printf("%s\n",arr[i][j]);
break;
}
}
}
You program has several issues, like using wrong format specifier:
scanf("%s",&arr[i][j]);
arr[i][j] is a character and you are using %s format specifier. If you want your program should take string as input, you just need to do:
scanf("%s",arr[i]);
Since, you have given the size 50 characters, put a restriction in scanf() to not to read more than 49 characters (the remain one character space is for null terminating character) like this:
scanf("%49s",arr[i]);
^^
Beware with this, it does not discard the remaining input from input stream when the input characters are more than 49 and the remaining characters will be consumed by consecutive scanf() call.
If you want to drop the extra input which wasn't consumed by scanf(), one way of doing it is to read and discard the extra input using a loop, like this:
int c;
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
In case if you have any doubt on how this will discard the extra input, I would suggest first go through getchar().
Putting all these together, you can do:
#include <stdio.h>
int main(void){
int i,m;
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
printf("please enter a string");
scanf("%49s",arr[i]);
int c;
while((c = getchar()) != '\n' && c != EOF) // <=== This loop read the extra input characters and discard them
/* discard the character */;
}
for(i=0;i<m;i++){
printf("%s\n",arr[i]);
}
return 0;
}
EDIT
The below edit is because OP updated question and added - Why this code does not work.only this code.Not a new way to write it
Above in my answer, I have already stated that you are using wrong format specifier in the scanf(). In this part of your code:
for(i=0;i<m;i++){
for(j=0;j<50;j++){ // <====== Nested for loop
printf("please enter a string");
scanf("%s",&arr[i][j]);
// since the nested loop is supposed to run 50 times, assuming you are trying to read character by character and using %s format specifier
break;
// the nested loop will break in the first iteration itself unconditionally, do you really need nested loop here!
}
}
Check the inline comments. Hope this might give an idea of the mistakes you are doing.
Seems that you want to read string character by character using scanf(). If this is the case than make sure to take care of null terminating character because, in C, strings are actually one-dimensional array of characters terminated by a null character '\0'.
You can do:
#include <stdio.h>
void discard_extra_input() {
int c;
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
}
int main(void){
int i,j,m;
printf ("Enter number of strings: ");
scanf("%d",&m);
discard_extra_input();
char arr[m][50];
for(i=0;i<m;i++){
printf("please enter string number %d: ", i+1);
for(j=0;j<49;j++){
scanf("%c",&arr[i][j]);
if (arr[i][j] == '\n') {
//need to add null terminating character manually
arr[i][j] = '\0';
break;
}
}
if (j==49) {
// In case where the input from user is more than 50 characters,
// need to add null terminating character manually.
arr[i][j] = '\0';
// discard the extra input when input from user is more than 50 characters.
discard_extra_input();
}
}
for(i=0;i<m;i++){
for(j=0;j<50 && arr[i][j]!='\0';j++){
printf("%c",arr[i][j]);
}
printf ("\n");
}
return 0;
}
The code is self explanatory except one thing - call to discard_extra_input() function after first input from user scanf("%d",&m);. Reason -
Look at the statement:
scanf("%c",&arr[i][j]);
the %c format specifier will consume the leftover newline character '\n' from the input stream due to the ENTER key pressed after first input by the user (number of strings input from user). Hence, in order to discard it, calling discard_extra_input() function. In the other place it has been used to discard the characters when user entered string of size more than 49.
Hope this helps.
I know the code. But looking for specific ans. Where the problem lies with the code
The problem is here:
scanf("%s",&arr[i][j]);
and here:
printf("%s", arr[i][j]);
This is the specific answer you are looking for.
%s won't do any bound checking. It adds the characters starting from the memory location arr + i * m + j to arr + i * m + j + (length of input) + 1 (one extra char for the additional null character that scanf appends). Take a sample input. Assume an arbitrary starting address for arr and do the maths.
Also consider any writes beyond the allocated space for arr leads to undefined behavior.
Similarly printf("%s", arr[i][j]); will try to start reading from the address arr[i][j] till it finds a null character. It would usually lead to crash of the code because if your string has ascii characters, the address would be too low to point to any valid user-mapped memory.
If your code is working, its mostly because you already have a UB in your scanf.
Get a pen and paper and do some dry runs
This is a pretty simple problem buddy. You've got the idea right actually, that you need to use 2d array to store strings. Just that the usage is slightly wrong.
First of all let me tell you how 2d arrays need to be used to store in c. In your 2-D array, you've got rows and columns. Say, row represented by i and columns by j, i.e, each row arr[i] contains j elements. So in your context, each row arr[i] contains each string of upto 50 chars. So scanf should be just for arr[i]. And you need to loop with for, m times to accept m strings.
Same applies to printing as well.
Here is the working code:
#include <stdio.h>
#include <stdbool.h>
int main(void){
int i,j,m;
printf("\nenter m value:");
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
printf("\nplease enter a string no %d: ", (i+1));
scanf("%s",arr[i]);
}
printf("\nthe strings are: \n");
for(i=0;i<m;i++){
printf("\n%s\n",arr[i]);
}
}
And the output in case you want to cross check:
OUTPUT:
enter m value: 3
please enter a string no 1: qwerty
please enter a string no 2: asdfgh
please enter a string no 3: zxcvbn
the strings are:
qwerty
asdfgh
zxcvbn
I am writing a program that starts printing at 0.
It prints up to 15 and asks the user a y/n question.
if y that program prints next 15.
if n program stops.
The program I wrote does not work.
Help solving this.
int main()
{
int i=0,k=1;
char ans;
while(k=1)
{
i++;
printf("\n%d",i);
if(i%15==0)
{
printf("\nDo you want to continue?(y/n): ");
scanf("%c",ans);
ans = toupper(ans);
if(ans=='Y') {
continue;
}
else if(ans=='N') {
k=0;
}
}
}
}
----------------------------------EDIT-------------------------------------
changed the code as #Programmer400. Also 15-->3. Now my computer prints
1
2
3
Do you want to continue?(y/n): y
4
5
6
Do you want to continue?(y/n):
7
8
9
Do you want to continue?(y/n): y
First it prints till 3 and asks. After Y, it prints till 6 and asks and then without any input prints till 9 and asks. Note the missing y in the 2nd question.
I have provided a working C program below that performs the tasks you specified in your question.
I have taken an effort to stay true to the functions that you used in your original code sample and I have also taken care to only make additions (not remove code).
In the comments, I have explained lines of code that I have added that were not in your original code sample.
#include <stdio.h>
int main(void)
{
int i = 0, k = 1;
char user_input;
char ans;
while(k == 1)
{
i++;
printf("%d\n", i);
if (i % 15 == 0)
{
printf("Do you want to continue? (y/n/Y/N): ");
scanf(" %c",&user_input); // Keep the whitespace in front of the %c format specifier -- it's important!
getchar(); // Consume the newline character left in the buffer by scanf()
// Check if user input is already capitalized
if (user_input >= 65 && user_input <= 90)
// If it is, keep it capitalized
ans = user_input;
else
// If it isn't, capitalize it
ans = toupper(user_input);
if (ans=='Y')
{
// Allow the loop to continue
continue;
}
else if (ans == 'N')
{
// Inform the user that execution is ending
printf("Exiting loop... ending program.\n");
// Consider removing 'k' entirely, just use a 'break' statement
k = 0;
}
else
{
// Inform the user that the input was not recognized (if not y/n/Y/N...)
printf("User input not recognized... please provide input again.\n");
// Decrement 'i' so that the user is forced to provide input again...
i--;
// Allow the loop to continue
continue;
}
}
}
}
Helpful notes:
scanf leaves a newline character in the buffer when you are reading user input with character formatters. Namely...
%c, %n, and %[] are the 3 specified expectations that do not consume leading whitespace
-- From a comment on this StackOverflow answer.
Keep in mind that if you would like to exit your while loop, you could simply insert a break statement. This way, you don't have to change the value of k (which is rather ambiguous) to end the loop and the code is more readable because an explicit break statement is harder to misinterpret. In this simple case, the use of k is easily understood (so don't worry about it too much, for now).
If you ever intend to read string input from a user (i.e., an array of characters), then I would recommend that you use fgets() instead of scanf(). A discussion of the merits of fgets() in comparison to scanf() is provided in this StackOverflow answer. Further, it is important to recognize that even though you can use gets() to perform a similar operation it is highly dangerous and never advised. Check out the explanations provided by the top two answers to this StackOverflow question.
I tried changing your code so that it doesn't generate warnings, now it seems to "work" (but maybe it can be even more correct).
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
int main()
{
int i=0,k=1;;
char c;
char ans[] = "";
while(k==1)
{
i++;
printf("\n%d",i);
if(i%15==0)
{
printf("\nDo you want to continue?(y/n): ");
scanf(" %c",ans);
ans[0] = (char) toupper(ans[0]);
if(ans[0]=='Y') {
continue;
}
else if(ans[0]=='N') {
k=0;
}
}
}
}
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.