I am reading from 2 different files and running this function on each.
The file format is
2
3
8 7 6
5 4 3
The code I am using is
void readFile(char txtName[], int k, int matrix){
int c = 0;
int i = 0;
int j = 0;
int x = 0;
//Open file
FILE *txt;
txt = fopen(txtName, "r");
//Go till the end of the file
while( fscanf(txt, "%d", &c) != EOF ){
//For assigning matrix A
if(matrix == 1){
//Used to skip over the first 2 inputs.
if(x > 1){
//Got to the end of the row increase to the next row.
if(j == k){
i++;
j = 0;
}
//Assiging c to A
A[i][j] = c;
printf("%d A in matrix %d %d\n", A[i][j], i, j);
j++;
}
x++;
}
}
fclose(txt);
}
int main( int argc, char *argv[] ) {
readFile(argv[1], k, 1);
int m = 2;
int k = 3;
int i;
int j;
for(i=0; i < m; i++){
for(j=0; j < k; j++){
printf("%d", A[i][j]);
}
printf("\n");
}
}
I am trying to initialize an 2 dimensional array with the file so that it is a matrix. The first value of the file is the m and the second is the k. So from the file posted. it is a 2x3 matrix with the values below it. A is a global array set to A[2][3];
The issue I am having is when I run this code my array comes out with
8 7 5
5 4 3
and I have no clue why. I have put a lot of print statements for debugging. When it comes to i = 0 and j = 2 it prints out 6. But when I print the array after the function A[0][2] = 5. Where is the error that I am making?
Your problem probably with while( fscanf(txt, "%d", &c) != EOF ). Just try with while( fscanf(txt, "%d", &c)) and check.
Related
Okay so I'm a beginner programmer so any tips on any part of the code are greatly appreciated,
but the main question is why does the code in function int longestSequence(int n,int array[n]);work when placed in main, but not when called from the function?
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int longestSequence(int n,int array[n]);
int main()
{
int n;
scanf("%d", &n);
int mat[n][n];
for(int i = 0; i<n; i++){
for(int j = 0; j<n; j++){
scanf("%d", &mat[i][j]);
}
}
int arraySize = n*n;
int array[arraySize];
int arrayIndex = 0;
for(int i=0; i<n; i++){
if(i%2 == 0){
for(int j = 0; j<n; j++){
array[arrayIndex++] = mat[i][j];
}
}else{
for(int j = n-1; j>=0; j--){
array[arrayIndex++] = mat[i][j];
}
}
}
/// Here's the same code that works when in main
// int numOfSequental = 0;
// int maxNumOfSequental = INT_MIN;
// for(int i = 0; i<n; i++){
// if(niz[i] == (niz[i+1]-1)){
// numOfSequental++;
// if(numOfSequental>maxNumOfSequental){
// maxNumOfSequental = numOfSequental;
// }
// continue;
// }
// numOfSequental = 0;
// }
//calling the function in printf
printf("Length of the sequence: %d", longestSequence(arraySize, array[arraySize]));
return 0;
}
int longestSequence(int n,int array[n])
{
int numOfSequental = 0;
int maxNumOfSequental = INT_MIN;
for(int i = 0; i<n; i++){
if(array[i] == (array[i+1]-1)){
numOfSequental++;
if(numOfSequental>maxNumOfSequental){
maxNumOfSequental = numOfSequental;
}
continue;
}
numOfSequental = 0;
}
return maxNumOfSequental+1;
}
"the main question is why does the code in function int longestSequence(int n,int array[n]); work when placed in main, but not
when called from the function?"
As called it should not work in either place.
printf("Length of the sequence: %d", longestSequence(arraySize, array[arraySize]));
// ^^^^^^^^^^^
return 0;
Note first that the index passed: arraySize is one beyond the legal index for array. In C, indexing is zero based, and so it goes from 0 - arraySize - 1
More importantly though the 2nd argument of longestSequence should be a pointer to the array, not an indexed element of the array.
printf("Length of the sequence: %d", longestSequence(arraySize, array));
return 0;
Also, in general, to compare subsequent numbers in an array with size n, the range of comparisons should be limited to:
a[i] == a[i+1] //for i == 0 through i == n-1
Change:
for(int i = 0; i<n; i++){
// ^^^
if(array[i] == (array[i+1]-1)){//array out of bounds when i == n
// ^^^
To
for(int i = 0; i<n-1; i++){
// ^^^^^
if(array[i] == (array[i+1]-1)){//i will never reach n
EDIT:
One last thing addresses comment about replacing calls to scanf() with using the 2nd argument of main. First to do that the code must include the prototype of main: int main(int argc, char *argv[]);. With this prototype, the program as called from the command line can now include command line arguments, eg: if running from CMD prompt in Windows:
C:\dev> myProg.exe 3 1 2 3 4 5 6 7 8 9
Inside your program then arguments of argc and argv[]` are populated as follows:
argc == 11 //total number of arguments
argv[0] == "myProg.exe" //program name is alway in argv[0]
argv[1] == "3"
argv[2] == "1"
...
argv[10] == "9"
Which should translate to creating a 3x3 array populated with the 9 subsequent values.
So the first statements in your code could now be: (in psuedo code)
int n = atoi(argv[1]);//check value of n before using
int array[n][n];
int index = 2;
for(int i = 0; i<n ; i++)
for(int j = 0; j<n ; j++)
array[i][j] = atoi(argv[index]);
index++;
Basically, the input file should look like this:
4
1 2 3 4
2 1 4 3
4 3 2 1
3 4 1 2
Where the first line is the size of the square matrix. However, I can't properly load the input directly into n and then into the matrix. I avoided such problem by creating a "loader" array.
int n, loader[100], p=0;
while(feof(data) == 0) {
if(p == 0) {
fscanf(data, "%d", &n); //taking n
p++;
} else {
fscanf(data, "%d", &loader[p]); //taking matrix values for p>0
p++;
}
}
//loading the matrix
int mat[n][n], o = 1; //o is set to 1, as the loader
//has been loaded from position 1.
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++){
printf("%d\n", loader[o]);
mat[i][j] = loader[o];
o++;
}
}
However, I think it is just unnecessary and there might be a faster way to directly take the matrix size and its values. When I programmed in such way, I received a welcoming Segmentation Fault error.
This code seems to work:
int loadMatrix(char *pth)
{
int i, j, n, **mat, p = 0, num;
FILE *fd;
fd = fopen(pth, "r");
if(fd == NULL) return(-1);
/* Read matrix size */
if(fscanf(fd, "%d", &n) == EOF) return(-1);
printf("Size: %d\n", n);
mat = malloc(n * sizeof(int *));
for(i = 0; i < n; i++) mat[i] = malloc(sizeof(int) * n);
while(fscanf(fd, "%d", &num) != EOF && p < (n * n)) {
mat[p / n][p % n] = num;
p++;
}
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
for(i = 0; i < n; i++) free(mat[i]);
free(mat);
fclose(fd);
return(0);
}
I'm having some issues trying to write a quick program which purpose is, given a matrix (bidimensional array allocated dinamically), saving it to a file. When checking the resulting output file I'm given at the end of each line of the file the following simbols, in bold and red, "\00".
This is my code:
/*\param n number of rows
\param m number of columns
\param mat pointer to the matrix
\param f file already opened in write mode where to write the matrix
*/
int save_to_file (char** mat, unsigned n, unsigned m, FILE* f){
int i, j;
for(i = 0;i <= n; i++)
for(j = 0; j <= m; j++)
if(j == m)
fprintf(f, "%c\n", mat[i][j]);
else
fprintf(f, "%c", mat[i][j]);
if (f == NULL)
return -1;
else
return 0;
}
Is the issue lying in the way I'm writing on the file? If that's the case, can anybody help me to fix it?
The first problem with your code is the range in the for loops. If you have n rows the loop must go from 0 to n-1 (both included). So these lines:
for(i = 0;i <= n; i++)
for(j = 0; j <= m; j++)
if(j == m)
shall be
for(i = 0;i < n; i++) // Remove =
for(j = 0; j < m; j++) // Remove =
if(j == m-1) // Insert -1
The second problem is that you check for f being NULL after you have used f. That is a bad idea and it may/will cause a program crash if f is NULL. Instead do the check as the first thing in the function:
int save_to_file (char** mat, unsigned n, unsigned m, FILE* f){
if (f == NULL) return -1;
....
....
return 0;
}
The third problem is the way you access the matrix. If your matrix is a 2D array (as you write in the text without posting the code), you can't access it correctly as a char**. The char** can be used when you have an array of char-pointers that points to arrays of chars. But not for a 2D array.
Below is an example of how the function could look for a matrix based on a 2D array.
#include <stdio.h>
int save_to_file (unsigned n, unsigned m, char mat[n][m]){
int i, j;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
if(j == m-1)
printf("%c\n", mat[i][j]);
else
printf("%c", mat[i][j]);
}
int main(void) {
char a[2][3] = {{'a','b','c'},{'d','e','f'}};
save_to_file(2,3,a);
return 0;
}
Output:
abc
def
Notice: The above function prints to stdout instead of a file but that can be easily changed by using fprintf
Firstly I'am new to C language and this is a part of the project I'am doing as my minor. My main objective is to read a matrix from text file and store it in 2D array and then take input from user, the particular row and column for which the value is to be updated in matrix and then overwrite the previous matrix stored in text file.
My text file consists of matrix in the form:
0 0 1 2 3 4...
0 0 2 0 3 0...
0 2 7 5 3 1...
.
.
.
Here's my code:
#include<stdio.h>
#include <stdlib.h>
int main()
{
int i;
int j;
int mat[31][200];
FILE *file;
file=fopen("uid.txt", "r");
for(i = 0; i < 31; i++)
{
for(j = 0; j < 200; j++)
{
if (!fscanf(file, "%d", &mat[i][j]))
break;
}
}
fclose(file);
int col,value,row;
printf("enter row");
scanf("%d",&row);
printf("enter col");
scanf("%d",&col);
printf("enter changed value");
scanf("%d",&value);
mat[row][col]=value;
file=fopen("uid.txt", "w+");
for(i = 0; i < 31; i++)
{
for(j = 0; j < 200; j++)
{
fprintf(file,"%d ", mat[i][j]);
}
fprintf(file,"\n");
}
fclose(file);
}
But the values are not getting updated. Is there a way to update the matrix by using the same technique??
Task is next:
After you generate 20 random numbers and read informations from file tombula.txt which contains names of users and their 9 numbers,print the first user (his/her name) who has 3 numbers from own array equal to generated numbers.
This is my part of code where i generate numbers and read from file but I don't know how to find that first person who has 3 numbers from array equal to generated numbers,if you know how to write that please help:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
typedef struct
{ char name[50];
int num[8];
}someone;
void generating(int[]);
int check(int[], int);
int main(void)
{
someone *pK = NULL;
int i, j, count = 0, tip;
FILE *F;
int generated[30];
int brojac[5];
srand(time(NULL));
generating(generated);
for (int j = 0; j < 20; j++)
printf("%d ", generated[j]);
printf("\n\n\n");
F = fopen("tombula.txt", "r");
if (F == NULL)
{
printf("error!");
exit(1);
}
i = 0;
while (feof(F) == 0)
{
pK = ((someone *)realloc(pK, (i + 1)*sizeof(someone)));
fscanf(F, "%s", pK[i].name);
for (j = 0; j < 8; j++)
fscanf(F, "%d", &pK[i].num[j]);
i++;
count++;
}
i--;
count--;
for (int z = 0; z < count; z++){
printf("%s ", pK[z].name);
for (int k = 0; k < 8; k++){
printf("%d ", pK[z].num[k]);
}
printf("\n");
}
return 0;
}
void generating(int numbers[])
{
int i, tmp;
for (i = 0; i < 20; ++i)
{
tmp = rand() % 50 + 1;
if (check(numbers, tmp))
{
--i;
continue;
}
numbers[i] = tmp;
}
}
int check(int b[], int a){
int i;
int n = 8;
for (i = 0; i < 20; ++i)
{
if (b[i] == a)
return 1;
}
return 0;
}
1.You opened file in r mode.
2.In a loop (loop must work until EOF) read data stored in file using fscanf() .Store name into char array and number into integer array (As you defined in struct).
3.Inside loop check if the 3 numbers matches with the numbers generated and if they do print the persons name and use break to come out of loop.
4.After this close the file.