just starting to learn c for loop - c

I am supposed to make a dice game that plays multiple times. I am not really looking for the answer, kind of looking to see what I am doing wrong. I would expect the for loop to assign the int i a value of 0, then run the dice rolls, then add one to i, until i is > 50. Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
main(){
int rollDie1, rollDie2, keyValue = 0, win = 0, lose = 0, reroll = 0, i;
srand(time(NULL)); // call this only once – seed the random generator
for (i = 0 ; i < 50 ; i++);
{
rollDie1 = rand() % 6 + 1; // in the range of 1 - 6
rollDie2 = rand() % 6 + 1; // in the range of 1 - 6
keyValue = rollDie1 + rollDie2;
if ( keyValue == 7 || keyValue == 11 )
{
printf ("Player wins on the first roll \n");
}
if ( keyValue == 2 || keyValue == 3 || keyValue == 12 )
{
printf("Sorry, you lost on the first roll \n");
}
if ( keyValue == 4 || keyValue == 5 || keyValue == 6 || keyValue == 8 || keyValue == 9 || keyValue == 10 )
{
printf("Reroll! \n");
}
}
system("pause");
}

There's a ; at the end of the for loop that shouldn't be there.
for (i = 0 ; i < 50 ; i++);
should be
for (i = 0 ; i < 50 ; i++)
otherwise there is nothing in the for-loop and what's in the {} will only be executed once, as that's a separate statement.

You have a semicolon at the end of the loop:
for (i = 0 ; i < 50 ; i++);
So it does nothing 50 times. You simply need to remove the semicolon so that your brackets {} will actually encapsulate the lines of your code that are supposed to be in the for loop. If you don't have an open bracket { immediately following a for loop, the first complete statement following the for loop will be executed at each iteration. The semicolon is a complete statement that does nothing.

Actually it will run as long as i<50 which is from 0 to 49

Related

Why is my program only printing my last number instead of all of the input numbers?

The problem I was given to solve is "The number of students who will take the exam is entered from the keyboard, and then the IDs of all the students who will take the exam are entered. The program should divide the students into three groups: students with IDs ending in the digits 0, 1, and 2, students with IDs ending in the digits 3, 4, 5, and students with IDs ending in the digits 6, 7, 8, 9 .The program should print the IDs for each group, in the same order as they were entered. The maximum number of students that can be entered is 1000.".
The code that I can come up with is
#include <stdio.h>
int main() {
int n,br,gr1,gr2,gr3;
scanf("%d",&n);
for (int i = 0; i < n; ++i) {
scanf("%d", &br);
if (br % 10 == 0 || br % 10 == 1 || br % 10 == 2)
{
gr1 = br;
}
else if (br % 10 == 3 || br % 10 == 4 || br % 10 == 5)
{
gr2 = br;
}
else if (br % 10 == 6 || br % 10 == 7 || br % 10 == 8 || br % 10 == 9)
{
gr3 = br;
}
}
printf("Grupa 1\n%d\n",gr1);
printf("Grupa 2\n%d\n",gr2);
printf("Grupa 1\n%d\n",gr3);
return 0;
}
Instead of printing all the IDs and sorting them into groups it is only printing the last input number and group number.
I am in no way an experienced programmer so I can't really tell what is wrong with the way I have written this or how to solve it. I would appreciate it if you can guide me through
The output I am expecting is:
Grupa 1
20010 20581 19452
Grupa 2
20145 19873 19825 20653
Grupa 3
20147 20139 19458
The output I am getting is
Grupa 1
19452
Grupa 2
20653
Grupa 3
19458
Your gr1,gr2,gr3 int variables can only store one values at a time (here, the last value that was assigned to it so its showing only one result.) Make them something like an array eg gr1[],gr2[],gr3[], which will be able to hold multiple values at a time and will be able to print them out at the end.
The way you format you code makes it harder for yourself to figure out what is going on. You need to stash in a data in an ordered data structure (array, linked list etc):
#include <stdio.h>
#include <stdlib.h>
#define MAX_STUDENTS 1000
typedef size_t student_id;
enum group {
GROUP_1 = 1,
GROUP_2,
GROUP_3
};
enum group group_student(student_id id) {
switch(id % 10) {
case 0: case 1: case 2:
return GROUP_1;
case 3: case 4: case 5:
return GROUP_2;
default:
return GROUP_3;
}
}
int main(void) {
student_id ids[MAX_STUDENTS];
size_t n = 0; // required below
for(; n < sizeof ids / sizeof *ids; n++) {
if(scanf("%zu", ids + n) != 1) {
break;
}
}
for(enum group group = GROUP_1; group <= GROUP_3; group++) {
printf("Grupa %d\n", group);
for(size_t j = 0; j < n; j++) {
if(group == group_student(ids[j]))
printf("%zu ", ids[j]);
}
printf("\n");
}
}
and here is an example run:
$ echo '20010 20581 19452 20145 19873 19825 20653 20147 20139 19458' | ./a.out
Grupa 1
20010 20581 19452
Grupa 2
20145 19873 19825 20653
Grupa 3
20147 20139 19458
When you type this in, end input with ctrl-D. I used a enum group here as it's an identifier (not a number) and documents by virtue of the return type that you change the enum you want to change the function group_student(), too.

for loop is only printing last iteration

I am trying to write a C program that takes a string input from a user and then looks into the input to count the frequency of all the integers in the string. So suppose if the user gives the input:
a11472o5t6
the output would be :
0 2 1 0 1 1 1 1 0 0
my approach involves comparing every character of the string to all 10 digits one by one and if any the character is equal to the digit, it would increment the isdigit number by 1.
the code I wrote for the same is as follows:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int is1 = 0; //initialise integers for checking
int is2 = 0;
int is3 = 0;
int is4 = 0;
int is5 = 0;
int is6 = 0;
int is7 = 0;
int is8 = 0;
int is9 = 0;
int is0 = 0;
int main()
{
char s[100]; //initialise array for string
scanf("%s", s); //scan string input
//now all characters of the string are stored in the array s
for (int i = 0; i < strlen(s); i++) //loop to iterate over all the elements in the array
{
if (strcmp(&s[i], "0") == 0)
{
is0 = is0 + 1;
}
if (strcmp(&s[i], "1") == 0)
{
is1 = is1 + 1;
}
if (strcmp(&s[i], "2") == 0)
{
is2 = is2 + 1;
}
if (strcmp(&s[i], "3") == 0)
{
is3 = is3 + 1;
}
if (strcmp(&s[i], "4") == 0)
{
is4 = is4 + 1;
//printf("%d", is4);
}
if (strcmp(&s[i], "5") == 0)
{
is5 = is5 + 1;
}
if (strcmp(&s[i], "6") == 0)
{
is6 = is6 + 1;
}
if (strcmp(&s[i], "7") == 0)
{
is7 = is7 + 1;
}
if (strcmp(&s[i], "8") == 0)
{
is8 = is8 + 1;
}
if (strcmp(&s[i], "9") == 0)
{
is9 = is9 + 1;
}
}
printf("%d ", is0);
printf("%d ", is1);
printf("%d ", is2);
printf("%d ", is3);
printf("%d ", is4);
printf("%d ", is5);
printf("%d ", is6);
printf("%d ", is7);
printf("%d ", is8);
printf("%d ", is9);
}
I expected the code to iterate over and over for the entire length of the string and and update values of the isdigit series every time a number was successfully found. However whenever I run the code only the last digit seems to find its place in the output .
for example if I type 54 as an input the expected output is
0 0 0 0 1 1 0 0 0 0
however the output my code seems to be giving is
0 0 0 0 1 0 0 0 0 0
likewise the number 45 also has the same expected output
0 0 0 0 1 1 0 0 0 0
but the output I am receiving is
0 0 0 0 0 1 0 0 0 0
which looks like the code overwrites any operation that occurred in the previous iteration, but I can't seem to understand why and how to fix it.
On my part I checked if the characters were being called properly one by one and that all characters were being compared, where I found no problem. I also looked up other answers on stack overflow and elsewhere, but was I am a beginner and most answers were written in reference to languages that I can't understand, so I was unable to relate to the solution they were being told. the closest I got was someone who was using a single variable repetitively thus overwriting it in each iteration. however I have declared sufficient variables( one for each digit from 0-9), so that shouldn't be the problem in my code either.
while I know this question could be solved easily using arrays, I would like to know what I was doing wrong here to avoid any such mistakes in the future.
When you do if (strcmp(&s[i],"1")==0) you are comparing strings, not individual characters, which is why only the last character is counted. It's the only one matching.
Example:
If s == "a11472o5t6" and you use strcmp(&s[1], "1"), you would be comparing the string "11472o5t6" with the string "1", which clearly will not be equal.
You want if(s[i] == '1') etc. to do the comparisons of individual characters instead.
And you are correct about using arrays instead. It'd certainly be easier.
Example:
#include <ctype.h>
#include <stdio.h>
int main() {
const char *str = "a11472o5t6";
int ints[10] = {0};
for (const char *chptr = str; *chptr != '\0'; ++chptr) {
if(isdigit((unsigned char) *chptr)) ++ints[*chptr - '0'];
}
for (int i = 0; i < 10; ++i) printf("%d %d\n", i, ints[i]);
}
Output:
0 0
1 2
2 1
3 0
4 1
5 1
6 1
7 1
8 0
9 0

put first array index at the end of array

I have an array called int arr[10] = {1,2,3,4,5}
From my understanding the rest of the array is filled with 0's.
My questions is if its a fixed array length how can I put the first index behind the last index that is not a 0. For example
I believe the 0 is not shown in real printf but I am including it for illustration purposes
for (int i = 0 ; i < 10 ; i++)
{
print("%i" , arr[i]);
}
The output
1 2 3 4 5 0 0 0 0 0
If i move the first index to the back of the 5 like so
for (int i = -1 ; i < 10 ; i++)
{
arr[i] = arr[i + 1];
print("%i" , arr[i]);
}
Will the output put the 1 behind the 5 or at the back of the whole array?
2 3 4 5 1 0 0 0 0 0
or because there is 0s then
2 3 4 5 0 0 0 0 0 1
If my question is unclear please tell me and I will try explain it.
The output
1 2 3 4 5 0 0 0 0 0
No, the actual output is
1234500000
Your code has undefined behavior. The first iteration of the loop (with i = -1) tries to assign to arr[-1], which does not exist:
arr[i] = arr[i + 1];
Similarly, the last iteration (with i = 9) tries to read from arr[10], which also does not exist.
I'm not sure why you think your code will move the first element back.
From my understanding the rest of the array is filled with 0's
You are right.:)
If i move the first index to the back of the 5 like so
for (int i = -1 ; i < 10 ; i++)
{
arr[i] = arr[i + 1];
print("%i" , arr[i]);
}
then you will get undefined behavior because the indices -1 and 10 are not valid indices.
It seems what you are trying to do is the following
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 10 };
int a[N] = { 1, 2, 3, 4, 5 };
size_t pos = 0;
while ( pos < N && a[pos] != 0 ) ++pos;
if ( pos != N && !( pos < 3 ) )
{
int tmp = a[0];
pos -= 2;
memmove( a, a + 1, pos * sizeof( int ) );
a[pos] = tmp;
}
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
return 0;
}
The program output is
2 3 4 1 5 0 0 0 0 0

C For Loop Comparison Using Function Doesn't Wait

This is kind of strange, imo, I have a for loop that does a comparison
using the return value from a function.
for (size_t i = 0; i < func(val); i++) {
printf("Value from array modified in func = %u", values[i]);
}
The issue is the loop seems to run before the function is finished, if have a printf in the called function some output occurs before the output of the loop, expected, and some after, not expected. The function is only called in the for loop comparison so output should all happen before for loop's output. If I use a var instead such as:
size_t temp = func(val);
for (size_t i = 0; i < temp; i++) {
printf("Value from array modified in func = %u", values[i]);
}
Then everything works correctly, this is rather odd to me, I'm not using threads so this should all be synchronus right? So why would the loop not wait for func(val) to return?
Here's the original code (cutting out a bunch of comments):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdlib.h>
#define SUITS 4
#define FACES 13
#define CARDS 52
#define HAND 5
typedef struct {
unsigned int suit;
unsigned int face;
} card;
size_t checkX(card hand[HAND], unsigned int faces[HAND], unsigned int num);
int main() {
card hand[HAND] = {{1,1},{1,7},{1,1},{1,4},{1,7}};
const char *suit[SUITS] = {"Hearts", "Diamonds", "Clubs", "Spades"};
const char *face[FACES] = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"};
unsigned int matchingFaces[HAND] = {0};
for (size_t i = 0; i < checkX(hand, matchingFaces, 2); ++i) {
printf("Pair of %s%s\n", face[matchingFaces[i]], matchingFaces[i] == 5 ? "es" : "s");
}
}
size_t checkX(card hand[HAND], unsigned int faces[HAND], unsigned int num) {
size_t facePos = 0;
for (size_t i = 0; i < HAND - 1; i++) {
size_t count = 1;
for (size_t j = i + 1; j < HAND; j++) {
printf("%u == %u && %u != %u\n", hand[i].face, hand[j].face, hand[i].face, faces[facePos]);
if (hand[i].face == hand[j].face && hand[i].face != faces[facePos]) count++;
}
faces[facePos] = hand[i].face;
if (count == num) facePos++;
}
return facePos;
}
Some of this isn't my code, I was given a basic card shuffling type of program and told to modify it to deal a hand and check for pairs/three of a kind. Like I said this does work when I set the return value of checkX as a variable and then compare i to that instead of directly, I just don't know why. I've tried disabling gcc optimization, which didn't seem to make a difference.
Output from direct func comparison:
1 == 7 && 1 != 0
1 == 1 && 1 != 0
1 == 4 && 1 != 0
1 == 7 && 1 != 0
7 == 1 && 7 != 0
7 == 4 && 7 != 0
7 == 7 && 7 != 0
1 == 4 && 1 != 0
1 == 7 && 1 != 0
4 == 7 && 4 != 1
Pair of Deuces
1 == 7 && 1 != 1
1 == 1 && 1 != 1
1 == 4 && 1 != 1
1 == 7 && 1 != 1
7 == 1 && 7 != 1
7 == 4 && 7 != 1
7 == 7 && 7 != 1
1 == 4 && 1 != 7
1 == 7 && 1 != 7
4 == 7 && 4 != 1
Output from indirect comparison of func using variable:
1 == 7 && 1 != 0
1 == 1 && 1 != 0
1 == 4 && 1 != 0
1 == 7 && 1 != 0
7 == 1 && 7 != 0
7 == 4 && 7 != 0
7 == 7 && 7 != 0
1 == 4 && 1 != 0
1 == 7 && 1 != 0
4 == 7 && 4 != 1
Pair of Deuces
Pair of Eights
I know this code isn't the nicest but I had to work with what was given and just need to make it work, so this question is just out of curiosity.
for (size_t i = 0; i < func(val); i++) {
printf("Value from array modified in func = %u", values[i]);
}
func(val) gets called multiple times here, each time a decision needs to be made whether to continue the loop or not, you can picture it as
size_t i = 0;
if (i < func(val)) {
printf(.....);
i++;
if (i < func(val)) {
printf(.....);
i++;
if (i < func(val)) {
printf(.....);
i++;
if (i < func(val)) {
printf(.....);
i++;
....and so on......
}
}
}
}
So you can see, func(val) may get called multiple times.
A rather good, but a little out of date, section of the great book "The C Programming Language", by Kernighan and Ritchie, re-state a for loop to the equivalent:
{
size_t i = 0;
while (i < func(val)){
printf("Value from array modified in func = %u", values[i]);
i++;
}
}
(The outer braces are mine and are necessary since you can now declare a variable inside the first "expression" in the for loop.)
If you write the loop this way, it's plain to see that func(val) is re-evaluated on each iteration. That is what is causing the effects you observe. (Note that not all languages do this, VBA and VB6 are two examples where the end condition of the for loop is not re-evaluated.)
Because of this, if func(val) is an expensive function and your algorithm doesn't require repeated evaluation, you might want to consider pre-computing the value in advance. Some compilers may optimise out the re-evaluation especially if you are using a standard function like strlen for example, but such an optimisation is a very tricky science.

Looking for faults in algorithm for organizing a one-way railway station traffic

I wrote the code below for solving this railway station traffic programming contest question. ( You may read comments and proposed solutions here). However, there are a few exceptional cases for which this code won't work. What are they?
#include <stdio.h>
#include <stdlib.h>
int main(){
int n, i,j;
int * array;
scanf("%i",&n);
array = malloc(sizeof(int) * n);
for(i=0;i<n;++i) scanf("%i",&array[i]);
for(i=0;i<n;++i){
if(i+1 == array[i]) array[i] = -1;
else{
if(array[i] < i+1){
for(j=0;j<i;++j){
if(array[i] == j+1){
if(array[j] == -1){
printf("No\n");
return 0;
}
else array[i] = array[j] = -1;
}
}
}
}
}
for(i=0;i<n;++i) if(array[i] != -1) break;
if(i == n) printf("Yes\n");
else printf("No\n");
return 0;
}
P.S.: I'm assuming this program takes one entry at each time ( rather than waiting for an 0 for signaling the end of input ).
What this code is supposed to do:
1) I'm assuming you've already read what's in this link.
2) After copying a sequence into an array, we must verify whether or not this sequence is valid.
So we use the following algorithm:
Iterate over the sequence, starting from the first element.
If element = element's index + 1 ( because C lists are zero-indexed ), then element = -1.
Otherwise, if and only if element < element's index: We look for a previous element for which ( current element == previous' element index + 1 ) is valid. If this element is found, then now both current element and previous element are changed to -1. If previous element has already been changed before ( that is, it's already -1 ) then this is not a valid sequence.
If after iterating over the list like this any elements are still left, this is not a valid sequence.
Examples:
Example 1
Array: 5 4 3 2 1
5 : 5 > 0 + 1, skip. 4: 4 > 1 + 1, skip. 3: 3 == 2 + 1. Then 3 -> -1.
Array: 5 4 -1 2 1
2 : 2 < 3 + 1. 4 has an index of 1 and 1 + 1 = 2.
Array: 5 -1 -1 -1 1
1: 1 < 4 + 1. 5 has an index of 0 and 0 + 1 = 1.
Array: -1 -1 -1 -1 -1
Therefore this sequence is valid.
Example 2
Array: 5 4 1 2 3
5: 5 > 0 + 1, skip. 4: 4 > 1 + 1, skip. 1: 1 < 2 + 1. 5 has an index
of 0.
Array: -1 4 -1 2 3
2: 2 < 3 + 1. 4 has an index of 1.
Array: -1 -1 -1 -1 3
3: 3 < 4 + 1. -1 ( at position 2 ) has an index of 2. 2 + 1 = 3.
Therefore the sequence is not valid.
Here is an example of an input where your code will give the wrong output:
5
3 4 2 5 1
Your description gave a translation of the code in English, but did not give insight into why that algorithm would solve the problem. So, I just went for a solution where an extra array is used for keeping track of the carriages that are in the station, which will have to function like a stack (First-in-last-out):
#include <stdio.h>
#include <stdlib.h>
int main(){
int n, i;
int carriageAtA = 1;
int * array;
int * station;
int stationSize = 0;
// Read input
scanf("%i",&n);
array = malloc(sizeof(int) * n);
station = malloc(sizeof(int) * n);
for(i=0;i<n;++i) scanf("%i",&array[i]);
// Iterate the desired carriages in sequence
for(i=0;i<n;++i) {
// While the last one in the station is not what we need:
while ((!stationSize || station[stationSize-1] != array[i]) && carriageAtA <= n) {
printf("Move %i from A to station\n", carriageAtA);
// Last carriage in station B is not what we need, so pull one in from A:
station[stationSize] = carriageAtA;
stationSize++; // There is now one more carriage in the station
carriageAtA++; // This is the next carriage at A
}
if (!stationSize || station[stationSize-1] != array[i]) {
// Could not find desired carriage at A nor at station. Give up.
printf("No\n");
return 0;
}
// Drive last carriage at station to B:
printf("Move %i from station to B\n", array[i]);
stationSize--;
}
printf("Yes\n");
return 0;
}
The additional printf calls are just for getting a view of the process. Remove them when you are satisfied.

Resources