【问题标题】:Reading data from file into structure in c programming language用c编程语言将数据从文件读取到结构中
【发布时间】:2021-09-05 17:10:28
【问题描述】:

我想从 txt 文件中读取数据并将这些数据保存在变量中,而不仅仅是打印输出。如何将文本文件中的这些数据保存在变量中? 我试过这样,但没有成功:

int value1 ; 
object2->value =&value1 ; 
*(object2->value) = value1 ; 

我的 txt 文件如下所示:

INT 
A
5

我的代码如下所示:

#include <stdio.h>
#include <stdlib.h> // For exit()

struct variable {
    char type[10];
    char name[10];
    int value;
};

int main(){

struct variable *object2=malloc(sizeof(struct variable));

    FILE * file= fopen("input.txt", "rb");
    if (file != NULL) {
        fread(object2, sizeof(struct variable), 1, file);
        fclose(file);
    }
    
    int value1 ;
    object2->value =&value1 ;
    *(object2->value) = value1 ;

    printf("%d\n",value1);

    printf("%s/%s/%d\n",object2->type,object2->name,object2->value);
    
    
    }

【问题讨论】:

  • 欢迎来到 StackOverflow!请拨打tour 并阅读“How to Ask”以了解本网站的运作方式。 -- 你考虑过使用fgets()sscanf() 来完成任务吗?如果你使用fread(),你需要你的输入文件与你的结构布局是二进制兼容的。通常它不能是文本文件。 -- 哦,你没有问问题。
  • 你陈述了你的目标,但不是你的问题。您需要就您遇到的问题提出具体问题。
  • @TomKarzes 我不知道如何将这些值保存在变量中,因为我不知道如何取消引用这些指针,例如在这里我试过这样: int value1 ;对象2->值=&值1; *(object2->value) = value1;它没有工作
  • @PPProgramer 编辑您的帖子以包含您的问题。
  • 我会在几秒钟内纠正所有问题,我将包括解决方案。我是新来的,很抱歉格式不好。

标签: c structure


【解决方案1】:

文件格式:

CHAR
B
6
INT
A
5
FLOAT
C
7

这是我的解决方案:

#include <stdio.h>
#include <stdlib.h> // For exit()
#include <string.h>

#define BUFF_SIZE 1024
#define NAME_TYPE_SIZE 10
#define VALUE_SIZE 20

#define NOT_ENOUGH_MEMORY 1
#define CANT_OPEN_FILE 2
#define FILE_ENDED 3
#define TOO_BIG_STR 4
#define CANT_FORMAT_VALUE 5
#define NOT_FOUND_LINE 6

#define SEARCH_NAME "A"

#pragma warning(disable : 4996) // for vs

struct variable {
    char type[NAME_TYPE_SIZE];
    char name[NAME_TYPE_SIZE];
    int value;
};

int find_var_in_file(char* file_path, char* find_name, struct variable* dest);

int main()
{
    struct variable* object2 = malloc(sizeof(struct variable));

    if (NULL == object2)
    {
        printf("not enough memory");
        return NOT_ENOUGH_MEMORY;
    }

    int error = find_var_in_file("input.txt", SEARCH_NAME, object2);

    if (CANT_OPEN_FILE == error)
    {
        return printf("can't open file");
    }

    if (error == 0)
    {
        // Printing data to check validity
        printf("read: type: %s name: %s value: %d", object2->type, object2->name, object2->value);
        int a = object2->value;
        // do stuff with a
    }
    else
    {
        if (error == NOT_FOUND_LINE)
        {
            printf("not find the var \"" SEARCH_NAME "\" in the file");
        }
        else
        {
            printf("error reading the file. error code: %d", error);
        }
    }

    free(object2);

    return 0;
}

int read_line(char* buffer, int buffer_size, char* dest, int dest_size, FILE* stream)
{
    if (!fgets(buffer, buffer_size, stream))
    {
        return NOT_FOUND_LINE;
    }

    int read_len = strlen(buffer);

    if ('\n' == buffer[read_len - 1])
    {
        if (read_len == 1)
        {
            return NOT_FOUND_LINE;
        }
        buffer[read_len - 1] = '\0'; // remove "\n" in the end
    }

    if (dest_size <= strlen(buffer)) // last chat is null
    {
        return TOO_BIG_STR;
    }

    strcpy(dest, buffer);

    // clear the read
    memset(buffer, '\0', read_len);

    return 0;
}

int find_var_in_file(char* file_path, char* find_name, struct variable* dest)
{
    char file_buffer[BUFF_SIZE] = { 0 }; // Buffer to store data
    FILE* stream = fopen(file_path, "r");
    if (NULL == stream)
    {
        return CANT_OPEN_FILE;
    }

    int error = 0;
    while (1)
    {
        // read type
        int read_type_result = read_line(file_buffer, BUFF_SIZE, dest->type, NAME_TYPE_SIZE, stream);
        if (read_type_result != 0)
        {
            error = read_type_result;
            break;
        }

        int read_name_result = read_line(file_buffer, BUFF_SIZE, dest->name, NAME_TYPE_SIZE, stream);

        if (read_name_result != 0)
        {
            error = read_name_result;
            break;
        }

        char value_buffer[VALUE_SIZE] = { 0 };
        int read_value_result = read_line(file_buffer, BUFF_SIZE, value_buffer, VALUE_SIZE, stream);
        if (read_value_result != 0)
        {
            error = read_value_result;
            break;
        }

        if (0 == strcmp(find_name, dest->name))
        {
            if (1 != sscanf(value_buffer, "%d", &dest->value))
            {
                error = CANT_FORMAT_VALUE;
            }
            break;
        }
    }

    fclose(stream);

    return error;
}

您只需要像在 main 中一样调用函数find_var_in_file。我遍历文件的所有行并搜索 var 名称。如果有格式错误或在文件中找不到 var 的名称,则返回错误代码。

【讨论】:

  • 这个程序会产生几个警告:return with no value, in function return non-void;格式 %s 需要 char * 类型的参数,但参数 {3,4} 的类型为 char (*)[5];未使用的变量count。另外:&amp;file_buffer 在调用中fread 可能会起作用,但通常这会写为file_buffer,因为当作为函数参数传递时,数组已经衰减为指向第一个元素的指针。
  • “另外,由于缓冲区溢出,sscanf 非常危险。” -- 您可以通过使用maximum field width 说明符来限制数据量来解决这个问题读入你的数组(例如,"%4s")。
  • 最后:您尝试从文件中读取 1024 字节,而不检查来自 fread 的返回大小或来自 sscanf 的转换匹配是否有效。
  • @Oka 感谢您的反馈!我试图解决这些警告。另外你的意思是什么:“格式 %s 需要 char 类型的参数,但参数 {3,4} 的类型为 char ()[5]”你能举个例子吗?在我的代码中?
  • 稍微冗长:object2-&gt;type 的类型为 char [10]10 个字符的数组),这意味着 &amp;object2-&gt;type 的类型为 char (*)[10]指针到 10 个字符的数组)。 *scanf 说明符 "%s(和 "%[]")期望 char *指向字符的指针)。当用作函数参数时,类型char [N] 会自然衰减char *。因此:&amp;object2-&gt;type 应该是 object2-&gt;type&amp;object2-&gt;name 应该是 object2-&gt;name。 (请注意,它目前有效,因为...reasons,但通常是错误的形式)。
【解决方案2】:

如果您尝试读取的文件是文本文件(在您的情况下),则使用fgets() 读取其内容。另外,如果其内容格式一致,则考虑使用sscanf() 进行解析。

我不明白您为什么使用指向struct variable 的指针来保存数据。您可以简单地使用struct variable 对象并使用. 访问其字段

您的代码应如下所示:

#include <stdio.h>
#include <stdlib.h> // For exit()
#include <string.h> // for strlen()

struct variable {
    char type[10];
    char name[10];
    int value;
};

int main()
{
    FILE *file = fopen("input.txt", "r");
    if (!file) {
        fprintf(stderr, "Could not read file\n");
        return 1;
    }

    struct variable object2;
    char buffer[1024];

    while (fgets(buffer, 1024, file)) {
        if (sscanf(buffer, "%9s %9s %d", object2.type, object2.name, &object2.value) != 3) {
            fprintf(stderr, "Error parsing file\n");
            fclose(file);
            return 1;
        }

        printf("%s %s %d\n", object2.type, object2.name, object2.value);
    }

    fclose(file);
}

现在,如果您想将文件的所有行存储到variables 以供以后使用,那么首先您需要计算文件中的行数(我们称之为n),然后,分配一个大小为n的动态数组。

【讨论】:

  • 谢谢。我会尝试这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-18
  • 1970-01-01
相关资源
最近更新 更多