【问题标题】:Storing input from file into struct in C将文件中的输入存储到C中的结构中
【发布时间】:2021-02-02 12:53:58
【问题描述】:

所以我有一个正在扫描的输入文件。我还有一个结构数组。我需要将此输入中的信息存储到结构中。我能够读取输入文件并将其打印出来,但我不确定如何将这些信息存储在我的结构中。问题似乎是我无法在扫描文件的函数中正确访问我的结构。下面是我的代码。

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

/* make an array of structs that contain the ponds, and the ponds contain pointers to the circular lists */

struct pond_struct {
    char name[20];
    int sequence;
    int failfish;
    int eatingcounter;
    int threshold;
    struct pond_struct *next;
    struct pond_struct *prev;
};

typedef struct pond_struct pond;

struct pond_list_struct {
    pond *head;
    pond *tail;
};

typedef struct pond_list_struct pond_list;

int get_number_of_ponds(FILE *ifp) 
{
    char s[128];
    int num;
    
    //get the first line of the file
    fgets (s, 127, ifp);

    if(isspace(s[0]))
    {
        fgets (s, 127, ifp);
    }
    
    sscanf(s, "%d", &num);
    
    return num;
}

void remove_crlf(char *s)
{
    char *t = s + strlen(s);

    // t begins at the null sentinel at the end of s.

    t--;

    /* t is now at the last character of s - unless s didn't contain any characters, in which
       case, t is now *BEFORE* s.  We have to keep checking for that. */

    /* We repeat until EITHER t slides to the left of s, OR we find a character that is not a
       line feed (\n) or a carriage return (\r). */

    while ((t >= s) && (*t == '\n' || *t == '\r'))
    {
        *t = '\0'; // Clobber the character t is pointing at.
        t--;      // Decrement t.
    }
}

void get_next_nonblank_line(FILE *ifp, char *s, int max_length)
{
    s[0] = '\0';

    while (s[0] == '\0')
    {
        fgets(s, max_length, ifp);
        remove_crlf(s);
    }
}

void read_pond (FILE *ifp, FILE *ofp, pond ponds)
{
    char s[128];
    char full_line[128];
    int nponds;
    int i;
    int pond_number;
    char name[128];
    //char sequence_string[128];
    int sequence;
    //char failfish_string[128];
    int failfish;
    //char eatingcounter_string[128];
    int eatingcounter;
    //char threshold_string[128];
    int threshold;
    
    nponds = get_number_of_ponds(ifp);
    printf("There are %d ponds\n", nponds);
    fprintf(ofp, "There are %d ponds\n", nponds);
    
    for (i = 0; i < nponds; i++)
    {
        get_next_nonblank_line(ifp, full_line, 127);
        sscanf(s, "%d %s %d %d %d", &pond_number, name, &failfish, &eatingcounter, &threshold);
        printf("The pond name is %s\n", full_line);
    }
}

/* void print_pond (FILE *ofp, pond ponds, char* name, int sequence, int failfish, int eatingcounter, int threshold)
{
    fprintf(ofp, "%s is pond number %d. The number of failfish is %d, the eating counter is %d, and the threshold is %d\n", name, sequence, failfish, eatingcounter, threshold);
} */

int main (void)
{
    
    FILE *ifp;
    FILE *ofp;
    
    int nponds;
    int i;
    char name[128];
    int sequence;
    int failfish;
    int eatingcounter;
    int threshold;
    
    pond ponds[10];
    
    // change input file name
    ifp = fopen("input.txt", "r");
    ofp = fopen("output.txt", "w");
    
    read_pond(ifp, ofp, ponds[0]);
    
    /* for (i = 0; i < nponds; i++)
    {
        print_pond(ofp, ponds[i], name, sequence, failfish, eatingcounter, threshold);
    } */
    
    fclose(ifp);
    fclose(ofp);
    
    return 0;
}

【问题讨论】:

  • 发布的代码包含大量未使用的变量和参数。发布的代码缺少声明; #include &lt;ctype.h&gt;isspace() 函数所需要的
  • 您想将指向您的池塘表的指针传递给加载函数。您正在传递表格中的第一个条目。
  • 除了缺少几乎所有的错误检查之外,对于是否加载链表、数组、单个实例还是在未使用的情况下加载一些明显的混淆 by- read_pond 中的值参数 ponds,以上都不是。例如,read_pond 中的 sscanf 加载了一些局部变量(我们希望,因为没有错误检查),然后立即将它们全部丢弃。
  • 关于:ifp = fopen("input.txt", "r");ofp = fopen("output.txt", "w"); 对于健壮的代码,请始终立即检查 (!=NULL) 返回值以确保操作成功。如果不成功(==NULL)则调用perror( "fopen for input file failed" );,然后清理,然后调用exit( EXIT_FAILURE );
  • @johnelemans 加载函数是什么意思?你指的是我的输入文件吗?

标签: c input struct io


【解决方案1】:

typedef struct { int nMyInt; char szDate[6]; char filler[2]; } _MY_STRUCT; _MY_STRUCT stMS; stMS.nMyInt = 2; strcpy(stMS.szDate,"10/19/2020");

  1. 使用填充符更新您的结构,使字节对齐存储为 8 个字节。
  2. 将 &stMS 与 fread/fwrite 和 sizeof(_MY_STRUCT) 一起使用来读取/写入数据。

【讨论】:

  • 在发布的代码中,是否有任何证据表明数据存储为机器相关形式的打包八位字节流?恰恰相反,从字面上看,OP 发布代码中的 everything 表示数据作为 text 进行存储、读取和(未成功)处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-19
  • 2017-06-25
  • 1970-01-01
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多