When I execute my code I keep getting the right answers but it is printed multiple times? I want it display a table with with 5 columns and 3 rows and there should be 4 of these tables but I get three times too many and I don't know why?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
int w;
int n = 1;
int i;
for(w = 1; w < 5; w++){
FILE *myFile;
float numberArray[1];
if(n == 4){
myFile = fopen("input4.txt", "r");
n++;
}
if(n == 3){
myFile = fopen("input3.txt", "r");
n++;
}
if(n == 2){
myFile = fopen("input2.txt", "r");
n++;
}
if(n == 1){
myFile = fopen("input1.txt", "r");
n++;
}
if (myFile == NULL)
{
printf("Error Reading File\n");
exit (0);
}
printf("Enter 3 numbers between 0 and 9.999:\n");
printf("Number sin cos tan atan\n");
printf("-------------------------------------------\n");
for (i = 0; i < 3; i++)
{
fscanf(myFile, "%f,", &numberArray[i] );
}
for (i = 0; i < 3; i++)
{
printf("%.6f %.4f %.4f %.4f %.4f\n",numberArray[i], sin(numberArray[i]), cos(numberArray[i]), tan(numberArray[i]), atan(numberArray[i]));
}
fclose(myFile);
}
return 0;
}
You are reading and writing in unallocated memory space when accessing numberArray.
You defined numberArray[1] with a size of 1, yet you are accessing numberArray[1..2] in your loops here :
for (i = 0; i < 3; i++)
{
fscanf(myFile, "%f,", &numberArray[i] );
}
for (i = 0; i < 3; i++)
{
printf("%.6f %.4f %.4f %.4f %.4f\n",numberArray[i], sin(numberArray[i]), cos(numberArray[i]), tan(numberArray[i]), atan(numberArray[i]));
}
I have not tested your code, but this seems to be the most obvious culprit.
Related
I need to sort my 2 text files for my project. One of the text files is in student id, course id and score format and the other is in student id's format. I wrote the values in both of them with fprintf, so I am using fscanf while reading, but my function is not working correctly, can you tell me where is my mistake?
(I deleted the old code that didn't work because I continued on a different code)
Edit :I tried to create a code snippet based on the solution below, but when I enter the while loop, fscanf starts to get the wrong numbers. Can you look for where my mistake is?
Edit :After editing here, I did the fopen checks. There is no problem with them. The while loop closes after it runs once, I think, in the if fscanf parts, fscanf does not read the number correctly, so it exits the loop with break.
most likely broken part:
FILE *index = fopen("index.txt", "r");
FILE *record = fopen("record.txt", "r");
if (!index)
return;
if (!record)
return;
int array[n][3];
//int *array = (int *)malloc(n *3 sizeof(int));???
int count = 0;
int i=0,temp,id,course,score;
while (1)
{
if(count==n) break;
if (fscanf(record, "%d", &id) != 1) break;
if (fscanf(record, "%d", &course) != 1) break;
if (fscanf(record, "%d", &score) != 1) break;
array[count][0] = id;
array[count][1] = course;
array[count][2] = score;
count++;
}
the rest of the function for you to browse if the error is elsewhere:
void sort_for_bin_search(int n)
{
FILE *index = fopen("index.txt", "r");
FILE *record = fopen("record.txt", "r");
if (!index)
return;
if (!record)
return;
int array[n][3];
//int *array = (int *)malloc(n *3 sizeof(int));???
int count = 0;
int i=0,temp,id,course,score;
while (1)
{
if(count==n) break;
if (fscanf(record, "%d", &id) != 1) break;
if (fscanf(record, "%d", &course) != 1) break;
if (fscanf(record, "%d", &score) != 1) break;
array[count][0] = id;
array[count][1] = course;
array[count][2] = score;
count++;
}
for (i = 1; i < n - 1; i++)
{
for (int j = 0; j < n - 1; j++)
{
if(array[i][0] > array [j][0])
{
temp=array[j][0];
array[j][0] = array[i][0];
array[i][0] = temp;
temp=array[j][1];
array[j][1] = array[i][1];
array[i][1] = temp;
temp=array[j][2];
array[j][2] = array[i][2];
array[i][2] = temp;
}
else if((array[i][0]==array[j][0])&&(array[i][1]>array[j][1]))
{
temp=array[j][0];
array[j][0] = array[i][0];
array[i][0] = temp;
temp=array[j][1];
array[j][1] = array[i][1];
array[i][1] = temp;
temp=array[j][2];
array[j][2] = array[i][2];
array[i][2] = temp;
}
}
}
fclose(record);
fclose(index);
FILE *index2 = fopen("index.txt", "w");
FILE *record2 = fopen("record.txt", "w");
for (i = 0; i < n; i++)
{
fprintf(index2,"%d\n",array[i][0]);
fprintf(record2,"%d %d %d\n",array[i][0],array[i][1],array[i][2]);
//printf("%d %d %d\n",array[i][0],array[i][1],array[i][2]);
}
//free(array);
fclose(record2);
fclose(index2);
}
It looks like you are doing a bubble sort, and in each iteration you read/write from disk. Disk operations are very slow. It is much easier and faster if you read once in to array. And then sort that single array.
Example:
void sort_for_bin_search(int n)
{
//assumes that `n` is the number of lines in this file
if (n < 1) return;
FILE* fin = fopen("index.txt", "r");
if (!fin)
return;
FILE* fout = fopen("record.txt", "w");
if (!fout)
return;
int* arr = malloc(n * sizeof(int));
if (!arr) return;
int count = 0;
while (1)
{
if (count == n)
break;
int id, course, score;
if (fscanf(fin, "%d", &id) != 1) break;
if (fscanf(fin, "%d", &course) != 1) break;
if (fscanf(fin, "%d", &score) != 1) break;
arr[count] = id;
count++;
}
//add code for sorting arr
for (int i = 0; i < count; i++)
fprintf(fout, "%d\n", arr[i]);
free(arr);
fclose(fin);
fclose(fout);
}
Then you can sort, for example using bubble sort.
Use printf to print the data on screen at each step, this will help with debugging.
void sort_for_bin_search(int n)
{
FILE* fin = fopen("input_file.txt", "r");
if (!fin)
{
printf("input error\n");
return;
}
int array[n][3];
int count = 0;
while (1)
{
int id, course, score;
if (count == n) break;
if (fscanf(fin, "%d", &id) != 1) break;
if (fscanf(fin, "%d", &course) != 1) break;
if (fscanf(fin, "%d", &score) != 1) break;
array[count][0] = id;
array[count][1] = course;
array[count][2] = score;
count++;
}
n = count;
printf("reading:\n");
for (int i = 0; i < n; i++)
printf("%d %d %d\n", array[i][0], array[i][1], array[i][2]);
printf("\nsort\n");
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - 1 - i; j++)
{
if (array[j][0] > array[j + 1][0])
{
int temp;
temp = array[j][0];
array[j][0] = array[j + 1][0];
array[j + 1][0] = temp;
temp = array[j][1];
array[j][1] = array[j + 1][1];
array[j + 1][1] = temp;
temp = array[j][2];
array[j][2] = array[j + 1][2];
array[j + 1][2] = temp;
}
}
}
fclose(fin);
printf("sorted\n");
for(int i = 0; i < n; i++)
printf("%d %d %d\n", array[i][0], array[i][1], array[i][2]);
printf("write to file\n");
FILE* fout = fopen("output_file.txt", "w");
if(!fout)
{
printf("output error\n");
return;
}
for (int i = 0; i < n; i++)
fprintf(fout, "%d %d %d\n", array[i][0], array[i][1], array[i][2]);
fclose(fout);
}
So I created an array which is saved in a file. I have the number 4 printed out 100 times in the file. Now everytime the an element in the array is accessed it the value will decrease by 1. So if A[1] = 4 is accessed then it will become A[1] = 3 and be saved on the file. The thing is I can't save the modified array to the file.
I already tried moving the placement of FILE pointer.
void buildingB4()
{
system("CLS");
FILE *input, *output;
int i, B4[100], room;
input = fopen("B4.txt", "r");
if (input == NULL)
{
output = fopen("B4.txt", "w");
for (i = 1; i <= 100; i++)
{
B4[i] = 4;
fprintf(output, "%d\n", B4[i]);
}
fclose(output);
for (i = 1; i <= 100; i++)
{
if (i % 10 == 0)
{
printf("\n\n");
}
printf("B-4-%d(%d)\t", i, B4[i]);
}
}
else
{
for (i = 1; i <= 100; i++)
{
fscanf(input, "%d\n", &B4[i]);
if (i % 10 == 0)
{
printf("\n\n");
}
printf("B-4-%d(%d)\t", i, B4[i]);
}
fclose(input);
printf("\nPlease choose a room:B-4-");
scanf("%d", &room);
B4[room] = B4[room] - 1;
output = fopen("B4.txt", "a");
fprintf(output, "%d\n", B4[i]);
studentDetails();
}
}
say if A[1] = 4
and when user input is 1, 1 is saved in a variable called room.
so A[room] = A[room] -1
so the result would be A[1] = 3 and it modify the A[1] saved in the file.
Use fclose after the line
fprintf(output, "%d\n", B4[i]);
I've found little mistakes in your code and here is your fixed code:
#define HOME_SIZE 100
void show_rooms(int B[]){
for (int i = 0; i < HOME_SIZE; i++){
if (i % 10 == 0){
printf("\n\n");
}
printf("B-4-%3d(%d) ", i + 1, B[i]);
}
}
void buildingB4()
{
FILE *input, *output;
input = fopen("B4.txt", "r");
unsigned int B[HOME_SIZE], room;
if (input == NULL){
fclose(input);
// Setting all homes to 4.
for (int i = 0; i < HOME_SIZE; ++i){
B[i] = 4;
}
output = fopen("B4.txt", "w");
for(int i = 0; i < HOME_SIZE; ++i)
fprintf(output, "%d\n", B[i]);
fclose(output);
show_rooms(B);
}
else{
for (int i = 0; i < HOME_SIZE; ++i){
fscanf(input, "%d", &B[i]);
}
fclose(input);
show_rooms(B);
printf("\nPlease choose a room:B-4-");
scanf("%d", &room);
if (room > 0 && room <= HOME_SIZE)
B[room - 1] -= 1;
output = fopen("B4.txt", "w");
for(int i = 0; i < HOME_SIZE; ++i)
fprintf(output, "%d\n", B[i]);
}
}
Notice that :
In C index starts from 0 not 1.
close using file after your work in order to save it properly.
Don't use '%d\n' format for scanf, it will ignore ' ' and '\n' automatically.
Tips for future development :
Try using feof function to know if your file is ended or not instead of using constant size for your inputs.
I want to read the matrix from file and store it in an array. But the array is storing only the last value of matrix. Can anyone explain this please?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
FILE *fp, *fp1;
int n = 0, i, j, a[4][4], b[16];
fp = fopen("Output.txt", "r");
if (fp == NULL) {
printf("\nError; Cannot open file");
exit(1);
}
while (!feof(fp)) {
i = 0;
fscanf(fp, "%d", &n);//reads the file containing matrix
b[i] = n;//this part is not working
printf("%d\n", n);
i++;
}
fclose(fp);
fp1 = fopen("Output2.txt", "w");
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
fprintf(fp1, "%d\t", a[i][j] * 2);
}
fprintf(fp1, "\n");//creates file of altered matrix
}
fclose(fp1);
return 0;
}
Your input loop is incorrect:
you reset i to 0 at the beginning of each iteration
you use an incorrect test: while (!feof(fp)). Learn here why: Why is “while ( !feof (file) )” always wrong? . You should instead test the array index against the array length and check if fscanf() succeeds at reading the next value.
Here is a corrected version:
for (i = 0; i < 16; i++) {
if (fscanf(fp,"%d",&n) != 1) { //reads the file containing matrix
fprintf(stderr, "invalid input\n");
exit(1);
}
b[i] = n;
printf("%d\n", n);
}
Note also that you do not read the values into the 2D matrix, so the output loop has undefined behavior because a is uninitialized.
Here is a improved version:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
int i, j, a[4][4];
fp = fopen("Output.txt", "r");
if (fp == NULL) {
fprintf(stderr, "Error: Cannot open file Output.txt for reading\n");
exit(1);
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if (fscanf(fp, "%d", &a[i][j]) != 1) {
fprintf(stderr, "invalid input for a[%d][%d]\n", i, j);
fclose(fp);
exit(1);
}
}
}
fclose(fp);
fp1 = fopen("Output2.txt", "w");
if (fp1 == NULL) {
fprintf(stderr, "Error: Cannot open file Output2.txt for writing\n");
exit(1);
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
fprintf(fp1, "%d\t", a[i][j] * 2);
}
fprintf(fp1, "\n");
}
fclose(fp1);
return 0;
}
The purpose of the program I'm developing is to get data from two different files, perform mathematical operations involving these data, and then store the results in another file. The number of lines is counted in order to perform further calculations such as averages etc. Everything is working fine when no arithmetical operations are include. For instance, the following program successfully opens the files, reads them, allocates memory for the data, stores them into these arrays, prints the arrays contents in order to verify if the data are there, and then writes the data to another file:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float *VarA;
float *VarB;
int n = 0;
int m = 0;
int i;
FILE *input1;
FILE *input2;
FILE *output;
input1 = fopen("C:\\...\\test.txt","r");
if (input1 == NULL)
{
printf("Error! Could not open input 1.\n");
exit(1);
}
else
printf("Input1 opening: OK.\n");
input2 = fopen("C:\\...\\test2.txt","r");
if (input2 == NULL)
{
printf("Error! Could not open input 2.\n");
exit(1);
}
else
printf("Input2 opening: OK.\n");
while(fscanf(input1,"%f") == 1)
n++;
rewind(input1);
printf("n = %i\n", n);
while(fscanf(input2,"%f") == 1)
m++;
rewind(input2);
printf("m = %i\n", m);
if(m != n)
{
printf("Error: Number of rows does not match!\n");
exit(1);
}
else
printf("Number of rows matches.\n");
VarA = calloc(n, sizeof(float));
if(VarA == NULL)
{
printf("Could not allocate memory for VarA.\n");
exit(1);
}
VarB = calloc(m, sizeof(float));
if(VarA == NULL)
{
printf("Could not allocate memory for VarB.\n");
exit(1);
}
for(i = 0; i < n; i++)
fscanf(input1,"%f",&VarA[i]);
fclose(input1);
for(i = 0; i < m; i++)
fscanf(input2,"%f",&VarB[i]);
fclose(input2);
for(i = 0; i < n; i++)
{
printf("VarA: %f\n",VarA[i]);
printf("VarB: %f\n",VarB[i]);
}
output = fopen("C:\\...\\out.txt","w");
if (output == NULL)
{
printf("Error! Could not open output.\n");
exit(1);
}
else
printf("Output opening: OK.\n");
for(i = 0; i < n; i++)
{
fprintf(output,"VarA: %f\n",VarA[i]);
fprintf(output,"VarB: %f\n",VarB[i]);
}
fclose(output);
free(VarA);
free(VarB);
return 0;
}
But if I add any simple arithmetic operation involving these arrays, the program simply crashes right after the second input is opened. For instance, suppose that I add the following lines to the code:
float SumA;
SumA = VarA[0] + VarB[0];
printf("SumA is: %f\n", SumA);
So that we get:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float *VarA;
float *VarB;
float SumA;
int n = 0;
int m = 0;
int i;
FILE *input1;
FILE *input2;
FILE *output;
input1 = fopen("C:\\...\\test.txt","r");
if (input1 == NULL)
{
printf("Error! Could not open input 1.\n");
exit(1);
}
else
printf("Input1 opening: OK.\n");
input2 = fopen("C:\\...\\test2.txt","r");
if (input2 == NULL)
{
printf("Error! Could not open input 2.\n");
exit(1);
}
else
printf("Input2 opening: OK.\n");
while(fscanf(input1,"%f") == 1)
n++;
rewind(input1);
printf("n = %i\n", n);
while(fscanf(input2,"%f") == 1)
m++;
rewind(input2);
printf("m = %i\n", m);
if(m != n)
{
printf("Error: Number of rows does not match!\n");
exit(1);
}
else
printf("Number of rows matches.\n");
VarA = calloc(n, sizeof(float));
if(VarA == NULL)
{
printf("Could not allocate memory for VarA.\n");
exit(1);
}
VarB = calloc(m, sizeof(float));
if(VarA == NULL)
{
printf("Could not allocate memory for VarB.\n");
exit(1);
}
for(i = 0; i < n; i++)
fscanf(input1,"%f",&VarA[i]);
fclose(input1);
for(i = 0; i < m; i++)
fscanf(input2,"%f",&VarB[i]);
fclose(input2);
for(i = 0; i < n; i++)
{
printf("VarA: %f\n",VarA[i]);
printf("VarB: %f\n",VarB[i]);
}
output = fopen("C:\\...\\out.txt","w");
if (output == NULL)
{
printf("Error! Could not open output.\n");
exit(1);
}
else
printf("Output opening: OK.\n");
for(i = 0; i < n; i++)
{
fprintf(output,"VarA: %f\n",VarA[i]);
fprintf(output,"VarB: %f\n",VarB[i]);
}
fclose(output);
SumA = VarA[0] + VarB[0];
printf("SumA is: %f\n", SumA);
free(VarA);
free(VarB);
return 0;
}
Then the program stops working. I tried to change the positions of these lines, but the result is the same. Does anyone know what I'm doing wrong?
Basically, I'm reading a bunch of values from a text file, which has them in the following layout:
4 1 1 2 3 4
But the following block of code doesn't want to read the double type value following the first two int type values:
int matrix_read(struct matrep *mat, const char *filename)
{
FILE *fptr;
unsigned m, n;
double *ptr = NULL;
int i, j;
double x;
if ((fptr = fopen(filename, "r")) == NULL)
{
fprintf(stderr, "Cannot Open File %s\n", filename);
return -1;
}
if(fscanf(fptr, "%u", &m) != 1)
{
fprintf(stderr, "Failed to read number of rows\n");
return -1;
}
if(fscanf(fptr, "%u", &n) != 1)
{
fprintf(stderr, "Failed to read number of columns\n");
return -1;
}
mat->matrix = (double *)malloc(sizeof(double) * m * n);
if (mat->matrix == 0)
{
fprintf(stderr, "Failed to allocate %d*%d matrix\n", m, n);
return -1;
}
ptr = mat->matrix;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
double x;
if (fscanf(fptr, "%f", &x) != 1)
{
fprintf(stderr, "Failed to read element matrix[%d,%d]\n", i, j);
free(mat->matrix);
mat->matrix = 0;
mat->cols = 0;
mat->rows = 0;
return -1;
}
*ptr++ = x;//Here it reads nothing, it just gives me: -9.2559604281615349e+061
}
}
fclose(fptr);
mat->cols = m;
mat->rows = n;
return 0; // Success
}
What am I doing wrong?
fscanf(fptr, "%f", &x)
For scanning doubles, you need the %lf format. %f scans a float. Using the wrong format invokes undefined behaviour, what probably happens is that the scanned value is converted to a float and then stored in the first four bytes of the pointed-to double.