Why infinite loop for input elements, bigger than single digit.
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Why infinite loop for input elements, bigger than single digit.
In the below code, want to display the elements in an array, in a format that there are two rows, and the first row is the element index; while the second row has the actual element. But, the second row elements are spaced by their size.
Issue arises of infinite loop, if the array elements are more than single digit big.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int *intvals = NULL; //array of integers
int **vals= NULL;//array of pointers
int total_elements;
if (isatty(fileno(stdin))) {
printf("How many elements in the array: ");
}
scanf("%d", &total_elements);
intvals = malloc(total_elements*sizeof(int));
vals = malloc(total_elements*sizeof(int *));
for(int i= 0; i<total_elements; ++i) {
vals[i]= &intvals[i];
scanf("%d", vals[i]);
}
for (int i=0; i<total_elements; ++i)
printf(" %d ", i);
printf("\n");
for (int i=0, j=0, no_of_spaces=0; i<total_elements; ++i){
//printf("%d:", i);
while((*(int *) vals[i])/10 >0) no_of_spaces++;
//printf("for %d, number of spaces : %d", *(int *) vals[i], no_of_spaces);
while(no_of_spaces)
{
printf(" ");
no_of_spaces--;
}
printf("%d", *(int *)vals[i]);
}
}
static int decimal_digits(long n, char *buff) {
int ndig= 0;
char *p;
char sign= 0;
unsigned long ntmp;
p= buff;
if (n>=0) {
ntmp= n;
} else {
ntmp= (ULONG_MAX - (unsigned long)n) + 1;
ndig += 1; /* only if you count '-' as a digit */
sign= '-';
}
do {
ndig += 1;
*p++ = '0' + ntmp%10;
ntmp /= 10;
} while (ntmp!=0);
if (sign) *p++ = sign;
*p= '\0';
strrev (buff);
return ndig;
}
This version not only counts the decimal digits, but also stores them into 'buff'. (Negative numbers are a bit problematic, make sure to test your code with -1 as well as LONG_MIN.)
Why an infinite loop? Because you have written an infinite loop of this form:
Code:
while( int_value>=10 )
do something;
Why only when the value is >=10? Fairly obvious.
Unable to understand that why only first inputted string is printed, though (before some trivial changes to the code) earlier all elements were printed.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int *intvals = NULL; //array of integers
int **vals= NULL;//array of pointers
int total_elements;
int spacing[total_elements];
if (isatty(fileno(stdin))) printf("How many elements in the array: ");
scanf("%d", &total_elements);
intvals = malloc(total_elements*sizeof(int));
vals = malloc(total_elements*sizeof(int *));
for(int i= 0; i<total_elements; ++i) {
vals[i]= &intvals[i];
scanf("%d", vals[i]);
}
for (int i=0, j=0, no_of_spaces=0; i<total_elements; i++, no_of_spaces=0){
j = *(int *) vals[i];
while(j) { no_of_spaces++; j = j/10; }
spacing[i]= no_of_spaces-1;
}
for (int i=0; i<total_elements; printf(" %d ", i), i++ )
for (int j =0; j<spacing[i]; j++)
printf(" ");
printf("\n");
for (int i=0; i<total_elements; ++i) printf(" %d ", *(int *) vals[i]);
}
The output is:
Code:
How many elements in the array: 3
1235
123
12
0
1235
static int decimal_digits(long n, char *buff) {
int ndig= 0;
char *p;
char sign= 0;
unsigned long ntmp;
p= buff;
if (n>=0) {
ntmp= n;
} else {
ntmp= (ULONG_MAX - (unsigned long)n) + 1;
ndig += 1; /* only if you count '-' as a digit */
sign= '-';
}
do {
ndig += 1;
*p++ = '0' + ntmp%10;
ntmp /= 10;
} while (ntmp!=0);
if (sign) *p++ = sign;
*p= '\0';
strrev (buff);
return ndig;
}
This version not only counts the decimal digits, but also stores them into 'buff'. (Negative numbers are a bit problematic, make sure to test your code with -1 as well as LONG_MIN.)
Please elaborate your code a bit more, else it would take much more time.
I suppose you want to count the number of decimal digits. The core of it is simply:
Code:
int ndig= 0;
do {
++ndig;
num /= 10;
} while (num!=0);
Please tell the purpose of your code line:
Code:
*p++ = '0' + ntmp%10;
My code intends for display purposes (will use a separate function, to be called whenever needed), a row of index, and the second row of array contents.
This would be used in conjunction with your earlier provided (& slightly embellished, by me) quicksort program, to display the first row of index, with spacing as prefix, so as to properly align with the second row, which is showing the contents.
This would be used to display the contents after each iteration.
That bit is not needed for digit-counting, it stores a '0'..'9' character into the buffer depending on the last decimal digit of the number.
Back to the formatting, you should check the 'width' part in 'printf(3)' manual, eg.
Unable to understand that why only first inputted string is printed, though (before some trivial changes to the code) earlier all elements were printed.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int *intvals = NULL; //array of integers
int **vals= NULL;//array of pointers
int total_elements;
int spacing[total_elements];
if (isatty(fileno(stdin))) printf("How many elements in the array: ");
scanf("%d", &total_elements);
intvals = malloc(total_elements*sizeof(int));
vals = malloc(total_elements*sizeof(int *));
for(int i= 0; i<total_elements; ++i) {
vals[i]= &intvals[i];
scanf("%d", vals[i]);
}
for (int i=0, j=0, no_of_spaces=0; i<total_elements; i++, no_of_spaces=0){
j = *(int *) vals[i];
while(j) { no_of_spaces++; j = j/10; }
spacing[i]= no_of_spaces-1;
}
for (int i=0; i<total_elements; printf(" %d ", i), i++ )
for (int j =0; j<spacing[i]; j++)
printf(" ");
printf("\n");
for (int i=0; i<total_elements; ++i) printf(" %d ", *(int *) vals[i]);
}
The output is:
Code:
How many elements in the array: 3
1235
123
12
0
1235
You need to compile with -Wall... again. You are using at least one uninitialized value which I have hilighted, so there is little point looking further until that is fixed.
No code change is so trivial that it does not need to be tested.
It seems to me that you tend to see only the overall program context, such as the original code and question, "Why infinite loop for input elements, bigger than single digit?", but do not expend much effort to look at the individual pieces inside (i.e. the actual loop code which is obviously incorrect).
I would suggest that you not try to write the whole program up front, then try to debug it.
Instead, think of each little function separately, write the code for each and test it in isolation so that you know what it must do and whether or not it does the desired thing correctly. Then put those pieces together into a more complete program.
For example, you want to print formatted output with aligned columns, so try to write a simplest function or code block to perform that specific task using fixed or constant data for testing. When you understand it and it works as desired, move on to the data input code using the same approach. When each piece is understood and working, put them together into an application.
You need to compile with -Wall... again. You are using at least one uninitialized value which I have hilighted, so there is little point looking further until that is fixed.
No code change is so trivial that it does not need to be tested.
It seems to me that you tend to see only the overall program context, such as the original code and question, "Why infinite loop for input elements, bigger than single digit?", but do not expend much effort to look at the individual pieces inside (i.e. the actual loop code which is obviously incorrect).
I would suggest that you not try to write the whole program up front, then try to debug it.
Instead, think of each little function separately, write the code for each and test it in isolation so that you know what it must do and whether or not it does the desired thing correctly. Then put those pieces together into a more complete program.
For example, you want to print formatted output with aligned columns, so try to write a simplest function or code block to perform that specific task using fixed or constant data for testing. When you understand it and it works as desired, move on to the data input code using the same approach. When each piece is understood and working, put them together into an application.
Thanks, but had no idea that only the first element of the array (i.e., spacing) would be picked up; if not specified the dimension of the array. Seems due to one pass compilation, C-language has this constraint. But, wouldn't there be garbage value for the variable: total_elements, rather than just containing the value = 1, each time the code is compiled & run (or might be it is specific to the www.onlinegdb.com compiler only); or is it that if the static array's dimension is un-specified, then only the first element is taken? Confused about that part.
Also, if the last line of the code below is changed to the one shown below, then the array contents are not displayed. The ordering of the two statements (i.e., '++i', & 'printf(" %d ", *(int *) vals[i])') in the 3rd part of the for-loop is important, but unclear as why that matters?:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int *intvals = NULL; //array of integers
int **vals= NULL;//array of pointers
int total_elements;
//int spacing[total_elements];
if (isatty(fileno(stdin))) printf("How many elements in the array: ");
scanf("%d", &total_elements);
int spacing[total_elements];
intvals = malloc(total_elements*sizeof(int));
vals = malloc(total_elements*sizeof(int *));
for(int i= 0; i<total_elements; ++i) {
vals[i]= &intvals[i];
scanf("%d", vals[i]);
}
for (int i=0, j=0, no_of_spaces=0; i<total_elements; i++, no_of_spaces=0){
j = *(int *) vals[i];
while(j) { no_of_spaces++; j = j/10; }
spacing[i]= no_of_spaces-1;
}
for (int i=0; i<total_elements; printf(" %d ", i), i++ )
for (int j =0; j<spacing[i]; j++)
printf(" ");
printf("\n");
for (int i=0; i<total_elements; ++i, printf(" %d ", *(int *) vals[i])) ; //the array contents are not printed out, but if the statement is changed to:
//for (int i=0; i<total_elements; ++i, printf(" %d ", *(int *) vals[i])); then correct (expected)
//output is obtained.
}
But, if have to print in each iteration of the for-loop, what is the error in including the printf() inside the 3rd part of the for loop?
If that is clear, then would understand.
But, if have to print in each iteration of the for-loop, what is the error in including the printf() inside the 3rd part of the for loop?
If that is clear, then would understand.
That's possible if unusual. But you have to listen to the order of the bits:
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.