I want to create an infinite loop such that I'm able to ask the user for up to 2 inputs, and store them into an array (a) and then print these array values. I want it then to restart, and repeat this process of asking and repeating. With my current code, once I enter values and declare End of Function (EOF), the console infinitely prints out these values rather than restarting and asking for new values.
#include <stdio.h>
int main (void) {
int a[2];
int i = 0;
while (1 < 2) {
while(scanf("%d", &a[i]) != EOF) {
i++;
//i == number of inputs (max is 2)
}
int j = 0;
while(j < i) {
printf("%d ", a[j]);
j++;
}
}
return 0;
}
My hypothesis is that the scanf("%d", &a[i]) value has not reset after being declared as being EOF but I'm not entirely sure on how to do that.
You have undefined behavior because of accessing out of bound.
You need to reset the i on each iteration or even better limit the scope of i to each iteration.
int i = 0;
while (1) {
i = 0; // reset i
while(scanf("%d", &a[i]) == 1 && i < 2) {
i++;
//i == number of inputs (max is 2)
}
...
}
Related
I was trying to make a program where if I enter an integer, the program would find out the bigger number and subtract it by the smaller number. This part, I got it.
The problem is, the infinite loop part.
I tried to get type in two integers keep on printing with the while loop, and break when at least one character is typed in.
For example, if I type in 2 #, it would break.
But I couldn't find the write place to get the break; within the code and therefore whenever I enter a character it would keep on creating an infinite loop.
Is there any way to create a break in this code? I humbly ask for advice...
The following is the code which I couldn't put the break
(By the way, the reason I did the condition in while as sizeof(i)==4 || sizeof(j)==4 was to make it so it would only enter an integer, since the size of an integer is 4)
int main()
{
int i, j;
int result;
while (sizeof(i)==4 || sizeof(j)==4){
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i){
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
The bottom code is the one I tried to put break but failed (it kept creating an infinite loop)...
int main()
{
int i, j;
int result;
while (sizeof(i)==4 || sizeof(j)==4){
if (sizeof(i) == 4 || sizeof(j) == 4) {
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
else
break;
}
return 0;
}
and here's a code where I got rid of the sizeof and used while(1), though there wasn't much change in the fact that the break didn't work...
int main()
{
int i, j;
int result;
while (1){
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
You can't use sizeof(i) to do run-time checks! This is a compile-time constant that, in your case (32-bit integers) will always evaluate to 4.
In order to check that two valid integers have been given, you can check the return value of the scanf function (it gives the number of fields successfully scanned):
#include <stdio.h>
int main()
{
int i, j;
int result;
while (1) {
printf("type in two integers : ");
if (scanf("%d %d", &i, &j) != 2) break; // Break here if we didn't get two integers
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
Feel free to ask fir further clarification and/or explanation.
Drop the whole concept of endless loop with break inside if.
Make a condition for the loop based on the return value of scanf(), that is practically what it is designed for.
#include <stdio.h>
int main()
{
/* always init everything */
int i=0, j=0;
int result=0;
printf("type in two integers : ");
while (2==scanf("%d %d", &i, &j))
{
if (i < j) {
result = j - i;
}
else /* removed second if, to have a meaningful result for i==j */
{
result = i - j;
}
printf("%d\n", result);
printf("type in two integers : ");
}
return 0;
}
I'd probably actually use do {...} while (...) with a variable storing the return value of scanf()for being used in the loop condition. I'd consider it more elegant for not having to copy the print, but I kept it closer to your code structure.
More comments on your code:
as explained in comments, sizeof() works differently than you seem to think; it is static and does not change at runtime and hence cannot be used in a loop condition
with while (sizeof(i)==4 || sizeof(j)==4){if (sizeof(i) == 4 || sizeof(j) == 4){/* a */} else {/* b */}, b cannot ever be reached, because the conditions of while and if are identical
check the possible outcomes of the if conditions inside the loop, you are leaving the one with i==j undefined and return an uninitialised value
always init all variables as a habit
for a good MRE include the include lines
On your request, here is a proposal for the do-while alternative:
#include <stdio.h>
int main()
{
/* always init everything */
int i=0, j=0;
int result=0;
int iScanned=0;
do
{
printf("type in two integers : ");
iScanned=scanf("%d %d", &i, &j); /* keep the return value for loop */
if (i < j) {
result = j - i;
}
else /* removed second if, to have a meaningful result for i==j */
{
result = i - j;
}
if(2==iScanned) printf("%d\n", result); /* if to avoid awkward last output */
} while (2==iScanned);
return 0;
}
I am trying to write a program to check for duplicate input from a programmable handheld barcode scanner, I am programming it to be able to scan 2000 barcodes.
I am new to c Programming, I am trying to take an input and put it into the array and increase the pointer to the next with every loop.
Example: int Array [10];
I want to scanf() into Array location 0 on the first loop then increment by 1 location to location 2 etc every time the while loops runs. Please help, your help is much appreciated.
#include <stdio.h>
int main ()
{
int i,j,k=1,arr[2000],ArrSize=2000;
//Welcome message
printf("Welcome to Yamato Transport (S) Pte. Ltd.\n");
printf("Barcode checker Ver 1.0\n");
while (k>=2000,k++)
{
//Scanner Input
for(i=0;i<ArrSize;i++)
{
scanf("%d",&arr[i]);
}
//Duplicate Logic
printf("Duplicate Barcodes: ");
for(i=0; i<ArrSize; i++)
{
for(j=i+1;j<ArrSize;j++)
{
if(arr[i]==arr[j])
{
printf("%d\n",arr[i]);
}
}
}
//Remove single duplicate
//Clear Screen
}
return 0;
}
The first problem with your code is this:
int i,j,k=1,...
...
while (k>=2000,k++)
^^^^^^
ups...
This will give the warning "left-hand operand of comma expression has no effect" which actually means that the line is the same as:
while (k++)
That will keep looping until you have integer overflow (which is undefined behavior). So you don't want to do that.
Since you initialize k to 1, I assume that you wanted to do:
while (k++ < 2000)
Now let's assume that you want:
while (k++ < 2000) // Will loop approx 2000 times
{
//Scanner Input
for(i=0; i< ArrSize; i++) // Will loop 2000 times
{
scanf("%d",&arr[i]);
}
So in the end your program calls scanf 2000 x 2000 = 4.000.000 times. Is that what you want? The purpose of the outer while is unclear.
Your program first reads 2000 integers and afterwards it seems you want to remove duplicates. That's a bad approach as you may end you doing a lot of memory move whenever you need to remove a duplicate element from the array.
A better approach is to check whether a newly scanned value is a duplicate before inserting it in the array. That could look something like:
for(i=0; i < ArrSize; )
{
int tmp;
if (scanf("%d", &tmp) != 1)
{
// Input error
exit(1);
}
// Check if tmp is already in the array
int duplicate = 0;
for (int j = 0; j < i; ++j)
{
if (tmp == arr[j])
{
duplicate = 1;
break;
}
}
if (duplicate)
{
printf("dup found\n");
}
else
{
arr[i] = tmp;
++i;
}
}
This should give you ArrSize unique elements.
Notice: In order to check if something is a duplicate, you'll need to scan through the array from start to the current number of elements. To improve performance you could consider another approach, e.g. a sorted tree, hash tables, etc so that check for duplicates can be done much faster. This gets more important as the number of array elements increase.
So half the problem is solved, I am still not sure how do I increase the pointer to the next position so on the next loop it will store another barcode number which will then be passed to the duplicate checker for checking then repeat the loop for the next scan.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i,j,k=1,arr[2000],counter=1;
//Welcome message
printf("Welcome to Yamato Transport (S) Pte. Ltd.\n");
printf("Barcode checker Ver 1.0\n");
while (k++ < 2000) // Will loop approx 2000 times
{
//Scanner Input
printf("Scan barcode\n");
for(i=0; i< counter; i++) // Will loop 1 time
{
scanf("%d",&arr[i]);
}
//check for duplicates
for(i=0; i < counter; )
{
int tmp;
if (scanf("%d", &tmp) != 1)
{
// Input error
exit(1);
}
// Check if tmp is already in the array
int duplicate = 0;
for (int j = 0; j < i; ++j)
{
if (tmp == arr[j])
{
duplicate = 1;
break;
}
}
if (duplicate)
{
printf("Duplicate Barcode\n");
}
else
{
arr[i] = tmp;
++i;
}
}
}
return 0;
}
I am taking input in an array of length 100 using scanf in a loop. After 20 numbers, if I enter -1, I want the loop to exit, i.e finish taking input and continue with the rest of the program. I am doing something like this
for(i=0;i<100;i++)
{
scanf("%d", &input[i]);
if(input[i] == -1)
{
break;
}
}
I heard, it is bad practice to use break statements even though this code works perfectly fine. So I was wondering what is a more efficient way to end the loop when -1 is entered. I tried
for(i=0;scanf("%d",&input[i])!=-1;i++)
also
fori(i=0;i<100;i++){
do
{scanf("%d", &input[i]);
}while(input[i]!=-1
}
Neither of these don't work
The second expression of the for loop is a free-form boolean expression. In this case you could add your condition there. However in this case it wouldn't look exactly nice. For example
for(i=0; i < 100 && (i < 1 || input[i - 1] != -1); i++)
{
scanf("%d", &input[i]);
}
I.e. if we have already input one value, check the value and that must be inequal to -1 for the loop to continue
Another would be to use a synthetic flag variable:
int loop_again = 1;
for (i = 0; loop_again && i < 100; i++) {
scanf("%d", &input[i]);
if(input[i] == -1)
{
loop_again = 0;
}
}
All in all, these both look way uglier than just using the break statement for the very thing that it was invented for.
Note that you also should check the return value of scanf itself!
it is bad practice to use break statements
As Ancient Greeks said, "Pan Metron Ariston", which means that everything that is used with balance is great. This applies here too, and your code as is, is good to go. The only thing to be worried about is not checking the return value of scanf().
Now if you really insist on changing your approach, then please refer to Haapala's answer, we got there first.
You can use a while loop and check for -1 in the input in the loop conditional. Note that you should always check the value returned by scanf(). In the posted code, non-numeric input results in no value being stored in input[]; this may lead to undefined behavior later if the code attempts to use an indeterminate value.
Here is an example. Note that the loop conditional first checks whether the array index has grown too large, then checks the return value from scanf() to be sure that a number was entered, then checks to see if -1 was entered. In the case of non-numeric input, the loop is terminated.
#include <stdio.h>
#define INPUT_SZ 100
int main(void)
{
int input[INPUT_SZ];
size_t i = 0;
while (i < INPUT_SZ && scanf("%d", &input[i]) == 1 && input[i] != -1) {
++i;
}
puts("You entered:");
for (size_t j = 0; j < i; j++) {
printf("%d\n", input[j]);
}
return 0;
}
Sample interaction:
2 4 6 8 -1
You entered:
2
4
6
8
You can simply change the value of counter variable to max, then it'll automatically come out of loop.
#include<stdio.h>
#define MAX 10
int main()
{
int ar[MAX], i, count;
for(i=0; i<MAX; i++)
{
scanf("%d", &ar[i]);
if(ar[i]==-1)
{
count=i--; //this is your new MAX. Not mandatory but will be useful if you need to access array elements
i=MAX;
}
}
//printing array
for(i=0; i<count; i++)
{
printf("Element %d: %d\t", i+1, ar[i]);
}
return 0;
}
Hope this helps.
Use a do-while loop
int i=0;
do{
if(scanf("%d", &input[i++]) != 1)
{
if(i>0)
--i; // Decrementing i if an integer is not provided
int ch;
while ((ch = getchar()) != '\n' && ch != EOF) // Wasting the buffer
;
}
}while(input[i-1] != -1 && i<=99);
I am creating a program where I insert a number of sentences and the program outputs them in order. I have finished the program, but when I run it it seems like the characters I input into the array aren't displayed or stored correctly, getting as a result random letters instead of the full sentence. Here is the code of the program:
char ch;
int i,j,k;
int nothing = 0;
int count = 1;
char lines[5][256];
int length[256];
int main() {
printf("Please insert up to a max of 5 lines of text (Press enter to go to next line and twice enter to stop the program):\n");
i = 0;
while (i<5){
j = 0;
ch = getche();
if (ch == '\r'){
if(i!= 0){
break;
}
printf("You have not inserted anything, please insert a line:");
i=-1;
}
if(ch != '\r'){
lines[i][j]=ch;
while (ch!='\r'){
ch = getche();
lines[i][j] = ch;
j++;
}
}
printf("\n");
i++;
}
for (k=i ; k > 0; k--){
printf("\tphrase %i :", count);
for ( j =0 ; j <= length[k]; j++){
printf("%c",lines[j][k]);
}
count++;
printf("\n");
}
return 0;
}
How can I get the characters to be stored and displayed correctly? Any help is appreciated, thank you!!
There are numerous problems with your code. I'll try and summarise here, and give you improved code.
Fist, some changes that I made to get this to compile on my system:
Changed getche() to getchar() (getche() does not appear to be available on Ubuntu).
I took out the section about re-entering a string, and just focused on the rest (since the logic there was slightly broken, and not relevant to your question). It will still check for at least one line though, before it will continue.
I had to change the check for \r to \n.
I changed your length array to size 5, since you'll only have the lengths of maximum 5 strings (not 256).
Some problems in your code:
You never updated the length[] array in the main while loop, so the program never knew how many characters to print.
Arrays are zero indexed, so your final printing loops would have skipped characters. I changed the for parameters to start at zero, and work up to k < i, since you update i after your last character in the previous loop. The same with j.
Your reference to the array in the printing loop was the wrong way around (so you would've printed from random areas in memory). Changed lines[j][k] to lines[k][j].
No need for a separate count variable - just use k. Removed count.
The nothing variable does not get used - removed it.
#include <stdlib.h>
#include <stdio.h>
char ch;
int i,j,k;
char lines[5][256];
int length[5];
int main()
{
printf("Please insert up to a max of 5 lines of text (Press enter to go to the next line and twice enter to stop the program):\n");
i = 0;
while (i<5)
{
j = 0;
ch = getchar();
if ((ch == '\n') && (j == 0) && (i > 0))
{
break;
}
if (ch != '\n')
{
while (ch != '\n')
{
lines[i][j] = ch;
j++;
ch = getchar();
}
}
length[i] = j;
printf("\n");
i++;
}
for (k = 0; k < i; k++)
{
printf("\tPhrase %i : ", k);
for (j = 0; j < length[k]; j++)
{
printf("%c", lines[k][j]);
}
printf("\n");
}
return 0;
}
I'm currently working on a program that scans each int and finds out if it is perfect or not. The problem is, I do not know how many ints there are in the input, so I want to find out how to stop scanning when the input ends.
Code:
#include <stdio.h>
int main() {
int input[500], count;
for (count = 0; count < 500; count++) {
scanf("%d", &input[count]);
if (input[count] == 0)
break;
}
for (count = 0; count < 500; count++) {
if (findFactors(input[count]) % input[count] == 0)
printf("%d perfect\n", input[count]);
else if (findFactors(input[count]) % input[count] <= 2 ||
findFactors(input[count]) % input[count] >= input[count] - 2)
printf("%d almost perfect\n", input[count]);
else
printf("%d not perfect\n", input[count]);
}
}
In this case, I need to enter 500 numbers for the code to run. I need it to run when the input is null. I know there is '/0' or something but I don't know how to use it in this code.
When you use a function read the doc
In return value
These functions return the number of input items successfully matched
and assigned, which can be fewer than provided for, or even zero in
the event of an early matching failure.
So you need to check the return value of scanf:
if (scanf("%d", &input[count]) != 1)
break;