Data not being read properly reading txt file - c

So I have a file format that designates the first line of the file to be the number of students total in the file and the next lines are the students with their information(Student ID, Grade, GPA). Formatted like this:
30
1320 A 3.9
1200 B 3.3
1250 F 0.0
When I am reading in the data into arrays I am not getting the correct info and I'm not sure if its because of how I'm directly reading it in my fscanf or I'm not skipping to the next line. But all thats being stored is random basically random data from memory.
void file_sort(char *infile, char *outfile)
{
FILE *fp;
fp = fopen(infile, "r");
int num;
fscanf(fp, "%d%[^\n]", &num);
int *student_id;
student_id = (int*) malloc (num * sizeof(int));
char *grade;
grade = (char*) malloc (num * sizeof(char));
double *gpa;
gpa = (double*) malloc (num * sizeof(double));
printf("\n%d", num);
for(int i = 0; i < num; i++)
{
fscanf(fp, "%d, %c %f%[^\n]", &student_id[i], &grade[i], &gpa[i]);
}
}

So to answer my own question my issue was in worrying about going to the next line while reading the file I created my own problem by include the
"%[^\n]"
This code below functions properly for anyone coming back to this problem.
void file_sort(char *infile, char *outfile)
{
FILE *fp;
fp = fopen(infile, "r");
int num;
fscanf(fp, "%d", &num);
printf("\n%d", num);
int *student_id;
student_id = (int*) malloc (num * sizeof(int));
char *grade;
grade = (char*) malloc (num * sizeof(char));
double *gpa;
gpa = (double*) malloc (num * sizeof(double));
printf("\n%d", num);
for(int i = 0; i < num; i++)
{
fscanf(fp, "%d %c %lf", &student_id[i], &grade[i], &gpa[i]);
}
}

First, you need to give the filename, and then for reading the GPA (double) value you need to use %lf, also there is an extra ',' after the %d. The following code fixed all these bugs. Hopes it help
FILE *fp;
fp = fopen('YOUR FILE NAME', "r");
int num;
fscanf(fp, "%d%[^\n]", &num);
printf("\n%d", num);
int *student_id;
student_id = (int*) malloc (num * sizeof(int));
char *grade;
grade = (char*) malloc (num * sizeof(char));
double *gpa;
gpa = (double*) malloc (num * sizeof(double));
printf("\n%d", num);
for(int i = 0; i < num; i++)
{
fscanf(fp, "%d %c %lf%[^\n]", &student_id[i], &grade[i], &gpa[i]);
}

Related

Saving integers from a file into an array

I was hoping to get a bit of help, I am implementing an inversion counter algorithm to take in 50,000 intergers and display the inversions and time it took to run the algorithm, I am having a hard time allocating and saving the integers from the file into an array. My code complies and runs but nothing happens
here is what I have:
int main(int argc, char** argv)
{
int n, i;
int inversions=0;
int *A;
FILE *file;
char filename[100];
clock_t start, end;
double totalTime;
printf("Enter filename: ");
scanf("%s", filename);
file = fopen(filename, "r");
if(file == NULL)
{
printf("Error opening file!\n");
return 0;
}
fscanf(file, "%d", &n);
A = (int*) malloc(n * sizeof(int));
for(i = 0; i < n; i++) {
fscanf(file, "%d", &A[i]);
}
start = clock();
inversions = countInversionsBruteForce(A, n);
end = clock();
totalTime = (double) (end - start) / CLOCKS_PER_SEC;
printf("Brute Force Algorithm\n");
printf("Number of inversions: %d\n", inversions);
printf("Execution time: %f\n", totalTime);
I think I have noth allocated array size and saved it properly
Your program is incomplete so I was not able to compile it. Minimized the problem to just loading the data into your array:
Formatted code for readability.
Generated a suitable input file. Most likely this is your problem but you have not shared your input sample with us.
Added missing include files.
Remove argc, argv as you not using them.
Minimize scope of variables. Use size_t instead of int for unsigned values.
Max string size on obtaining file name
Check return value for scanf(), fopen(), fscanf().
Printing out the data read to demonstrate it's working.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
printf("Enter filename: ");
char filename[100];
if(scanf("%99s", filename) != 1) {
printf("scanf failed\n");
return 1;
}
FILE *file = fopen(filename, "r");
if(!file) {
printf("Error opening file!\n");
return 1;
}
size_t n;
fscanf(file, "%zu", &n);
if(!n) {
printf("n must be positive");
return 1;
}
int *A = malloc(n * sizeof(*A));
for(size_t i = 0; i < n; i++)
if(fscanf(file, "%d", &A[i]) != 1) {
printf("fscanf() failed\n");
return 1;
}
printf("n = %zu\n", n);
printf("A = ");
for(size_t i = 0; i < n; i++)
printf("%d%s", A[i], i + 1 < n ? ", " : "\n");
}
with 1.txt as:
4
1
2
3
4
a sample session looks like this:
Enter filename: 1.txt
n = 4
A = 1, 2, 3, 4

Reading a file and finding the largest integer in C

int main()
{
int* ptr;
int numofstu;
printf("Please enter the number of students: \n");
scanf("%d", &numofstu);
ptr = (int*) malloc(numofstu * sizeof(int));
FILE* fptr;
if ((fptr = fopen("C:\\Users\\umut\\Desktop\\students.txt", "r")) == NULL)
{
printf("Error! opening file");
}
else
{
int highest=0;
for (int i = 0; i < numofstu; i++)
{
fscanf(fptr, "%d\n", &ptr[i]);
if (ptr[i] >highest )
ptr[i] = highest;
}
printf("%d", highest);
}
}
Hello Guys!
This is my second semester in C language but i'm still a amateur.
What is the problem of this code chunk. I am posting a new question because i coulnt found any similar resource to solve it?
Thanks in advance :)
Edit: There are 9 integers in students.txt and their order is like int newline int
Edit2: Result is 0 all the time.

How to read floats from file in c?

I am struggling with reading floats from a file which I created during the program lifetime. I was trying to rewind the file, I was trying to open and close file before reading it, I was trying to put values directly in the table and by another variable. Idk what can I do more, what's wrong here?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(NULL));
float *tab;
float x = 0.0;
int i, size;
FILE *fp;
fp = fopen("data.txt", "w+");
if (fp == NULL) {
printf("Error");
system("PAUSE");
exit(1);
}
printf("Size of table: ");
scanf("%d", &size);
tab = (int*)malloc(size * sizeof(int));
for (i = 0; i < size; i++) {
tab[i] = (8.0 - 2.0) * (float)rand() / RAND_MAX + 2.0;
fprintf(fp, "%.2f ", tab[i]);
}
for (i = 0; i < size; i++) {
printf("%.2f ", tab[i]);
}
printf("\n");
fp = fclose;
fp = fopen("data.txt", "w+");
tab = realloc(tab, 2*size);
for (i = 0; i < size * 2; i+=2) {
fscanf(fp, "%f", &x);
printf("%.2f ", x);
//tab[i + 1] = tab[i] / 2;
}
/*for (i = 0; i < size * 2; i++) {
printf("%.2f \n", tab[i]);
}*/
fp = fclose;
printf("\n");
system("PAUSE");
return 0;
}
There are a number of problems in this code. First, as noted in the comments, the initial allocation is wrong. You are allocating space for floats, not ints. You could have avoided this problem entirely if you had written the call to malloc() like this:
tab = malloc(sizeof(*tab) * size);
Here, the result of malloc() is not cast, since it is not necessary in C. Also, note that instead of using an explicit type for the argument to the sizeof operator, the identifier is used instead. This guarantees that whatever the type of tab, which must be a pointer, the result of sizeof will be correct. Also, you should always check to see if an allocation was successful.
fp = fclose is just wrong. This should be fclose(fp). After this, when you open the file again with "w+", the file is truncated to zero length, and you lose the data that was previously written. Since the file has already been opened with "w+", just use rewind(fp) here.
For the reallocation that you do, aside from that the arguments are not quite right here, there is a potential problem that you should be aware of. realloc() can return a null pointer in the event of an allocation error. If this happens, and you are directly assigning the result of realloc() to the pointer for which you are reallocating (tab), then you will lose the reference to previously allocated memory. This is a memory leak, and lost data. The way to do this is to store the result of realloc() in a temporary pointer, which you test. If the temporary pointer is a null pointer, there was an error; otherwise you can safely assign the return value to the original pointer.
And as already noted, when you call fclose() the final time, it needs to be fclose(fp).
Here is a modified code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(NULL));
float *tab, *temp; // added temp for realloc() check
float x = 0.0;
int i, size;
FILE *fp;
fp = fopen("data.txt", "w+");
if (fp == NULL) {
printf("Error");
system("PAUSE");
exit(1);
}
printf("Size of table: ");
scanf("%d", &size);
/* You should always check for allocation errors */
if ((tab = malloc(sizeof(*tab) * size)) == NULL) {
fprintf(stderr, "Error in initial allocation\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < size; i++) {
tab[i] = (8.0 - 2.0) * (float)rand() / RAND_MAX + 2.0;
fprintf(fp, "%.2f ", tab[i]);
}
for (i = 0; i < size; i++) {
printf("%.2f ", tab[i]);
}
printf("\n");
// fclose(fp); // not fp = fclose;
// fp = fopen("data.txt", "w+"); // when you reopen, the file is truncated
rewind(fp); // but just do this
/* Fixed this reallocation */
temp = realloc(tab, sizeof(*tab) * size * 2);
if (temp == NULL) {
fprintf(stderr, "Error in reallocation\n");
exit(EXIT_FAILURE);
}
tab = temp;
for (i = 0; i < size * 2; i+=2) {
fscanf(fp, "%f", &x);
printf("%.2f ", x);
//tab[i + 1] = tab[i] / 2;
}
/*for (i = 0; i < size * 2; i++) {
printf("%.2f \n", tab[i]);
}*/
fclose(fp); // not fp = fclose;
printf("\n");
system("PAUSE");
return 0;
}
Sample interaction:
Size of table: 10
2.65 5.67 5.21 3.22 3.07 4.29 5.96 5.96 5.15 7.36
2.65 5.67 5.21 3.22 3.07 4.29 5.96 5.96 5.15 7.36

fscanf to read an array of floats, but only getting first number in array

Reading a file, first number is an int that's the size of the array, then the rest are double
Here is the function:
void read1dascii(double** a, int* m, char* infile)
{
FILE * fp = fopen(infile, "r");
fscanf(fp, "%d", m);
alloc1d(a, *m);
fscanf(fp, "%lf\n", *a);
fclose(fp);
}
Here is the alloc1d function it calls:
void alloc1d(double** a, int m)
{
*a = malloc(sizeof(double) * m);
}
I'm getting the first number which is the size and then the first number in array, but then the rest are reading in as zeros.
You need to read all of them using loop.
int i;
for (i = 0; i < *m; ++i) {
fscanf(fp, "%lf", *a + i);
}
fscanf(fp, "%lf\n", *a);
Here you are only reading once, so it's just receiving the first float, to read the rest of the array, you need something like
while ( fscanf(fp, "%lf\n", &a) == 1 )
{
/* do stuff with 'a' here */
}

double dimensional array as return value

For my homework, I have to read data from an input file and to store it in a double dimensional array and then pass this array to another function. This is what I have tried so far, but I don't know when I call this function in main it gives the error:
Access violation writing location 0x00000000.
I have tried to dynamically allocate memory and it gives the same error. What I am doing wrong?
The last update of the code:
#include<stdio.h>
#include<stdlib.h>
int *a[2];
void getData(void)
{
FILE *fp = fopen("input.txt", "r");
int number;
fscanf(fp, "%d", &number);
for (int i = 0; i < number; i++)
{
a[i]=(int*)malloc(number * sizeof (int));
fscanf(fp, "%d %d", &a[i][0], &a[i][1]);
}
fclose(fp);
}
int main()
{
getData();
for(int i=0;i<8;i++)
{
printf("%d %d\n",a[i][0],a[i][1]);
}
}
You need to allocate memory for a
Before the for loop
a = (int **)malloc(number * sizeof(int *))
You are not allocating the first dimension, ie a is a null pointer when you are trying to dereference it.
#include <stdlib.h>
a = malloc(number * sizeof *a);
BTW, sizeof(int) is not sufficient to store two numbers.
#include <stdlib.h>
a[i] = malloc(2 * sizeof *a[i]);
fscanf(iFile, "%d %d", &a[i][0], &a[i][1]);
Here is a whole correct code (although not perfect, as long as a is an hugly global variable):
int (*a)[2] = NULL;
void getData(void)
{
FILE *fp = fopen("input.txt", "r");
int number;
fscanf(fp, "%d", &number);
a = malloc(number * sizeof *a);
for (int i = 0; i < number; i++)
fscanf(fp, "%d %d", &a[i][0], &a[i][1]);
fclose(fp);
}

Resources