I'm trying to read the data from .txt file into struct array and then writing some of this data into another .txt file using said array.
My code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 5 // max array size
//C:\\Users\\PATOX\\Desktop\\uczniowie.txt
struct para
{
char name[15];
int grade;
};
int read(FILE* file, struct para tab[], int m, int *k) {
FILE* output;
char path[80];
printf("Enter input file path: ");
scanf_s("%s", path, 80);
file = fopen(path, "r");
if (file == NULL)
{
printf("\nError opening input file\n");
return 1;
}
else
{
char path[80];
printf("Enter output file path: ");
scanf_s("%s", path, 80);
output = fopen(path, "w");
if (output == NULL)
{
printf("\nError opening output file\n");
return 1;
}
for (int i = 0; i < m; i++)
{
if (!feof(file))
{
int index;
char name[15];
int grade;
fscanf(file, "%d %s %d", &index, name, &grade);
strcpy(tab[i].name, name);
tab[i].grade = grade;
fwrite(&(tab[i]), sizeof(struct para), 1, output);
(*k)++;
}
}
}
fclose(file);
fclose(output);
return 0;
}
void print_array(struct para tab[], int m) {
for (int i = 0; i < m; i++)
{
printf("%s %d\n", tab[i].name, tab[i].grade);
}
}
int main() {
int k = 0; //data counter
FILE* file;
struct para tab[5];
read(&file, tab, MAX, &k);
print_array(tab, k);
return 0;
}
When I check the output .txt file the data is here, however only .name is written as expected, the second item is written as some artifact:
Expected (output.txt)
Drozd 4 Jas 5 Tom 6 Bas 8
Actual (output.txt) (output.txt)
Drozd ÌÌÌÌÌÌÌÌÌÌ Jas ÌÌÌÌÌÌÌÌÌÌÌÌ Tom ÌÌÌÌÌÌÌÌÌÌÌÌ Bas ÌÌÌÌÌÌÌÌÌÌÌÌ
In trying out your program experimenting with various methods of pushing the structure data to a text output file, I could not successfully produce an output data file file with just text data. My experience with outputting structures to a file, the file is usually defined as a binary file rather than a text file.
With that in mind, I did a bit of refactoring of your program to output the data as text data. Following is a listing of the refactored code.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 20 // max array size
//C:\\Users\\PATOX\\Desktop\\uczniowie.txt
struct para
{
char name[15];
int grade;
};
int readx(FILE* filex, struct para tab[], int m, int *k)
{
FILE* output;
char path[80];
int check = 0;
printf("Enter input file path: ");
check = scanf("%s", path);
filex = fopen(path, "r");
if (filex == NULL)
{
printf("\nError opening input file\n");
return 1;
}
else
{
char path[80];
printf("Enter output file path: ");
check = scanf("%s", path);
output = fopen(path, "w");
if (output == NULL)
{
printf("\nError opening output file\n");
return 1;
}
for (int i = 0; i < m; i++)
{
if (!feof(filex))
{
int index;
char name[15];
int grade;
check = fscanf(filex, "%d %s %d", &index, name, &grade);
if (check < 0) /* Exit loop if no more data is found */
{
break;
}
strcpy(tab[i].name, name);
tab[i].grade = grade;
/* fwrite(&(tab[i]), sizeof(struct para), 1, output); */
/* Use fprintf instead for text type output */
fprintf(output, "%s %d\n", name, grade);
(*k)++;
}
}
}
fclose(filex);
fclose(output);
return 0;
}
void print_array(struct para tab[], int m)
{
for (int i = 0; i < m; i++)
{
printf("%s %d\n", tab[i].name, tab[i].grade);
}
}
int main()
{
int k = 0; //data counter
FILE* filex = NULL;
struct para tab[MAX]; /* Sized for maximum allowable structure size */
readx(filex, tab, MAX, &k);
print_array(tab, k);
return 0;
}
Following are some items to note.
With that, the following file set was built for testing.
Following was the sample grade data.
1 Craig 88
2 Kelly 92
3 Kurt 78
4 Lisa 94
5 Benjamin 89
6 Troy 91
7 Isaac 97
8 William 78
9 Elsie 85
10 Winston 75
Following is sample terminal output testing this refactored code.
@Vera:~/C_Programs/Console/TextWrite/bin/Release$ ./TextWrite
Enter input file path: Sample.txt
Enter output file path: Grades.txt
Craig 88
Kelly 92
Kurt 78
Lisa 94
Benjamin 89
Troy 91
Isaac 97
William 78
Elsie 85
Winston 75
Following is the text data that was placed into file "Grades.txt"
Craig 88
Kelly 92
Kurt 78
Lisa 94
Benjamin 89
Troy 91
Isaac 97
William 78
Elsie 85
Winston 75
So, to reiterate, if the output data should be in a textual format, probably the "fprintf" function would be used; otherwise, if the program truly needs to store each structure as a record, the program would want to utilize an output file defined as a binary file.
Hopefully, this refactored code meets the spirit of your project.