C 从文件中读取数据,并使用指针将数据放入动态结构中
我正在尝试制作一个程序来管理学生的信息。但由于缺乏c编程技巧,我不能很好地使用指针 以下是源代码:C 从文件中读取数据,并使用指针将数据放入动态结构中,c,pointers,gcc,struct,C,Pointers,Gcc,Struct,我正在尝试制作一个程序来管理学生的信息。但由于缺乏c编程技巧,我不能很好地使用指针 以下是源代码: #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int id; char fName[8]; char lName[8]; } Student; void main() { int size = 0; int i
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int id;
char fName[8];
char lName[8];
} Student;
void main()
{
int size = 0;
int i = 0;
/* get max lines */
scanf("%d", &size);
Student *students = (Student*) malloc(sizeof(Student) * size); // allocate whole table
Student *pointAt = students; // pointer used to point whole table by memory address
/* retrieves data from stdin */
for (i = 0; i < size; i++)
{
scanf("%d", &((*pointAt).id));
printf("recorded id at %d is %d\n", i, (*pointAt).id);
fgets((*pointAt).fName, sizeof((*pointAt).fName), stdin);
printf("recorded fName at %d is %s\n", i, (*pointAt).fName);
fgets((*pointAt).lName, sizeof((*pointAt).lName), stdin);
printf("recorded lName at %d is %s\n", i, (*pointAt).lName);
while (getchar() != '\n')
;
}
free(students);
}
2
11223344 Jennifer Smith
22334455 John Bob
a.out < test.txt
recorded id at 0 is 11223344
recorded fName at 0 is Jennif
recorded lName at 0 is er Smit
recorded id at 1 is 22334455
recorded fName at 1 is John B
recorded lName at 1 is ob
^Z
Suspended
for(i=0; i<size; i++) {
scanf("%d", &((*pointAt).id));
printf("recorded id at %d is %d\n", i, (*pointAt).id);
getchar();
fgets((*pointAt).fName, sizeof((*pointAt).fName), stdin);
printf("recorded fName at %d is %s\n", i, (*pointAt).fName);
getchar();
fgets((*pointAt).lName, sizeof((*pointAt).lName), stdin);
printf("recorded lName at %d is %s\n", i, (*pointAt).lName);
}
recorded id at 0 is 11223344
recorded fName at 0 is Jennifer
recorded lName at 0 is Smith
recorded id at 1 is 22334455
recorded fName at 1 is John Bob
recorded lName at 1 is Smith
*注意,这里第一行的2用于设置动态分配结构的大小,用于:Student students=(Student)malloc(sizeof(Student)*size);因为只有两个学生,詹妮弗和约翰
下面是我运行来测试这个的命令:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int id;
char fName[8];
char lName[8];
} Student;
void main()
{
int size = 0;
int i = 0;
/* get max lines */
scanf("%d", &size);
Student *students = (Student*) malloc(sizeof(Student) * size); // allocate whole table
Student *pointAt = students; // pointer used to point whole table by memory address
/* retrieves data from stdin */
for (i = 0; i < size; i++)
{
scanf("%d", &((*pointAt).id));
printf("recorded id at %d is %d\n", i, (*pointAt).id);
fgets((*pointAt).fName, sizeof((*pointAt).fName), stdin);
printf("recorded fName at %d is %s\n", i, (*pointAt).fName);
fgets((*pointAt).lName, sizeof((*pointAt).lName), stdin);
printf("recorded lName at %d is %s\n", i, (*pointAt).lName);
while (getchar() != '\n')
;
}
free(students);
}
2
11223344 Jennifer Smith
22334455 John Bob
a.out < test.txt
recorded id at 0 is 11223344
recorded fName at 0 is Jennif
recorded lName at 0 is er Smit
recorded id at 1 is 22334455
recorded fName at 1 is John B
recorded lName at 1 is ob
^Z
Suspended
for(i=0; i<size; i++) {
scanf("%d", &((*pointAt).id));
printf("recorded id at %d is %d\n", i, (*pointAt).id);
getchar();
fgets((*pointAt).fName, sizeof((*pointAt).fName), stdin);
printf("recorded fName at %d is %s\n", i, (*pointAt).fName);
getchar();
fgets((*pointAt).lName, sizeof((*pointAt).lName), stdin);
printf("recorded lName at %d is %s\n", i, (*pointAt).lName);
}
recorded id at 0 is 11223344
recorded fName at 0 is Jennifer
recorded lName at 0 is Smith
recorded id at 1 is 22334455
recorded fName at 1 is John Bob
recorded lName at 1 is Smith
问题是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int id;
char fName[8];
char lName[8];
} Student;
void main()
{
int size = 0;
int i = 0;
/* get max lines */
scanf("%d", &size);
Student *students = (Student*) malloc(sizeof(Student) * size); // allocate whole table
Student *pointAt = students; // pointer used to point whole table by memory address
/* retrieves data from stdin */
for (i = 0; i < size; i++)
{
scanf("%d", &((*pointAt).id));
printf("recorded id at %d is %d\n", i, (*pointAt).id);
fgets((*pointAt).fName, sizeof((*pointAt).fName), stdin);
printf("recorded fName at %d is %s\n", i, (*pointAt).fName);
fgets((*pointAt).lName, sizeof((*pointAt).lName), stdin);
printf("recorded lName at %d is %s\n", i, (*pointAt).lName);
while (getchar() != '\n')
;
}
free(students);
}
2
11223344 Jennifer Smith
22334455 John Bob
a.out < test.txt
recorded id at 0 is 11223344
recorded fName at 0 is Jennif
recorded lName at 0 is er Smit
recorded id at 1 is 22334455
recorded fName at 1 is John B
recorded lName at 1 is ob
^Z
Suspended
for(i=0; i<size; i++) {
scanf("%d", &((*pointAt).id));
printf("recorded id at %d is %d\n", i, (*pointAt).id);
getchar();
fgets((*pointAt).fName, sizeof((*pointAt).fName), stdin);
printf("recorded fName at %d is %s\n", i, (*pointAt).fName);
getchar();
fgets((*pointAt).lName, sizeof((*pointAt).lName), stdin);
printf("recorded lName at %d is %s\n", i, (*pointAt).lName);
}
recorded id at 0 is 11223344
recorded fName at 0 is Jennifer
recorded lName at 0 is Smith
recorded id at 1 is 22334455
recorded fName at 1 is John Bob
recorded lName at 1 is Smith
第一次修复后更改了部分源:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int id;
char fName[8];
char lName[8];
} Student;
void main()
{
int size = 0;
int i = 0;
/* get max lines */
scanf("%d", &size);
Student *students = (Student*) malloc(sizeof(Student) * size); // allocate whole table
Student *pointAt = students; // pointer used to point whole table by memory address
/* retrieves data from stdin */
for (i = 0; i < size; i++)
{
scanf("%d", &((*pointAt).id));
printf("recorded id at %d is %d\n", i, (*pointAt).id);
fgets((*pointAt).fName, sizeof((*pointAt).fName), stdin);
printf("recorded fName at %d is %s\n", i, (*pointAt).fName);
fgets((*pointAt).lName, sizeof((*pointAt).lName), stdin);
printf("recorded lName at %d is %s\n", i, (*pointAt).lName);
while (getchar() != '\n')
;
}
free(students);
}
2
11223344 Jennifer Smith
22334455 John Bob
a.out < test.txt
recorded id at 0 is 11223344
recorded fName at 0 is Jennif
recorded lName at 0 is er Smit
recorded id at 1 is 22334455
recorded fName at 1 is John B
recorded lName at 1 is ob
^Z
Suspended
for(i=0; i<size; i++) {
scanf("%d", &((*pointAt).id));
printf("recorded id at %d is %d\n", i, (*pointAt).id);
getchar();
fgets((*pointAt).fName, sizeof((*pointAt).fName), stdin);
printf("recorded fName at %d is %s\n", i, (*pointAt).fName);
getchar();
fgets((*pointAt).lName, sizeof((*pointAt).lName), stdin);
printf("recorded lName at %d is %s\n", i, (*pointAt).lName);
}
recorded id at 0 is 11223344
recorded fName at 0 is Jennifer
recorded lName at 0 is Smith
recorded id at 1 is 22334455
recorded fName at 1 is John Bob
recorded lName at 1 is Smith
尝试解决以下两个问题:
fgets
也将“\0”计算为另一个字符。
所以它认为“jennifer\0”有9个字符长。因此,增加
fname的大小为9个字符,以容纳整个字符串getchar()
使用它尝试解决以下两个问题:
fgets
也将“\0”计算为另一个字符。
所以它认为“jennifer\0”有9个字符长。因此,增加
fname的大小为9个字符,以容纳整个字符串getchar()
使用它fgets
完全按照您的要求执行。传递并声明一个八个字符的缓冲区。上一次读取是一个scanf%d
,因此它在第一个非数字字符(此处为空格)上停止。然后将输入流定位到jennifer…
(注意初始空格!)fgets
读取7个字符,并在第8个位置放置一个终止null,该位置给出:
1 2 3 4 5 6 7 8
J e n n i f \0
如何修复?停止混合fgets
和scanf
。。。并增加缓冲区的大小。由于最长的名称为Jennifer(8个字符),因此包含终止null的最小大小为9。还要避免这种可怕的黑客行为:while(getchar()!='\n';
,如果文件不是由\n
终止的,或者如果最后一个\n
被fgets
吃掉,这将导致无限循环
最后但并非最不重要的一点是,控制输入函数(如scanf)的返回值。还需要main返回一个int而不是void,并且malloc返回值不应在C中强制转换
固定代码可能如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int id;
char fName[12];
char lName[12];
} Student;
int main()
{
int size = 0;
int i = 0;
/* get max lines */
int cr = scanf("%d", &size);
if (cr != 1) {
fprintf(stderr, "Incorrect size");
return 1;
}
Student *students = malloc(sizeof(Student) * size); // allocate whole table
Student *pointAt = students; // pointer used to point whole table by memory address
/* retrieves data from stdin */
for (i = 0; i < size; i++)
{
cr = scanf("%d%11s%11s", &(pointAt->id),pointAt->fName, pointAt->lName);
if (cr != 3) {
fprintf(stderr, "Incorrect format line %d\n", i+1);
return 1;
}
printf("recorded id at %d is %d\n", i, (*pointAt).id);
printf("recorded fName at %d is %s\n", i, (*pointAt).fName);
printf("recorded lName at %d is %s\n", i, (*pointAt).lName);
pointAt += 1; // point to next struct in array
}
free(students);
return 0;
}
#包括
#包括
#包括
类型定义结构
{
int-id;
char-fName[12];
字符名称[12];
}学生;
int main()
{
int size=0;
int i=0;
/*获取最大行数*/
int cr=scanf(“%d”和大小);
如果(cr!=1){
fprintf(标准“尺寸不正确”);
返回1;
}
Student*students=malloc(sizeof(Student)*size);//分配整个表
Student*pointAt=students;//用于按内存地址指向整个表的指针
/*从stdin检索数据*/
对于(i=0;iid)、pointAt->fName、pointAt->lName);
如果(cr!=3){
fprintf(stderr,“不正确的格式行%d\n”,i+1);
返回1;
}
printf(“在%d处记录的id是%d\n”,i,(*pointAt).id);
printf(“在%d处记录的fName是%s\n”,i,(*pointAt).fName);
printf(“在%d处记录的lName是%s\n”,i,(*pointAt).lName);
pointAt+=1;//指向数组中的下一个结构
}
免费(学生);
返回0;
}
fgets
完全按照您的要求执行。您传递并声明一个八个字符的缓冲区。上一次读取是一个扫描%d
,因此它在第一个非数字字符(这里是空格)上停止。然后输入流定位在Jennifer…
(注意初始空格!).fgets
读取7个字符,并在第8个位置放置一个终止null,该位置给出:
1 2 3 4 5 6 7 8
J e n n i f \0
如何修复?停止混合fgets
和scanf
…并增加缓冲区的大小。由于最长的名称是Jennifer(8个字符),包含终止null的最小大小是9。同时也避免了可怕的攻击:while(getchar()!='\n';
如果文件没有被\n
终止,或者最后一个\n
被fgets吃掉,则保证导致无限循环
最后但并非最不重要的一点是,控制输入函数(如scanf)的返回值。还需要main返回一个int而不是void,并且malloc返回值不应在C中强制转换
固定代码可能如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int id;
char fName[12];
char lName[12];
} Student;
int main()
{
int size = 0;
int i = 0;
/* get max lines */
int cr = scanf("%d", &size);
if (cr != 1) {
fprintf(stderr, "Incorrect size");
return 1;
}
Student *students = malloc(sizeof(Student) * size); // allocate whole table
Student *pointAt = students; // pointer used to point whole table by memory address
/* retrieves data from stdin */
for (i = 0; i < size; i++)
{
cr = scanf("%d%11s%11s", &(pointAt->id),pointAt->fName, pointAt->lName);
if (cr != 3) {
fprintf(stderr, "Incorrect format line %d\n", i+1);
return 1;
}
printf("recorded id at %d is %d\n", i, (*pointAt).id);
printf("recorded fName at %d is %s\n", i, (*pointAt).fName);
printf("recorded lName at %d is %s\n", i, (*pointAt).lName);
pointAt += 1; // point to next struct in array
}
free(students);
return 0;
}
#包括
#包括
#包括
类型定义结构
{
int-id;
char-fName[12];
字符名称[12];
}学生;
int main()
{
int size=0;
int i=0;
/*获取最大行数*/
int cr=scanf(“%d”和大小);
如果(cr!=1){
fprintf(标准“尺寸不正确”);
返回1;
}
Student*students=malloc(sizeof(Student)*size);//分配整个表
Student*pointAt=students;//用于通过备忘录指向整个表的指针