fgets in a loop repeats data in the 2d array - c

I am trying to get my 9x9 grid of numbers from a file and store it in a 2D int array. For this, I wrote my code so that it uses fgets() from the file and then converts the char array values to an int and then stores it in that respective spot in the array.
While I thought it was working, when I printed out the array, I noticed how it has repeated values (from the previous row that it read) and it doesn't print out the full 9x9 grid. Here is what I mean:
int strIndex = 1; // Goes every odd to extract number
/* Need to do this for the whole grid */
for(int i = 0; i < 9; i++) {
fgets(str,19, f);
strIndex = 1;
// printf("%s\n", str);
for(int j = 0; j < 9; j++) {
// Since asci digits start at 48, subtracting gets you the num
grid[i][j] = (int) str[strIndex] - 48;
strIndex = strIndex + 2;
}
}
This is what I am supposed to be getting (basically whatever is in input.txt):
8 2 7 1 5 4 3 9 6
9 6 5 3 2 7 1 4 8
3 4 1 6 8 9 7 5 2
5 9 3 4 6 8 2 7 1
4 7 2 5 1 3 6 8 9
6 1 8 9 7 2 4 3 5
7 8 6 2 3 5 9 1 4
1 5 4 7 9 6 8 2 3
2 3 9 8 4 1 5 6 7
But this is what I am getting:
8 2 7 1 5 4 3 9 6
-38 2 7 1 5 4 3 9 6
9 6 5 3 2 7 1 4 8
-38 6 5 3 2 7 1 4 8
3 4 1 6 8 9 7 5 2
-38 4 1 6 8 9 7 5 2
5 9 3 4 6 8 2 7 1
-38 9 3 4 6 8 2 7 1
4 7 2 5 1 3 6 8 9
Am I using fgets() correctly? And what is -38? I can't seem to understand why that is being printed instead of the actual number. (For ex: Instead of 8 from grid[0][0], it prints -38 in grid[0][1]. In fgets, I made the space 19 because I noticed how fgets() also takes in whitespace, so that's why my strIndex is incrementing every 2.
Thanks

fgets(str,19, f)
That doesn't read the whole line. Your lines have 19 visible characters but there is a newline (\n) character at the end of each line. By reading only 19 characters you leave the newline for the next fgets. Hence every second fgets call will read a single newline character with the rest of the buffer retained from the previous line. The newline ascii value is 10 and that is where the -38 comes from since the code does str[strIndex] - 48.
So the fix would be to read 20 characters rather than 19. In fact, it wouldn't hurt to put an even larger buffer. Say 32 bytes. fgets will stop at the newline anyway.

Related

Loop a 2D array vertically and choose one from each line

How to loop a 2D array, such as
1 2 3 4
5 6 7 8
9 10 11 12
choose one from each line everytime, left first. The expected order for the example is:
1 5 9
2 5 9
1 6 9
1 5 10
2 6 9
2 5 10
1 6 10
2 6 10
....
Thanks.
you can try two for loops
$a[$row][$column];
for($i=0; $i <$row; i++) {
for($j=0; $j<$column;$j++){
echo $a[$j][$i];
}
}
you can indent after 1 loop

How to do print formatting in Python with chunks of strings?

I'm having some trouble with formatting the pyramid. I've tried to use format when printing from the loop but that didn't seem to work and just breaks the program. What would be different ways to format the output. The only trouble that I am having is when I am printing 10 and up when there's double digits. What would be the best approach formatting the printing output? I've tried variety of ways but couldn't make formatting work within the loop from documentation
https://docs.python.org/3.5/library/string.html#formatstrings
Here is the script:
userinput = int(input("Enter the number of lines: " )) # User input of the total number of lines
userinput = userinput + 1 # adding a value of 1 additionally with the user input to make numbers even
for i in range(1, userinput): # Loop through lines from 1 to userinput
for j in range(userinput - i): # printing spaces, 1 at a time from j = 1 to j = userinput - i
print(" ", end = " ")
for j in range(i, 0, -1): # printing number decreasing from the line number j to 1
print(j, end = " ")
for j in range(2,i + 1): # Printing number increasing from 2 to line number j
print(j, end = " ")
print()
j += 1
The output when its less than 10
Enter the number of lines: 9
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
The output when it's 15 or more:
Enter the number of lines: 15
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
When I have reserved an extra space for 10 and up, here is what my outout looks like: (The dots were used to distinguish from empty space, all I did was added a " " quotes in the beginning of the print.
Enter the number of lines: 12
. . . . . . . . . . . . 1
. . . . . . . . . . . 2 1 2
. . . . . . . . . . 3 2 1 2 3
. . . . . . . . . 4 3 2 1 2 3 4
. . . . . . . . 5 4 3 2 1 2 3 4 5
. . . . . . . 6 5 4 3 2 1 2 3 4 5 6
. . . . . . 7 6 5 4 3 2 1 2 3 4 5 6 7
. . . . . 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
. . . . 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
. . . 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
. . 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
. 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
Here is what I've tried changing by adding aditional space
for j in range(userinput - i): # printing spaces, 1 at a time from j = 1 to j = userinput - i
print(".", end = " ")
for j in range(i, 0, -1): # printing number decreasing from the line number j to 1
print(" ", j, end = "")
for j in range(2,i + 1): # Printing number increasing from 2 to line number j
print(" ", j, end = "")
for j in range(userinput - i): # printing spaces, 1 at a time from j = 1 to j = userinput - i
print(" ", end = " ")
Here is the ideal output of what I am trying to accomplish:
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Thank you!
The things to consider for this problem are
The length of the largest number.
The length of the current number being printed.
The difference in lengths.
In order to correctly space everything, you're going to need to print extra
spaces after the numbers with less digits (to compensate for the extra digits in the larger number).
For example, if you have a row that contains the number 10, in order to correctly space the other smaller numbers, you're going to need to use extra spaces to compensate for that second digit in the number 10.
This solution works for me.
userinput = int(input("Enter the number of lines: " ))
userinput = userinput + 1
# Here, you can see I am storing the length of the largest number
input_length = len(str(userinput))
for i in range(1, userinput):
# First the row is positioned as needed with the correct number of spaces
spaces = " " * input_length
for j in range(userinput - i):
print(spaces, end = " ")
for j in range(i, 0, -1):
# Now, the current numbers length is compared to the
# largest number's length, and the appropriate number
# of spaces are appended after the number.
spaces = " " * (input_length + 1 - len(str(j)))
print(j, end = spaces)
for j in range(2,i + 1):
# The same is done here as in the previous loop.
spaces = " " * (input_length + 1 - len(str(j)))
print(j, end = spaces)
print()
j += 1
Take a look at
https://stackoverflow.com/a/13077777/6510412
I think this might be what you're looking for. I hope it helps.

Array processing, shapes

I have a square 2d array of values, where each row is identical, and where each element of row is one bigger than the last. For example:
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
I want to filter them, such that I can make a diamond as such:
1
1 2 3
1 2 3 4 5
1 2 3 4 5 6 7
1 2 3 4 5
1 2 3
1
Notice how the first part of the array is used, no matter how many elements are to be printed on that line. Also, spacing doesn't matter. I spaced them to show the diamond.
I know how to filter the top right "chunk" out, using j-i<(j/2). This will convert the original square into:
1
1 2 3
1 2 3 4 5
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
How can I get the bottom right "chunk" to filter out also? What additional condition can I impose on the values?
Presuming you have found out and stored the length of the "side" of the square already then you could use something like below. However, if your square has an even length then it will not work (can't produce a diamond in this way from an even side length square).
The following is pseudo-code so you will need to adapt it for your language. I've also used 0-indexed arrays and presumed square is a 2D array.
for (i=0, i<length, i++)
{
for (j=0, j<Length, j++)
{
if (i < length/2)
{
if (j < length/2 AND j <= i)
print square[i][j]
}
}
else
{
if (j < length/2 AND j <= (length - i))
{
print square[i][j]
}
}
}
print newline
}

Trick the randomizer in C

I want to get random numbers between 1 to 10.
It actually works, but when it's in a loop, I don't really get random numbers.
int randomNum;
srand ( (unsigned int)time(NULL) );
randomNum = rand() % 10;
I've been spending hours here and in google looking for a solution, but it looks like no one really solved it (or maybe I didn't search good enough).
The value we get from the randomizer depends on the seconds (not miliseconds or something else, like in other programming language) and that's why the numbers are not random.
In addition, I don't want to download a package for C because I run my code in the university labs, and they won't allow it.
Is there anyone with a creative solution for this problem? maybe some mathematic functions?
To illustrate Sidoh's answer.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main(int argc, char** argv)
{
int i;
srand ( (unsigned int)time(NULL) );
for (i = 0; i < 100; i++)
{
printf("%d ", 1 + (rand() % 10));
}
putchar('\n');
return 0;
}
This produced the following results for my one time seed using time( ).
7 10 2 4 4 4 2 1 7 7 10 4 3 10 2 9 6 9 2 9 7 10 4 1 1 8 2 4 8 1 2
4 2 3 9 5 8 1 7 4 9 8 10 1 8 1 1 5 1 4 5 7 3 9 10 3 6 1 9 3 4 10
8 5 2 7 2 2 9 10 5 9 8 4 1 7 7 2 3 7 5 8 6 10 8 5 4 3 7 2 8 2 1 7
7 5 5 10 6 5
Do not seed the random number generator more than once. Since your code probably runs all within the same second, every query to rand uses the same seed, so you'll get the same number every time.
Dave Newman provides a very good answer.
Alternatively, you could also try a pseudo random generator, for example
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main()
{
int a0; // this value will be our requirement
int mod = 11; //this is the limit (0 - mod-1), here 10
int a; // this stores the previous value of a0;
int i; // loop variable
int mul=25; //multiplicative factor
int add=3; // additive factor
int limit=100; // our limit
srand ( (unsigned int)time(NULL) ); // initialize the seed
a0 = rand() % mod;
for(i=0;i<limit;i++)
{
printf("%d\t",a0);
a = a0;
a0 = (a * mul + add) % mod;
}
putchar('\n');
return 0;
}
The output::
1st run::
2 10 4 3 1 8 0 6 7 9 2 10 4 3 1 8 0 6
7 9 2 10 4 3 1 8 0 6 7 9 2 10 4 3 1 8
0 6 7 9 2 10 4 3 1 8 0 6 7 9 2 10 4 3
1 8 0 6 7 9 2 10 4 3 1 8 0 6 7 9 2 10
4 3 1 8 0 6 7 9 2 10 4 3 1 8 0 6 7 9
2 10 4 3 1 8 0 6 7 9
2nd output::
9 2 10 4 3 1 8 0 6 7 9 2 10 4 3 1 8 0
6 7 9 2 10 4 3 1 8 0 6 7 9 2 10 4 3 1
8 0 6 7 9 2 10 4 3 1 8 0 6 7 9 2 10 4
3 1 8 0 6 7 9 2 10 4 3 1 8 0 6 7 9 2
10 4 3 1 8 0 6 7 9 2 10 4 3 1 8 0 6 7
9 2 10 4 3 1 8 0 6 7

Index manipulation of array in C

Begining with an ordered array
[1, 2, 3, 4, 5, 6, 8, 9, 10]
How would be the way to get every iteration the following results?
1 2 3 4 5 6 7 8 9 10
1 3 4 5 6 7 8 9 10 2
1 4 5 6 7 8 9 10 2 3
1 5 6 7 8 9 10 2 3 4
1 6 7 8 9 10 2 3 4 5
1 7 8 9 10 2 3 4 5 6
1 8 9 10 2 3 4 5 6 7
1 9 10 2 3 4 5 6 7 8
1 10 2 3 4 5 6 7 8 9
#include <stdio.h>
#define MAX 10
int a[MAX], i,j,cnt=2;
main (){
for (i=0; i<MAX; i++){
a[i]= i+1;
}
for (i=0; i<MAX; i++) {
printf ("%d ", a[i]);
}
printf ("\n");
for (j=0; j < MAX-2;j++){
a[0]=1;
for (i=1; i < MAX-1; i++){
if (a[i]%MAX != 0){
a[i]= a[i] + 1;
}else{
if (a[i]==10) {
//printf ("a[%d]: %d \t ** %d\n", i , a[i] ,cnt);
//a[i-1]= i;
a[i] = cnt;
}
}
}
for (i=0; i<MAX; i++) {
printf ("%d ", a[i]);
}
printf ("\n");
}
}
Now I almost get it but the last column is not right, What should I do?
1 2 3 4 5 6 7 8 9 10
1 3 4 5 6 7 8 9 10 10
1 4 5 6 7 8 9 10 2 10
1 5 6 7 8 9 10 2 3 10
1 6 7 8 9 10 2 3 4 10
1 7 8 9 10 2 3 4 5 10
1 8 9 10 2 3 4 5 6 10
1 9 10 2 3 4 5 6 7 10
1 10 2 3 4 5 6 7 8 10
C arrays are indexed from 0. So when you access elements from 1 to MAX, you are running off the end of the array.
Have your loops go from 0 to MAX-1. Customary way to write it is
for (i=0 ; i < MAX ; ++i)
...so anybody reading your code can immediately prove that the array index never equals MAX.
Well, at a minimum, arrays in C are zero based so you are writing past the end of the array. For an array declared int foo[MAX] valid elements are from foo[0]…foo[MAX-1]
Specifically a[MAX] might well reference the memory location that the variable i uses, causing the loop to reset when it attempt to overwrite a[MAX].
Either shift everything down by one, or declare your array MAX+1 and ignore the zero bit.
Oh, and you should not need to set a[1]=1; every time.

Resources