Why does while loop sometimes exit before exit condition is met? - c

I need to create a string of variable length composed of random characters, so I built a function that does just that, however, after executing it a few times I noticed that the while loop stops executing even though the condition is still not met at first I had (j < taille) but then I changed it to (j <= taille ) but I still have the same problem , sometimes it doesn't execute normally
here's my code:
void gener_observation(char num[b])
{
int taille,i,j;
srand(time(NULL));
taille = (rand()%(b-40)) + 1;
j=0;
i=0;
while(j <= taille)
{
i = ((rand()%26) + 65 );
num[j] = i;
j++;
}
}

Turn your code into this:
void gener_observation(char num[b])
{
int taille,i,j;
srand(time(NULL));
taille = (rand()%(b-40)) + 1;
j=0;
i=0;
printf("The value of taille equals [%d]", taille);
while(j <= taille)
{
printf("Currently, j equals [%d]", j);
i = ((rand()%26) + 65 );
num[j] = i;
j++;
}
printf("Finished");
}
... and run your code again. As your code contains a random number, it might be different for all of us, but using the printed results, you might find out the problem you're having.

Related

How to stop the loop after printing one?

So here is the problem: Write a program that accept an integer n, print out the largest number but smaller or equal n that is the product of two consecutive even number. Example: Input: 12, Output: 8 ( 2x4 )
Here is my code :
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d ", i);
break;
}
}
}
return 0;
}
So if i input 20, it will print out 8 and 0 instead of 8, if i input 30, it will print out 24,8 and 0 instead of just 24. How do i make it stop after printing out the first number that appropriate ?
You need to stop an outer loop from processing, for example by using a boolean flag (meaning "solution found, we finish work") or a goto statement.
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int solutionFound = 0;
for (int i = n; i >= 0; i--) {
// this could also be put into for's condition i.e. "i >= 0 && !solutionFound"
if (solutionFound) {
break;
}
for (int j = 0; j <= n; j = j + 2) {
if ( i == j * (j+2) ) {
printf("%d ", i);
solutionFound = 1;
break;
}
}
}
return 0;
}
EDIT: immediate return as noted in the comments is also a nice idea, if you don't need to do anything later.
Your problem is that you are nested - in a for loop which is inside another for loop - when you want to stop processing.
Some languages would let you code break 2; to indicate that you want to break out of 2 loops. Alas, C i snot such a language.
I would recommend that you code a function. That would serve a few porpoises: 1) your main should be "lean & mean" 2) as your programs get larger, you will learn the benefits of putting individual coding tasks into functions 3) you can use return; instead of break; and it will exit the function immediately.
Something like this:
#include <stdio.h>
void FindNeighbouringDivisors(int n)
{
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d times %d = %d", j, j + 2, i);
return;
}
}
}
printf("There are no two adjacent even numbers which can be multiplied to give %d", n);
}
int main()
{
int n;
scanf("%d", &n); /* could get from comamnd line */
FindNeighbouringDivisors(n);
return 0; /* should be EXIT_SUCCESS */
}
Btw, when you have a problem with your code, ask a question here. When you have it working, consider posting it at our code review site where more experienced programmers can give you advice on how to improve it. It's a great way to learn
Break only breaks you out of immediate loop, so either use flags or just use return to terminate the execution. Or you can even use following code:
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int j = 0; j <= n; j = j + 2)
{
if ( n < j * (j+2) )
{
printf("%d ", j*(j-2));
break;
}
}
return 0;
}

CS50 mario pyramid upside down can't figure why

I thought long and hard before asking this in here but I've spent too much time now trying to figure this one out without cheating.
The CS50 mario ps1 (less comfortable) asks for a *simple left align (at first) pyramid, but my code is giving me it upside down and I can't figure why.
#include <cs50.h>
#include <stdio.h>
int main (void)
{
int n;
do
{
n = get_int("Pyramid Height: ");
}
while (n < 1 || n > 8);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - i ; j++)
printf("#");
for (int j = 0; j < n - i; j++)
{
printf(" ");
}
printf("\n");
}
}
I'm sorry if this type of questioning shows up regularly here but I really do need your help.
Thanks in advance.
edit:
expected result:
........#
.......##
......###
.....####
....#####
...######
..#######
.########
I can change the dots to spaces afterwards, this is just for visualisation;
the restriction for height is 8, so I guess that each line has always eight characters;
I actually added trailing spaces so that the pyramid could be right aligned, I've metioned wrong before;
I'm going to check the How to debug small programs?;
Sorry, I'm new to this, I didn't know there was a difference between here and stack exchange, gonna look into that.
*Sorry for the "meh" english, it is not my native language.
See what is the difference between my and your code (especially how to count):
void draw(int n, int align, int dir)
{
for (int i = 1; i <= n; i++)
{
if(align)
{
for(int s = 0; s < (dir ? (n - i) : i - 1); s++)
{
printf(" ");
}
}
for (int j = 0; j < (dir ? i : (n - i + 1)) ; j++)
{
printf("#");
}
printf("\n");
}
}
int main (void)
{
draw(8,1,0);
printf("\n");
draw(8,1,1);
printf("\n");
draw(8,0,0);
printf("\n");
draw(8,0,1);
}
https://godbolt.org/z/7YT16j
my code is giving me it upside down and I can't figure why
Let's see what the code looks like
// There's a loop executed n times. The body prints a line, so n lines are printed.
// In case you have doubts, the characters are normally printed top to bottom and
// left to right.
for (int i = 0; i < n; i++)
{
// The following loop prints (n - i) characters '#' at the beginning
// of each line. That's NOT what you are supposed to do, kind the opposite.
for (int j = 0; j < n - i ; j++)
printf("#");
// You should first print the spaces, then the '#'s, starting from 1 '#' at
// the first line and increasing the number by one at each line (so you have
// to change the condition in the loop accordingly).
// This loop prints the right amount of spaces, but only after
// all the '#'s and just before the end of the line, so that you just
// can't see them (change the printed char to '.' to visualize those).
for (int j = 0; j < n - i; j++)
{
printf(" ");
}
// Note that you could use putchar('\n'), here and previously, to print
// only one char, instead of using printf() to print string literals.
printf("\n");
}

Trying to print 10 lines of 100 array values in C

I have an array with 100 numbers in it, and I am trying to print it out with only 10 ints on each line, and a tab between each number. It is only printing the first 10 integers and then stopping, which makes sense because of my for loop. I am clearly missing part of it to allow for it to continue through the array. I was going to try to add the line
for(int line_num = 0; line_num < 10; line_num+=10)
before the for statement after the while loop
int array_value;
int length_of_array = 100;
while (length_of_array <= 100){
for(array_value = 0; array_value < 10; ++array_value){
printf("%d ", A[array_value]);
++length_of_array;
}
I was also thinking of including a line like
if (array_value % 10 == 0)
printf("\n");
I figured it out! Posted the answer below.
This might be what you're looking for:
/* test.c */
#include <stdio.h>
#define ELEMENTS 100
int main (void)
{
int array [ELEMENTS];
for ( int i = 0; i < ELEMENTS; ++i )
array [i] = i;
for ( int i = 0; i < ELEMENTS; ++i ) {
printf ("%i", array[i]);
if ( (i + 1) % 10 != 0 )
printf ("\t");
else
printf ("\n");
}
return 0;
}
edit: Because of the way the tab can extend to the next line at the end of the line you have to be careful with the tab and new line character.
For clarity, rename length_of_array to offset_in_array and then set it to zero at the start. I renamed array_value and corrected your length check. I also added a check to the inner loop in case the array length gets changed and doesn't divide by 10.
Something like:
int i;
#define ARRAY_LENGTH 100
int offset_in_array = 0;
while (offset_in_array < ARRAY_LENGTH){
for(i = 0; i < 10 && offset_in_array < ARRAY_LENGTH; ++i){
printf("%d ", A[offset_in_array]);
++offset_in_array;
}
}
I haven't tried running this but it should be closer.
Just print a newline every tenth number... If it's not a tenth number, then print a tab.
for (size_t i = 0; i < array_length; ++i) {
printf("%d%c", A[i], i % 10 != 9 ? '\t' : '\n');
}
Live code available at onlinedbg.
Just change the value of length_of_array to 0 and print \n after a for loop.
int array_value;
int length_of_array = 0;
while (length_of_array <= 100) {
for(array_value = 0; array_value < 10; ++array_value){
printf("%d ", A[array_value]);
++length_of_array;
}
printf("\n");
}
You can use the following solution to print 10 lines of 100 array values in C:
for (int i = 0; i < 100; ++i){
printf("%i\t", A[i]);
if ((i+1)%10 == 0){
printf("\n");
}
}

Continue computation in do while even if no columns exist

What I am trying to do (not very successful) is if my code detects a signal (if(matrix[i][j] ==1)) coming (1 or 0) for the next few steps I want my code to write in a new matrix: newmatrix[i][j]=10 and if not to continue with 0. Here is my code so far:
for (i = 0; i < rows; i++) {
j = 0;
do {
if (matrix[i][j] == 1) {
int m = j;
while (j < m + 3) {
newmatrix[i][j] = 10;
printf("newmatrix[%i][%i] and %f\n", i, j, newmatrix[i][j]);
j++;
continue;
}
}
if (matrix[i][j] == 0) {
newmatrix[i][j] = 0;
printf("newmatrix[%i][%i] and 0 is %f\n", i, j, newmatrix[i][j]);
j++;
continue;
}
j++;
} while (j < MAXTIME);
}
}
The problem is that if there is a signal near the end instead of stopping when to column count reaches the max number the code inserts new columns even though they are only 10:
Where is my mistake can someone point me to the right direction? Is there maybe a way to do this cleaner with goto statement?
Here is a simpler approach with a temporary variable:
for (i = 0; i < rows; i++) {
int spike = 0;
for (j = 0; j < MAXTIME; j++) {
if (matrix[i][j] == 1) {
spike = 3;
}
if (spike) {
newmatrix[i][j] = 10;
spike--;
} else {
newmatrix[i][j] = 0;
}
printf("newmatrix[%i][%i] is %f\n", i, j, newmatrix[i][j]);
}
}
Notes:
I am assuming that matrix[i][j] is either 0 or 1. If other values are possible and newmatrix[i][j] should stay unmodified for these cells, the code should be modified.
It is advisable to only modify a loop index in the for update clause. do / while loops are notoriously error prone, especially with nested loops that also modify the loop index as is the case in your code.

C, Showing count of repeating symbols

Need to figure out a code that counts all the repeating symbols in a string. As you can see below, so far so good.
And here starts the tricky part, at the end of the code I want to output symbols in an order they were typed which had for example 2 occurences in a string, and I got problems figuring that out.
int counts[256] = { 0 };
int i;
size = strlen(text);
for (i = 0; i < size; i++) {
counts[(int)(text[i])]++;
}
for (i = 0; i < 256; i++) {
printf("The %d. character has %d occurrences.\n", i, counts[i]);
}
Just iterate through the source string again and for each character look into your counts array.
If you don't want to print the same statistics for every occurence of repeating character, you can reset the corresponding counts value to zero just after you print the statistics, and have an additional check before printing.
for(i = 0; i < size; i++) {
if(counts[(int)(text[i])] == 2)
printf("%d", (int)(text[i]));
The first line loops through your source string for the order of occurences.
The second line checks if it was captured in the counts array as occuring only twice.
If it was we print the char code on the third line.
To only print the character once:
for(i = 0; i < size; i++) {
if(counts[(int)(text[i])] == 2) {
printf("%d", (int)(text[i]));
counts[(int)(text[i])] = 0;
}
}
Here is an implementation of Inspired's answer:
int counts[256] = { 0 };
char text[] = "Hello, world!";
int i, size = strlen(text);
for (i = 0; i < size; i++)
{
counts[(unsigned int)(text[i])]++;
}
for (i = 0; i < size; i++)
{
if (counts[(unsigned int)text[i]] > 1)
{
printf("%c", text[i]);
counts[(unsigned int)text[i]] = 0; // Remove to print repeats.
}
}
Make a key,count pair, like:
#include <string.h>
#include <stdio.h>
int main()
{
char* text = "count this text";
char *keys = new char[strlen(text)];
int* count = new int[strlen(text)];
int last = 0; int j=0;
for(int i=0; i<strlen(text); i++){
for(j=0; j<last; j++){
if(keys[j]==text[i]) break;
}
if(keys[j]==text[i]){
count[j]++;
} else {
keys[last]=text[i];
count[last]=1;
last++;
}
}
for(int i=0; i<last; i++){
printf("%c %d\n", keys[i], count[i]);
}
}
so you keep the order in the text and get the count.
On execution the output is:
c 1
o 1
u 1
n 1
t 4
2
h 1
i 1
s 1
e 1
x 1

Resources