[英]In C, how can I pass the strings from a file into a string array. Notice that main objective is to order the students with respect to their id
The program given below is equalize all name and surname with last ones.下面给出的程序是将所有姓名和姓氏与最后一个相等。 The contents of the students.dat;
students.dat的内容;
2020102054 Name1 Surname1
2021202051 Name2 Surname2
2020302057 Name3 Surname3
2020802053 Name4 Surname4
2020602059 Name5 Surname5
2019452065 Name6 Surname6
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *stdFptr, *orderFptr;
int student_id ,temp_id[20],ordered_id[20], a=0,i,j;
char student_name[32], student_surname[32];
char *ordered_name[32],*ordered_surname[32],*temp_string[32];
stdFptr = fopen("students.dat","r");
orderFptr = fopen("order.dat","w");
if(!stdFptr || !orderFptr){
puts("File Error, Exiting The Program");
exit(0);
}
else{
puts("Before ordering");
fscanf(stdFptr, "%d %s %s ",&student_id,student_name,student_surname);
while(!feof(stdFptr)){
ordered_name[a] = student_name;
ordered_surname[a] = student_surname;
ordered_id[a] = student_id;
a++;
fprintf(stdout,"%d %s %s\n",student_id,student_name,student_surname);
fscanf(stdFptr, "%d %s %s ",&student_id,student_name,student_surname);
}
ordered_name[a] = student_name;
ordered_surname[a] = student_surname;
ordered_id[a] = student_id;
fprintf(stdout,"%d %s %s\n",student_id,student_name,student_surname);
for(i=0;i<a;i++){
for(j=i+1;j<=a;j++){
if(ordered_id[i]>ordered_id[j]){
temp_string[i] = ordered_name[i];
ordered_name[i] = ordered_name[j];
ordered_name[j] = temp_string[i];
temp_string[i] = ordered_surname[i];
ordered_surname[i] = ordered_surname[j];
ordered_surname[j] = temp_string[i];
temp_id[i] = ordered_id[i];
ordered_id[i] = ordered_id[j];
ordered_id[j] = temp_id[i];
}
}
}
rewind(stdFptr);
fclose(stdFptr);
}
stdFptr = fopen("students.dat","r");
if(!stdFptr || !orderFptr){
puts("File Error, Exiting The Program");
exit(0);
}
else{
puts("After ordering");
i=0;
while(i<=a){
fprintf(orderFptr,"%d\t%s\t\t\t%s\n",ordered_id[i],ordered_name[i],ordered_surname[i]);
fprintf(stdout,"%d %s %s\n",ordered_id[i],ordered_name[i],ordered_surname[i]);
i++;
}
fclose(stdFptr);
fclose(orderFptr);
}
return 0;
}
You have multiple errors in your program.您的程序中有多个错误。
Errors:错误:
ordered_name[a] = student_name;
You only have pointers in your array.你的数组中只有指针。 And you only have one single array for the name.
而且您只有一个数组作为名称。 That means you just assign the address of the same array to each of your entries in
ordered_name
.这意味着您只需将同一数组的地址分配给
ordered_name
中的每个条目。 Same for the other fields.其他领域也一样。
while(!feof(stdFptr)){
Just don't do this.只是不要这样做。 See Why is “while (?feof (file) )” always wrong?
请参阅为什么“while (?feof (file) )”总是错误的? why this is wrong.
为什么这是错误的。
temp_id[i] = ordered_id[i];
You use array temp_id
to swap your array entries.您使用数组
temp_id
来交换数组条目。 First of all, that is very inefficient as you only need a single variable, not an array.首先,这是非常低效的,因为你只需要一个变量,而不是一个数组。
Second, this is wrong because you only have 20 elements in temp_id
and ordered_id
but 32 elements in the other ordered*
arrays.其次,这是错误的,因为您在
temp_id
和ordered_id
中只有 20 个元素,而在另一个ordered*
arrays 中有 32 个元素。
Also you do not care about the number of entries in your file and might overflow both arrays.此外,您不关心文件中的条目数,并且可能会同时溢出 arrays。
Bad practice:不好的做法:
int student_id ,temp_id[20],ordered_id[20], a=0,i,j;
char student_name[32], student_surname[32];
char *ordered_name[32],*ordered_surname[32],*temp_string[32];
You are using corresponding arrays to store each field of your data sets.您正在使用相应的 arrays 来存储数据集的每个字段。 That is terrible to maintain.
维护起来太糟糕了。 Use a struct instead:
改用结构:
#define NAME_LENGTH 32
#define MAX_NUMBER 50
struct student {
int id;
char name[NAME_LENGTH];
char surname[NAME_LENGTH];
};
fscanf(stdFptr, "%d %s %s ",&student_id,student_name,student_surname);
You do not check the result of fscanf
which you should always do.你不检查你应该经常做的
fscanf
的结果。 Even better, use fgets
followed by sscanf
to parse your content.更好的是,使用
fgets
后接sscanf
来解析您的内容。
stdFptr = fopen("students.dat","r");
You open the file again after you already read all the content.阅读完所有内容后,您再次打开文件。 That's not needed.
那是不需要的。
Your sorting is also inefficient:您的排序也很低效:
for(i=0;i<a;i++){
for(j=i+1;j<=a;j++){
if(ordered_id[i]>ordered_id[j]){
This can be used to fully sort an unsorted array.这可用于对未排序的数组进行完全排序。 You do this for each new line.
您为每条新行执行此操作。 Therefore you can rely on the array being sorted.
因此,您可以依赖正在排序的数组。 You onle need to find the place where to put the new entry.
你只需要找到放置新条目的地方。 For this, a single loop would be sufficient.
为此,一个循环就足够了。
Or you can move that sorting after you have finished reading the file.或者您可以在阅读完文件后移动该排序。
You exit your program in case of an error but you don't report an error to the calling environment出现错误时退出程序,但不向调用环境报告错误
exit(0);
That is same as exit(EXIT_SUCCESS);
这与
exit(EXIT_SUCCESS);
. . If terminate due to an error, you should also indicate that condition.
如果由于错误而终止,您还应该指出该情况。
An improved version could look like this:改进后的版本可能如下所示:
#include <stdio.h>
#include <stdlib.h>
#define NAME_LENGTH 32
#define MAX_NUMBER 50
struct student {
int id;
char name[NAME_LENGTH];
char surname[NAME_LENGTH];
};
int main(void)
{
struct student students[MAX_NUMBER];
int count = 0;
FILE *infile = fopen("students.dat","r");
if (infile == NULL) {
fprintf(stderr, "Input file cannot be openend.");
exit(EXIT_FAILURE);
}
// PART 1: Read the file content
puts("Before ordering");
char line[2*NAME_LENGTH + 20];
while (fgets(line, sizeof (line), infile) != NULL
&& count < MAX_NUMBER)
{
int result = sscanf(line, "%d %31s %31s", &students[count].id, students[count].name, students[count].surname);
if (result != 3)
{
fprintf(stderr, "Invalid line ignored: <%s>", line);
}
else
{
fprintf(stdout,"%d %s %s\n", students[count].id, students[count].name, students[count].surname);
count++;
}
}
fclose(infile);
// PART 2: Sort the array
struct student temp;
for (int i = 0; i < count-1; i++) {
for (int j = i+1; j < count; j++) {
if (students[i].id > students[j].id) {
temp = students[i];
students[i] = students[j];
students[j] = temp;
}
}
}
// Note: You could also just use qsort() function from standard library.
// PART 3: Write to output file
FILE *outfile = fopen("order.dat","w");
if (outfile == NULL) {
fprintf(stderr, "Output file cannot be openend.");
exit(EXIT_FAILURE);
}
puts("After ordering");
for (int i=0; i < count; i++) {
fprintf(outfile,"%d\t%s\t\t\t%s\n", students[i].id, students[i].name, students[i].surname);
fprintf(stdout,"%d %s %s\n", students[i].id, students[i].name, students[i].surname);
}
fclose(outfile);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.