我有一个应该读取文件的函数,将各行作为单独的元素放入数组中。然后它应该通过数组并将某些元素放在结构中的某些位置。
我差不多拥有它...当我去打印结构以确保它正确的一切时,会出现额外的字符!
这是文件中的内容:
123
pre
45
cse
67
345
ret
45
cse
56
这就是它的印刷品:
123
pre
45
cse
C
67
345
ret
45
cse
8
56
以下是代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct students //Defining structure for students
{
int id; //Students ID Number
char name[30]; //Students Name
int age; //Students Age
char dept[4]; //Studets Department
int grade; //Students Grade
};
int main()
{
struct students list[20];
FILE *f;
char line[30];
char **temp = NULL;
int num_righ = 0;
int id5;
int age5;
int grade5;
int i, k;
f = fopen("records.txt", "r");
while(fgets(line, sizeof (line), f) != NULL)
{
if (line != NULL)
{
num_righ++;
temp = (char**)realloc(temp, sizeof(char*) *num_righ);
temp[num_righ - 1] = strdup(line);
}
}
fclose(f);
k = 0;
i = 0;
while (temp[i] != NULL)
{
id5 = atoi(temp[i]);
list[k].id = id5;
i++;
strcpy(list[k].name, temp[i]);
i++;
age5 = atoi(temp[i]);
list[k].age = age5;
i++;
strcpy(list[k].dept, temp[i]);
i++;
grade5 = atoi(temp[i]);
list[k].grade = grade5;
i++;
k++;
}
for (i = 0; i < k; i++)
{
printf("%d\n", list[i].id);
printf("%s", list[i].name);
printf("%d\n", list[i].age);
printf("%s\n", list[i].dept);
printf("%d\n", list[i].grade);
}
}
答案 0 :(得分:4)
需要注意的一点是,'C'的十进制值是67,'8'的十进制值是56。 学生数组中的dept数组太小了。它抓取换行符,然后无法存储终止字符。 printf一直运行到等级整数,该整数打印为字符。
编辑:相反,你的数组不是太小,但fgets正在抓取新行,这会填充数组,阻止空终结符被正确存储。
答案 1 :(得分:1)
以下代码解决了多个问题 - 它不仅确保“安全”复制字符串(使用strncpy
,并使用'\0'
终止字符串),而且还确保您不要在内存中创建所有数据的第二个副本(不是玩具示例的问题,而是为什么从坏习惯开始)。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct students //Defining structure for students
{
int id; //Students ID Number
char name[30]; //Students Name
int age; //Students Age
char dept[4]; //Studets Department
int grade; //Students Grade
};
int main()
{
struct students list[20];
FILE *f;
char line[30];
char **temp = NULL;
int num_righ = 0;
int id5;
int age5;
int grade5;
int i, k=0;
char *newLine;
f = fopen("records.txt", "r");
int s = 0; // this is the "state" counter - it goes from 0 to 4, then back to 0
while(fgets(line, sizeof (line), f) != NULL)
{
newLine = strchr(line, '\n');
if(newLine) *newLine='\0'; // terminate string on the newline.
switch(s) {
case 0:
list[k].id = atoi(line);
break;
case 1:
strncpy(list[k].name, line, 30);
list[k].name[29]='\0'; // make sure it is terminated
break;
case 2:
list[k].age = atoi(line);
break;
case 3:
strncpy(list[k].dept, line, 3);
list[k].dept[3] = '\0'; // make sure it is terminated
break;
case 4:
list[k].grade = atoi(line);
break;
}
s++;
if (s == 5) {
s = 0;
k++; // if it's 5, go back to zero and start reading next structure
}
}
fclose(f);
for (i = 0; i < k; i++)
{
printf("id: %d\n", list[i].id);
printf("name: %s", list[i].name);
printf("age: %d\n", list[i].age);
printf("dept: %s\n", list[i].dept);
printf("grade: %d\n\n", list[i].grade);
}
}