I have the following code:`
#include <stdio.h>
#include <stdlib.h>
void load_from_file(int A[], int *n);
int main()
{
int *A;
A = (int*)malloc(0);
int count = 0;
int i;
load_from_file(A, &count);
for(i = 0; i < count; i++)
{
printf("A[%d]=%d ", i, A[i]);
printf("\n");
printf("&A[%d]=%p \n\n", i, &A[i]);
}
return 0;
}
void load_from_file(int A[], int *n)
{
FILE* fp;
int temp, i;
fp = fopen("data.txt", "r");
if (fp == NULL)
{
printf("error!!");
exit (1);
}
fscanf(fp, "%d", &temp);
*n = temp;
A = (int*) realloc(A, temp * sizeof(int));
if (*A == NULL)
{
printf("error realloc!!");
exit(1);
}
for(i = 0; i < temp; i++)
{
fscanf(fp, "%d", &A[i]);
}
for(i = 0; i < temp; i++)
{
printf("A[%d]=%d ", i, A[i]);
printf("\n");
printf("&A[%d]=%p \n\n", i, &A[i]);
}
fclose(fp);
}
I'm trying to read a text file into an array.
First line of the file has the number of elements of the array, and second line the numbers-elements.
We create the array through realloc.
But something is going wrong.....
I have some patches, printing the address of array's elements.
But unfortunatelly they are different(not all the times) inside the function, and outside the function, although an array is passed by reference (as I think...)
Please, tell me where is the mistake, and how can I fix the problem.
Thanks in advance...
Dimitri
Call:
int *A = load_from_file(&count);
Function:
int *load_from_file(int *n)
{
FILE* fp;
int temp,i;
int *A = 0;
fp=fopen("data.txt","r");
if (fp==NULL){fprintf(stderr, "error!!\n");exit (1);}
fscanf(fp,"%d",&temp);
*n=temp;
A = (int*) realloc(A,temp * sizeof(int));
if (A == NULL) {fprintf(stderr, "error realloc!!\n");exit(1);}
for(i=0;i<temp;i++)
fscanf(fp, "%d",&A[i]);
for(i=0;i<temp;i++)
{
printf("A[%d]=%d ",i,A[i]);
printf("\n");
printf("&A[%d]=%p \n\n",i,&A[i]);
}
fclose(fp);
return A;
}
This is a totally minimal set of changes; the code needs a lot more work. In particular, the fscanf() calls should be error checked. There's a subtle but important change in the allocation test: if (A == NULL) rather than the original if (*A == NULL).
With somewhat more complete error checking:
int *load_from_file(int *n)
{
FILE *fp;
int temp, i;
int *A = 0;
const char file[] = "data.txt";
fp = fopen(file, "r");
if (fp == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", file);
exit(1);
}
if (fscanf(fp, "%d", &temp) != 1)
{
fprintf(stderr, "Failed to read number of entries\n");
exit(1);
}
*n = temp;
A = (int *) realloc(A, temp * sizeof(int));
if (A == NULL)
{
fprintf(stderr, "Failed to reallocate %zu bytes of memory\n",
temp * sizeof(int));
exit(1);
}
for (i = 0; i < temp; i++)
{
if (fscanf(fp, "%d", &A[i]) != 1)
{
fprintf(stderr, "Failed to read entry number %d\n", i);
exit(1);
}
}
for (i = 0; i < temp; i++)
printf("A[%d]=%d: &A[%d]=%p\n", i, A[i], i, &A[i]);
fclose(fp);
return A;
}
I have a library of error reporting functions that I use which would reduce the error handling from 4 lines to 1 line per error. I strongly recommend creating and using such a library for yourself.
Related
#include <stdio.h>
#include <stdlib.h>
#include "vettore.h"
int main(int argc, char *argv[]){
if(argc != 5)
printf("Incorrect parameters number\n");
else{
int n = atoi(argv[1]);
int *a = (int*) calloc(n, sizeof(int));
if(a == NULL)
printf("Unsufficient memory\n");
else{
finput_array(argv[2], a, n);
bubblesort(a, n);
foutput_array(argv[4], a, n);
int *oracle = (int*) calloc(n, sizeof(int));
finput_array(argv[3], oracle, n);
if(compare_array(a, oracle, n))
printf("PASS\n");
else
printf("FAIL\n");
}
}
}
I run the program this way: ./test_ordina_array.exe 12 TC4_input.txt TC4_oracle.txt TC4_output.txt but it gives me segmentation fault.
"TC4_output.txt" is created by the program while the other two files already exist.
This are the functions used:
void bubblesort(int a[], int n){
int i, j;
for(i = 0 ; i < n - 1; i++)
{
for(j = 0 ; j < n - i - 1; j++)
{
if (a[j] > a[j+1]) /* For decreasing order use < */
{
swap(&a[j], &a[j+1]);
}
}
}
}
void finput_array(char *file_name, int a[], int *n){
FILE *fd = fopen(file_name, "r");
if(fd == NULL)
printf("Errore in apertura del file %s\n", file_name);
else{
int i = 0;
fscanf(fd, "%d", &a[i]);
while(i<*n && !feof(fd)){
i++;
fscanf(fd, "%d", &a[i]);
}
fclose(fd);
if(i<*n)
*n = i;
}
}
void foutput_array(char *file_name, int a[], int n){
int i;
FILE *fd;
fd = fopen(file_name, "w");
if(fd == NULL)
printf("Errore in apertura del file %s\n", file_name);
else{
for(i=0; i<n; i++)
fprintf(fd, "%d\n", a[i]);
fclose(fd);
}
}
int compare_array(int a[], int b[], int n){
int i=0;
while(i<n && a[i] == b[i])
i++;
return (i==n) ? 1 : 0;
}
They are contained in "vettore.c" and "vettore.h" contains their prototypes.
The program has to order in ascending order the elements contained in the first txt file and write them in the output file.
You have problem when using finput_array
finput_array(argv[2], a, n);
Please replace by
finput_array(argv[2], a, &n);
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;
}
I have some problems with my code. Everything is fine; gcc shows no errors or warnings; valgrind says no memory leaks, but my array isn't printed and I'm not sure why. Is fscanf() not working correctly or am I printing it incorrectly?
#include <stdio.h>
#include <stdlib.h>
int arrsize (FILE *file)
{
if (file == NULL) {
printf("Error: file pointer is null.");
return 0;
}
int sizer;
fscanf(file, "%d", &size);
return size;
}
int main()
{
int i = 0, j = 0, k = 0,a=0;
FILE *fp;
if ((fp = fopen("matrix.txt", "r")) == NULL)
{
printf("Error: file pointer is null.\n");
return 1;
}
int size = arrsize(fp);
printf("Array size is %d x %d \n", size, size);
double **array = (double **)malloc(size * sizeof(double *));
for (i; i < size; i++)
array[i] = (double *)malloc(size * sizeof(double));
for (i; i < size; i++)
{
for (j = 0; j < size; j++)
{
fscanf(fp, " %lf", &array[i][j]);
printf(" %lf ",array[i][j]);
}
}
for (k ; k < size; k++) {
free(array[k]);
}
free(array);
fclose(fp);
return 0;
}
Check the return of fscanf and malloc to make sure of success.
Add fflush ( stdout); to the print loops since the format string does not have a newline.
#include <stdio.h>
#include <stdlib.h>
int arrsize (FILE *file)
{
if (file == NULL) {
printf("Error: file pointer is null.");
return 0;
}
int size;
if ( 1 == fscanf(file, "%d", &size)) {
return size;
}
return -1;
}
int main()
{
int i = 0, j = 0, k = 0;
FILE *fp;
if ((fp = fopen("matrix.txt", "r")) == NULL)
{
printf("Error: file pointer is null.\n");
return 1;
}
int size = arrsize(fp);
if ( -1 == size) {
fprintf( stderr, "Error: problem parsing array size.\n");
return 1;
}
printf("Array size is %d x %d \n", size, size);
double **array = NULL;
if ( NULL != ( array = malloc(size * sizeof(double *)))) {
for (i = 0; i < size; i++) {
if ( NULL == ( array[i] = malloc(size * sizeof(double)))) {
fprintf ( stderr, "problem allocation array[]\n");
while ( i) {
i--;
free ( array[i]);
}
free ( array);
return 1;
}
}
}
else {
fprintf ( stderr, "problem allocation array\n");
return 1;
}
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
{
if ( 1 == fscanf(fp, "%lf", &array[i][j])) {
printf(" %lf ",array[i][j]);
}
else {
fprintf ( stderr, "problem parsing double\n");
break;
}
}
fflush ( stdout);
}
for (k = 0; k < size; k++) {
free(array[k]);
}
free(array);
fclose(fp);
return 0;
}
I need to sort a list of numbers in a file in a ascending order. I have done all the opening of the file and created my bubble sort function. But I'm stuck on how to make this all work together.
my inputefile.csv looks something like the following:
3,-4,-5,-8
10,30,50,-10
40,100,60,-2
void bubble_sort(char* line, int size);
int main(void)
{
FILE *file;
char* line;
int size = sizeof(line);
file = fopen("inputfile.csv", "r");
if(file == NULL)
{
printf("Unable to open the file");
}else
{
while(fgets(line, sizeof(line), file)
{
bubble_sort(line, size)
}
}
}
void bubble_sort(char* line, int size)
{
int temp, i, j;
for (i=0; i< size-1; i++)
{
for (j=0; j<size-1; j++)
{
if(line[j] > line[j+1])
{
temp = line[j];
line[j] = line[j+1];
line[j+1] = temp;
}
}
}
}
The number of lines is unknown and also each line has 4 integers separated by a comma. By my code you could say i am a newbee
#include <stdio.h>
#include <stdlib.h>
void bubble_sort(int *array, int size);
int main(void){
FILE *file;
char line[128];
if((file = fopen("inputfile.csv", "r")) == NULL){
printf("Unable to open the file");
return -1;
}
while(fgets(line, sizeof(line), file)){
int i, a[4], size = sizeof(a)/sizeof(*a);
sscanf(line, "%d,%d,%d,%d", &a[0], &a[1], &a[2], &a[3]);
bubble_sort(a, size);
for(i = 0; i < size; ++i){
printf("%d", a[i]);
if(i<size-1)
printf(", ");
}
printf("\n");
}
fclose(file);
return 0;
}
void bubble_sort(int *a, int size){
int i, temp, swap;
do{
for(swap=i=0;i<size-1;++i){
if(a[i]>a[i+1]){
swap = 1;
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
--size;
}while(swap);
}
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.