C 从文件获取行,放入结构数组,打印内容(家庭作业)

C 从文件获取行,放入结构数组,打印内容(家庭作业),c,struct,getline,C,Struct,Getline,这是我的CS课程的作业, 我正在尝试编写一个代码,逐行读取文件并将输入放入struct元素中。struct如下所示: typedef char* Name; struct Room { int fStatus; Name fGuest; }; 可用状态为0,预订状态为1。如果房间可用,则名称将为空 有两个函数,一个用于读取值并将其放入struct元素,另一个用于打印 int openRoomFile() { FILE *roomFile; char

这是我的CS课程的作业, 我正在尝试编写一个代码,逐行读取文件并将输入放入struct元素中。struct如下所示:

typedef char* Name;
struct Room
{
    int     fStatus;
    Name    fGuest;
};
可用状态为0,预订状态为1。如果房间可用,则名称将为空

有两个函数,一个用于读取值并将其放入struct元素,另一个用于打印

int openRoomFile()
{
    FILE *roomFile;
    char *buffer = NULL;
    size_t length = 0;
    size_t count = 0;

    roomFile = fopen("roomstatus.txt", "r+");
    if (roomFile == NULL)
        return 1;

    while (getline(&buffer, &length, roomFile) != -1) {
        if (count % 2 == 0) {
            sscanf(buffer, "%d", &AllRooms[count].fStatus);
        } else {
            AllRooms[count].fGuest = buffer;
        }
        count++;
    }

    fclose(roomFile);
    free(buffer);
    return 0;
}
打印功能

void printLayout(const struct Room rooms[])
{
    for (int i=0; i<3; i++) {
        printf("%3d \t", rooms[i].fStatus);
        puts(rooms[i].fGuest);
    }
}
我将获得输出:

1   (null)
0   
0   (null)

我不知道出了什么问题,我是不是用正确的方式来阅读文件?每个代码都是从互联网上的不同来源改编的。

如果您的输入保证是有效的(就像我在CS类中的许多输入一样),我会使用类似这样的内容来读取文件

while(!feof(ifp)){
    fscanf(ifp,"%d%s",&AllRooms[i].fStatus, AllRooms[i].fGuest); //syntax might not be right here
                                                                //might need to play with the '&'s
                                                                //and maybe make the dots into
                                                                //arrows

     //do work here
    i++;
}

这是一个固定版本的
openRoomFile()



当您不再需要这些
fGuest
时,您应该免费调用它们。

您没有为名称分配内存。看看这个。在下面的示例中,没有包括对已分配内存的free()调用。一旦您觉得已经完成了所有房间数组中的每个指针,并且不再需要这些指针,您就需要从这些指针中调用free

#include<stdio.h>
#include<stdlib.h>

typedef char* Name;
struct Room
{
    int     fStatus;
    Name    fGuest;
}Room_t;
struct Room AllRooms[10];

int openRoomFile()
{
    FILE *roomFile;
    char *buffer = NULL;
    size_t length = 0;
    size_t count = 0;
    size_t itemCount = 0;

    roomFile = fopen("roomstatus.txt", "r+");
    if (roomFile == NULL)
        return 1;
    buffer = (char *) malloc(16); // considering name size as 16 bytes
    while (getline(&buffer, &length, roomFile) != -1) {
        if (count % 2 == 0) {
            sscanf(buffer, "%d", &AllRooms[itemCount].fStatus);
        } else {
            AllRooms[itemCount].fGuest = buffer;
        itemCount++;
        }
        count++;
    buffer = (char *) malloc(16); // considering name size as 16 bytes
    }

    fclose(roomFile);
    free(buffer);
    return 0;
}
void printLayout(const struct Room rooms[])
{
    int i;
    for (i=0; i<3; i++) {
        printf("%3d \t", rooms[i].fStatus);
        puts(rooms[i].fGuest);
    }
}

int main(void)
{
  openRoomFile();
  printLayout(AllRooms);
  // free all memory allocated using malloc()
  return 0;
}
#包括
#包括
typedef char*名称;
结构室
{
内部状态;
姓名fGuest;
}房间;;
结构房间所有房间[10];
int openRoomFile()
{
文件*roomFile;
char*buffer=NULL;
尺寸长度=0;
大小\u t计数=0;
大小\u t itemCount=0;
roomFile=fopen(“roomstatus.txt”、“r+”);
if(roomFile==NULL)
返回1;
buffer=(char*)malloc(16);//考虑名称大小为16字节
while(getline(&buffer,&length,roomFile)!=-1){
如果(计数%2==0){
sscanf(缓冲区、%d、&AllRooms[itemCount].fStatus);
}否则{
所有房间[itemCount].fGuest=缓冲区;
itemCount++;
}
计数++;
buffer=(char*)malloc(16);//考虑名称大小为16字节
}
fclose(roomFile);
自由(缓冲);
返回0;
}
无效打印布局(const struct Room rooms[])
{
int i;

对于(i=0;iOh,您错误地使用了
feof()
,请看您的右图,我记得不久前读到过这方面的内容。但是,如果保证您的文件一开始不是空的,您仍然可以绕过它。然后,不必在while循环中使用!feof(ifp),只需添加一个if(!feof(ifp)检查然后中断;在循环结束时。我知道这不是有史以来最优雅的代码,但它完成了任务。您也没有考虑
名称
类型的内存分配,这是一个伪装的
字符*
。您可以使用POSIX功能
%ms
,或者您可以使用或滚动自己的字符串duplicator。但您必须确保内存已分配到某个位置。您正在像筛子一样泄漏!您需要在循环中的第二个
buffer=NULL;
之前插入
free(buffer);
。(仍然需要第一个,以便第一个来宾的姓名不会被其他数据覆盖。)@leeduhem嗨!谢谢你的回答。只需要一个简单的问题,为什么我需要释放缓冲区,然后将其设置为null(在
sscanf
之后有3行).Dot
free
不允许分配内存吗?为什么在调用
free
后缓冲区仍然可用?顺便说一句,它按照我的要求编译和运行。@user3060941如果其第一个参数的解引用为
NULL
getline()
malloc
足够的内存来存储输入,并将该缓冲区的地址存储到其第一个参数所指向的指针。当您不再需要该缓冲区时,应释放它以防止内存泄漏。
int openRoomFile(void)
{
    FILE *roomFile;
    char *buffer = NULL;
    size_t length = 0;
    size_t count = 0;

    roomFile = fopen("roomstatus.txt", "r+");
    if (roomFile == NULL)
        return 1;

    while (1) {
        buffer = NULL;
        if (getline(&buffer, &length, roomFile) == -1) {
            break;
        }
        sscanf(buffer, "%d", &AllRooms[count].fStatus);
        free(buffer);

        buffer = NULL;
        if (getline(&buffer, &length, roomFile) == -1) {
            fprintf(stderr, "syntax error\n");
            return 1;
        }
        AllRooms[count].fGuest = buffer;
        count++;
    }

    fclose(roomFile);
    return 0;
}
#include<stdio.h>
#include<stdlib.h>

typedef char* Name;
struct Room
{
    int     fStatus;
    Name    fGuest;
}Room_t;
struct Room AllRooms[10];

int openRoomFile()
{
    FILE *roomFile;
    char *buffer = NULL;
    size_t length = 0;
    size_t count = 0;
    size_t itemCount = 0;

    roomFile = fopen("roomstatus.txt", "r+");
    if (roomFile == NULL)
        return 1;
    buffer = (char *) malloc(16); // considering name size as 16 bytes
    while (getline(&buffer, &length, roomFile) != -1) {
        if (count % 2 == 0) {
            sscanf(buffer, "%d", &AllRooms[itemCount].fStatus);
        } else {
            AllRooms[itemCount].fGuest = buffer;
        itemCount++;
        }
        count++;
    buffer = (char *) malloc(16); // considering name size as 16 bytes
    }

    fclose(roomFile);
    free(buffer);
    return 0;
}
void printLayout(const struct Room rooms[])
{
    int i;
    for (i=0; i<3; i++) {
        printf("%3d \t", rooms[i].fStatus);
        puts(rooms[i].fGuest);
    }
}

int main(void)
{
  openRoomFile();
  printLayout(AllRooms);
  // free all memory allocated using malloc()
  return 0;
}