for-loop left after one iteration - c

I'm encountering this problem and I don't get why. I used the exact same loop before to test it (without inside code) and it worked. I'm not a programming newbie (though c newbie), but now I definitely feel like one. I replaced length with a hard coded number, doesn't change anything. jobStatus() also only uses a for-loop which works fine. Help is appreciated!
PS: Don't mind the if / else-if part. This was just a desperation move because I cant find the problem, I know that I don't need the last else if etc.
thanks in advance
#include <stdio.h>
#include <stdlib.h>
short jobs[] = {6,13,7,3,4,9,10,11};
short table[13][10];
short Q,i,j,k,diff;
short sum;
void jobStatus(short a){
printf("Jobstatus:");
for(i=0;i<a;i++){
printf(" %i",jobs[i]);
} printf("\n");
}
int main(){
// berechne Anzahl der Jobs
short length = sizeof(jobs)/2;
printf("Jobs: %i\n", length);
/* für alle Quanten Q
for(Q=0;Q<13;Q++){
// schreibe das jeweilige Quantum in die erste Spalte jeder Zeile
table[Q][0]=(Q+1);
gehe jeden Job durch*/
for(i=0;i<length;i++){
printf("Current Job: %i\n", i);
/* falls der aktuelle job i bereits erledigt ist überspringe ihn
if(jobs[i]==0){
i++;
}*/
diff=jobs[i]-(Q+1);
if(diff>0){
jobs[i]=diff;
jobStatus(length);
table[Q][i+1]=diff;
} else if(diff==0){
jobs[i]=0;
} else if(diff<0){
diff=diff*(-1);
jobs[i]=0;
table[Q][i+1]+=diff;
}
}
printf("# Q P1 P2 P3 P4 P5 P6 P7 P8 Avg.Time\n");
printf("#------------------------------------\n");
for(Q=0;Q<13;Q++){
for(i=0;i<8;i++){
printf(" %i", table[Q][i]);
}
printf("\n");
}
return 0;
}
This is the output:
Jobs: 8 // Indicates that length should be set to 8
Jobstatus: 5 13 7 3 4 9 10 11
Q P1 P2 P3 P4 P5 P6 P7 P8 Avg.Time
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

You have only a global variable i which is used in both for loops (inside jobstatus and in your main). Thus once you call jobstatus(length); within your main loop the content of the variable will be changed and afterwards the loop terminates (because i was then set to length).

You are using global variable i. It is changes inside jobStatus and for-loop in main.
Try to use local inside main()

I agree with Howard, but I think that sizeof(jobs) it's wrong. You should write something like (sizeof (jobs))/(sizeof (jobs[0])) or instead use count() function.

Related

Find all possible knight move on chess board within the limit, with recursion, C language

So I tried to make a program that shows you all the possible knight moves within the limit, the possible move marked with the number '1'. but when I run the program with a movement limit more than 2, it's kind of messed up. what did I do wrong?
#include<stdio.h>
int xpos[8]={2,1,-1,-2,-2,-1,1,2};
int ypos[8]={1,2,2,1,-1,-2,-2,-1};
void whiteMove(int wx, int wy,int map[8][8],int limit);
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
int map[8][8]={{0}};
int limit; char k1[3];
scanf("%d",&limit);getchar();
scanf("%s",k1);getchar();
int wx=k1[0]-'A';
int wy='8'-k1[1];
printf("Case #%d: \n",i+1);
whiteMove(wx,wy,map,limit+1);
for(int j=0;j<8;j++){
for(int k=0;k<8;k++){
printf("%d ",map[j][k]);
}
puts("");
}
}
return 0;
}
void whiteMove(int wx, int wy,int map[8][8], int limit){
if(wx<0||wy<0||wx>7||wy>7||limit==0){
return;
}else if(map[wy][wx]!=1){
map[wy][wx]=1;
}else{
return;
}
for(int i=0;i<8;i++){
whiteMove(wx+xpos[i],wy+ypos[i],map,limit-1);
}
}
input example:
1 => the amount of test case
3 => movement limit
A1 =>starting coordinate
th result is
Case #1:
0 0 0 0 0 0 0 0
0 1 0 1 0 0 0 0
1 0 1 0 1 0 0 0
1 1 1 0 0 1 0 0
1 0 1 1 1 0 0 0
*0 1 0 1 0 1 0 0 *map[5][0]
1 0 *1 1 1 0 0 0 *map[6][2]
1 1 1 0 *0 1 0 0 *map[7][4]
as you can see theres some place that should be '1' but for some reason is not, for example:
map[5][0] and map[7][4] should be '1' because map[6][2] is '1', i dunno whats the problem with my code but my asumption is maybe the coordinate is visited twice, but i already make limitation about the coordinate, so i dont know wheres the problem.
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0
1 1 0 0 1 0 0 0
0 0 1 1 0 0 0 0
1 0 1 0 1 0 0 0
this is the result when the movement limit is 2.
as you can see map[5][0] and map[7][4] is '1' as it should be.
any help will be apreciated, thank you
what did I do wrong?
Stopping, when recursion should go on.
else if (map[wy][wx] != 1) { and map[wy][wx] = 1 are problems.
The test map[wy][wx] != 1 is simple asking, have I been here before? But that is not enough.
The test should be have I been here before in less moves?
If during the tour, it is possible to get to a square in fewer moves, then the recursion from that point needs to go deeper, even though the square has been visited.
Two changes I made help see this, but do not solve it. Leave that for OP. (Note there are many ways to solve this.)
if (wx < 0 || wy < 0 || wx > 7 || wy > 7 || limit == 0) {
return;
// } else if (map[wy][wx] != 1) {
} else if (map[wy][wx] == 0) {
// map[wy][wx] = 1;
map[wy][wx] = limit;
} else {
return;
}
Case #1:
0 0 0 0 0 0 0 0
0 1 0 1 0 0 0 0
1 0 1 0 1 0 0 0
2 1 2 0 0 1 0 0
1 0 1 2 1 0 0 0
0 3 0 1 0 1 0 0
1 0(1)2 1 0 0 0 From this square, recursion should go deeper ...
4 1 2 0(0)1 0 0 ... to get to this square.

What is the difference between char array[100]; and char array[100] = "";?

I am trying to write a C program that loads a file, reads it and outputs the longest line from the file together with the number of symbols. The result is written in another file. The code seems to be working like it is, but I would like to understand why I get wrong results once I slightly change the definition of the arrays, to remove the equals to empty quotes (= "") from the maxLine definition. For example, if I write the following:
char currentLine[100];
char maxLine[100];
then I get unwanted results.
Here is the whole function:
#define MAX_FILE_NAME 50
void maxCharRow()
{
FILE *fptr;
errno_t err;
char fileNameRead[MAX_FILE_NAME] = "test.txt";
char fileNameWrite[MAX_FILE_NAME] = "results.txt";
char currentLine[100];
char maxLine[100] = "";
if ((err = fopen_s(&fptr, fileNameRead, "r")) != NULL) {
printf("Could not open the file: %s\n", fileNameRead);
exit(1);
}
while (fgets(currentLine, sizeof(currentLine), fptr) != NULL)
{
if (strlen(maxLine) < strlen(currentLine))
{
strcpy_s(maxLine, currentLine);
}
}
printf("\nLongest line in file has %i symbols\nand its content is:%s", strlen(maxLine), maxLine);
((err = fopen_s(&fptr, fileNameWrite, "w")) != NULL); {
fprintf(fptr, "%s", maxLine);
exit(1);
}
fclose(fptr);
}
In c "" is an empty string terminated by null character 0.
Since char currentLine[100] is a local variable it is by default not initialized to zero and is filled with indeterminate values.
But if you initialize zero-th element to 0 or "" then c will initialize whole array with zeros.
example:
#include <stdio.h>
int main()
{
char arr0[100];
char arr1[100] = "";
char arr2[100] = {0};
for(int i=0; i<100; ++i){
printf("%d ", arr0[i]);
}
printf("\n");
for(int i=0; i<100; ++i){
printf("%d ", arr1[i]);
}
printf("\n");
for(int i=0; i<100; ++i){
printf("%d ", arr2[i]);
}
printf("\n");
}
Output:
0 0 0 0 0 0 0 0 -1 -75 -16 0 0 0 0 0 -62 0 0 0 0 0 0 0 -89 -82 55 -96 -4 127 0 0 -90 -82 55 -96 -4 127 0 0 85 -105 -84 -34 -92 127 0 0 1 0 0 0 0 0 0 0 101 88 74 28 -111 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 88 74 28 -111 85 0 0 -48 85 74 28 -111 85 0 0 -80 -81 55 -96
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Edit:
Also note that even if you set first eg. 3 elements to non-zero values char arr0[100] = {1,2,3} the rest of the elements will still be initialized to zero.
Assigning "" to an array null-terminates the array so it becomes a string.
It's like doing this:
char array[100] = { '\0' };
Note that this isn't needed at global scope because variables at global scope are already zero-initialized.

Why are the last row and last column behaving like this?

I am a complete beginner to c programming. Help me out please. I am trying to write a program that reads from a .txt file and stores the values in a 2D array and later it prints the array to show what it got.
This is what is contained in my .txt file:
100 200 300
400 500 600
This is the program I have written:
#include <stdio.h>
main(){
//reading file
FILE *fp;
fp=fopen("c:\\users\\user\\desktop\\Arpon 4-1\\Thesis Programming\\Nov18-1.txt", "r");
//creating a 2d array
float a[9][9]={0};
//getting the data into the array
int r,c;
for(r=0; r<=1; r++){
for(c=0; c<=2; c++){
fscanf(fp, "%f", &a[r][c]);
}
}
//printing the array
for(r=0; r<=9; r++){
for(c=0; c<=9; c++){
printf("%.0f ", a[r][c]);
}
printf("\n");
}
}
The program does what I intend it to do, but the output comes out like this:
100 200 300 0 0 0 0 0 0 400
400 500 600 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1990463982126334400000000000000000
1990463982126334400000000000000000 0 0 0 0 0 0 0 0 0
Why are the last column and row behaving like this? a[0][9], a[8][9] and a[9][0] should all be zeros as I initiated the whole array as 0 in line 8. But they are not. This is bugging me out a lot. Please help!
p.s. If I write float a[9][9]; instead of float a[9][9]={0}; , the output is worse. But this should have worked too, as I understand, because any array should be initiated as 0s by default.
The output in this case is like this:
100 200 300 0 0 0 0 0 0 400
400 500 600 0 0 0 0 -144118967647076350 0 0
0 3508856861431739000000000000000000 2070380395102208 0 0 0 0 -0 0 1921062897128927200000000000000000
1921062897128927200000000000000000 0 0 0 0 0 -0 0 1921062897128927200000000000000000 0
0 0 1921064599296481200000000000000000 -0 0 0 3501549920349857000000000000000000 3486704852883756600000000000000000 -1 0
0 0 0 0 -5529745792027328500 0 0 0 0 1931126885420802600000000000000000
1931126885420802600000000000000000 0 0 1941291301598365100000000000000000 1990334617392229100000000000000000 0 1940873342092601300000000000000000 0 1931097793829879400000000000000000 1931096401147335200000000000000000
1931096401147335200000000000000000 -0 0 0 0 0 0 0 0 1934835908521006500000000000000000
1934835908521006500000000000000000 -406541672906752 -1 1931096401147335200000000000000000 1931134003576028500000000000000000 0 0 0 0 1990463982126334400000000000000000
1990463982126334400000000000000000 0 0 0 0 0 0 0 0 0
The first 6 values are okay, but the other stuff, oh well :(
#include <stdio.h>
main(){
//reading file
FILE *fp;
fp=fopen("c:\\users\\user\\desktop\\Arpon 4-1\\Thesis Programming\\Nov18-1.txt","r");
//creating a 2d array
float a[9][9]={0};
//getting the data into the array
int r,c;
for(r=0; r<=1; r++){
for(c=0; c<=2; c++){
fscanf(fp, "%f", &a[r][c]);
}
}
//printing the array
for(r=0; r<9; r++){
for(c=0; c<9; c++){
printf("%.0f ", a[r][c]);
}
printf("\n");
}
}
The problem is in printing the array. You have declared a[9][9] but trying to print the 10 row and column , so there is a junk value . Execute the above program and get your expected output

regExp in c: match a digit after <n> repetitions

i have a group of numbers that start with string, inside a string in C:
intr 250727985 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 238463729 0 0 0 0 0 8510 1009565 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 75963 0 0 0 0 0 0 0 0 0 0 0 0 0 6416543 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 29812 197 0 0 0 0 842664 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
i want to capture (match) only the 26th position of them (desired match: 1009565 on my return.)
i've tried this pattern:
(?:[0-9]+[[:space:]]){26}(?<![0-9])
but this is capturing whole string until the desired position.
How to achieve this with RegExp in C? someone could provide an sample source?
RegExp is the fastest (and lightest on system resources) way to do this? i need to repeat this operation various times in a second, all the uptime.
i'm confused on how to do this.
I believe using RegExp will make the problem more complicated, as suggested by others, using strtok is much easier.
You can parse the string at each space, and match the pattern you are trying to search for using strcmp from <string.h>.
Here is a basic idea of what you might want to use:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *string_search(char *string, unsigned position);
int main(void) {
char string[] = "250727985 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 238463729 0 0 0 0 0 8510 1009565 0 0 0 0 0";
char *check;
unsigned position = 26;
check = string_search(string, position);
if (check != NULL) {
printf("String %s found in position %d.\n", check, position);
} else {
printf("No string found in position %d.\n", position);
}
return 0;
}
char *string_search(char *string, unsigned position) {
char *number;
const char *delim = " ";
unsigned pos_count = 1;
number = strtok(string, delim);
while (number != NULL) {
if (pos_count == position) {
return number;
}
pos_count++;
number = strtok(NULL, delim);
}
return NULL;
}
The Unix strings library has strtok which divides a string into tokens given a delimiter. You should be able to simply iterate through the string until you get to the position you want.
A discussion on Stack Overflow of strtok is at Using strtok in c which has some sample code and gotchas.

An attempt to generate a certain amount of randomly-placed numbers in an array

Using this program, I'm trying to set a 6x15 array to 0, then place a random number x amount of times in a random slot of the array. However, it doesn't go as planned...
Note that MAX_ROWS is 6, MAX_COLS is 15, and OCEAN is 0
#include <stdio.h>
#include <time.h>
#include "util.h"
int rand_number(int param);
main()
{
int map[MAX_ROWS][MAX_COLS]; //initializes an array, map, with the dimensions 6 and 15.
//sets all values in the array to 0
int a,b;
for (a = 0; a < MAX_ROWS; a++)
{
for (b = 0; b < MAX_COLS; b++)
{map[a][b]=OCEAN;}
}
int shipnum = 6;
This SHOULD place the random numbers. (shipnum is just a value I use to limit the number of ships I place):
while(shipnum > 0)
{
map[rand_number(MAX_ROWS)][rand_number(MAX_COLS)] = 3;
shipnum -= 1;
map[rand_number(MAX_ROWS)][rand_number(MAX_COLS)] = 2;
shipnum -= 2;
map[rand_number(MAX_ROWS)][rand_number(MAX_COLS)] = 1;
shipnum -= 3;
}
However, when I run
/*This will print the array*/
for (a = 0; a < MAX_ROWS; a++)
{
for (b = 0; b < MAX_COLS; b++)
{printf("%d ", map[a][b]);}
printf("\n");
}
}
I am given
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
When I actually want to get something like
0 0 0 0 0 0 0 0 0 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 2 0 0 0 0 0 3 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
This is the function I use to generate a random number.
/*This will generate a random number*/
int rand_number(int param)
{
srand((unsigned int)time(NULL));
int x = param;
int rn = rand() % x;
return rn;
}
Every time you call rand_number, you reset the pseudo rng with srand((unsigned int)time(NULL)); , remove that line, or move it to the start of your main()
Don't call srand() more than once in a program, somwhere at program startup.
Depending on what you want to do, remember a random number generator doesn't produce unique numbers, so you might need to account for that if you want to guarantee you've placed shipnum entries in your array. I.e. your 6 calls to rand_number() could all produce 4.
You are reseeding your random generator on every call which will make it not random. Remove this line:
srand((unsigned int)time(NULL));
Your code also allows writing a ship where there already was a ship. If you don't want to allow this, you should check that the cell is empty before placing a ship in that cell.
int x = rand_number(MAX_ROWS);
int y = rand_number(MAX_COLS);
if (map[x][y] == 0) { /* Add this check! */
map[x][y] = 1;
shipnum -= 1;
}
In addition to not calling srand() multiple times, you're not going to get your desired output with the while loop you have. You're stating you want a total of 6 ships, 1, 1, 1, 2, 2, 3, however your while loop places one of each type, after which your shipnum will be == 0, breaking you out of the loop.
Instead, create three separate ship placement routines, one for each type. Additionally, you need to make sure your placement is not on top of another ship -- which is exactly what's happening when you srand() within your random function when called so rapidly, and is possible to happen at other times as well.
First thing that strikes me is that you don't check if the existing cell already has a ship assigned or not. I would use 0 as a sentinel value.
Also (it's been some time since I worked with random numbers), I'm betting there's something wrong with your seed. I believe the computer is too fast for your function to succeed, meaning that the 'time' you use as the seed is always the same.
Make the seed external (declare it outside the function body), and initialize it once.

Resources