c语言 - 动态分配和结构 - 将内存动态分配给结构中的字符串



我有一个关于动态分配和结构的问题。 任务:我有一个学生结构,看起来像这样:

typedef struct{
unsigned id;
char *lastName;
float grade;
}students_t;

我不允许向 lastName 传递最大数量的字符,它必须保持一个指针,我每次都会增加大小。

我的代码如下所示:

unsigned counter = 0;
students_t* students = NULL;
students_t temp;
char char_current;
unsigned char_counter=0;
while (fscanf(inputFile,"%u",&temp.id) == 1) {
students = realloc(students,(counter+1) * sizeof(students_t));
students[counter].id=temp.id;
printf("%d",students[counter].id);
students[counter].lastName = NULL;
while (fscanf(inputFile,"%c",&char_current) != ' ') {
students[counter].lastName = realloc(students[counter].lastName,(char_counter+1) * sizeof(char));
students[counter].lastName[char_counter] = char_current;
char_counter++;
}
students[counter].lastName[char_counter] = '';
fscanf(inputFile,"%f",&students[counter].grade);

counter++;
}

我的问题出在whilefscanf(因为程序进入无限循环(,但我不知道如何实际解决它。

如果有人能帮助我弄清楚,我将不胜感激。 谢谢!

您有几个问题:

  1. while(( 循环没有终止(您的初始问题(。
  2. fscanf(( 是不安全的 - 有更好的选择。
  3. 您错误地使用了 fscanf((。
  4. 一次
  5. 读取一个字符串是低效的。
  6. 反复调用"realloc(("是低效的 - 有更好的选择。

下面是一些示例代码。

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#define MAX_STRING 80
typedef struct {
unsigned id;
char *lastName;
float grade;
} students_t;
students_t* enter_new_student (FILE *inputFile)
{
char buffer[MAX_STRING];
unsigned id;
int iret;
// Check for end of input
iret = fscanf(inputFile, "%u", &id);
if ((iret < 1) || feof(inputFile)) {  // iret should be "1" if successful
return NULL;
}
// Allocate a record and read its data
students_t *student = (students_t *)malloc(sizeof(students_t));
iret = fscanf(inputFile, "%s %f", buffer, &student->grade); // iret should be "2" if successful
student->id = id;
student->lastName = strdup(buffer);   // strdup() does an implicit "malloc()" and "strcpy()"
// Return new student
return student;
}
int main()
{
students_t *student = NULL;
int record_counter = 0;
FILE *fp;
// Open file
if (!(fp = fopen("tmp.txt", "r"))) {
perror("unable to open file");
return 1;
}
// Read student records
while ((student = enter_new_student(fp))) {
if (student) {
++record_counter;
printf("new student=%s,id=%u, grade=%f, record_counter=%dn",
student->lastName, student->id, student->grade, record_counter);
}
}
// Done
printf("Done: final record count=%dn", record_counter);
return 0;
}

下面是一个示例"tmp.txt"文件:

1 Johnson 4.0
2 Jackson 3.5
3 Jamison 3.85

以及相应的样本输出:

new student=Johnson,id=1, grade=4.000000, record_counter=1
new student=Jackson,id=2, grade=3.500000, record_counter=2
new student=Jamison,id=3, grade=3.850000, record_counter=3

一般来说,更喜欢使用 fgets(( 而不是 fscanf((: scanf 的缺点

请注意,我将与读取学生记录有关的所有内容都放在一个单独的函数中:enter_new_student()。 您还会注意到"控制结构" - "while 循环"在函数之外

有两种(相关(条件可能导致循环退出:

  1. 没有读"id">
  2. 文件结尾

您最初的"while循环"失败的原因是fscanf()永远不会返回' '......所以你无意中编码了一个"无限循环"。 原因如下:

https://linux.die.net/man/3/fscanf

返回值

这些函数返回成功匹配和分配的输入项数,该数可以少于提供的输入项数 for,在早期匹配失败的情况下甚至为零。

如果在以下任一之前到达输入结束,则返回值 EOF 发生第一次成功转换或匹配失败。EOF是 如果发生读取错误,也返回,在这种情况下,错误 设置了流的指示符(参见 ferror(3((,并设置了 errno 指示错误。

相关内容

  • 没有找到相关文章

最新更新