【问题标题】:How to search for specific structure from Structures of data array and read using fread?如何从数据数组结构中搜索特定结构并使用 fread 读取?
【发布时间】:2015-05-26 15:17:09
【问题描述】:

我的文本文件是这样的,

Person.txt

John 
{
   sex = "Male";
   age = 23;
};

Sara 
{
   sex = "Female";
   age = 23;
};

stephan 
{
   sex = "Male";
   age = 25;
};

我想根据请求获取特定人员的数据。例如,我收到了获取 Stephan 数据的请求。我想,首先我需要阅读 person.txt 来搜索 Stephan,然后获取他的信息。我有点困惑使用 fread 以正确的方式做到这一点。这是我的代码,

struct personS
{
  int age;
  char sex[7];
} personS;

FILE *fp;
void check_person_data(const char *name, int *age, const char *sex)               
{
  PersonS *person;

  if((fp=fopen("Person.txt", "r")) == NULL)
    printf("File reading error\n");

  fseek(fp, 0, SEEK_END);
  size = ftell(fp);
  fseek(fp, 0, SEEK_SET);
  char buffer[size];

  while(fread(buffer, size, 1, fp) != NULL)
  {
   if((strstr(buffer, name)) != NULL)
   { 
     printf("Match found \n");
     fread(&person, sizeof(struct personS), 1, fp);    
     *age = person->age;
     *sex = person->sex;       
   }
   else
    printf("Match not found \n");        
  }   
 fclose(fp);
}

我做了两次 fread,一次是搜索字符串,另一次是获取结构。这是正确的做法还是其他更好的方法?

【问题讨论】:

  • 我建议您使用fgets 读取行数未知的文本文件。它将数据读取到(并包括)下一个换行符,因此尽管您需要足够的空间来读取该行,但您不需要知道它在 读取它之前有多长时间。另一方面,fread 通常用于已知大小的二进制信息。

标签: c struct fread fseek strstr


【解决方案1】:

该示例似乎是一个可以使用fgets()sscanf() 读取的文本文件。读取文件以查找匹配名称不需要该结构,因此将其省略。一旦读取了值,调用函数就可以将它们放入结构中。

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

int check_person_data(char *name, int *age, char *sex)
{
    char buffer[50] = {0};
    FILE *fp;

    if ( ( fp = fopen ( "person.txt", "r")) == NULL) {
        printf ( "file reading error\n");
        return 2;
    }

    while ( fgets ( buffer, sizeof ( buffer), fp)) {
        if ( buffer[0] == '\n') {
            continue;//blank line
        }
        if ( buffer[strlen(buffer)-1] == '\n') {
            buffer[strlen(buffer)-1] = '\0';//remove trailing newline
        }
        if ( strcmp ( buffer, name) == 0) {//found match
            while ( fgets ( buffer, sizeof ( buffer), fp)) {
                if ( strstr ( buffer, "sex")) {//does the line contain sex
                    if ( ( sscanf ( buffer, " %*[^\"\n]\"%6[^;\"\n]", sex)) != 1) {//scan and discard up to a ", scan " and scan up to six characters to next "
                        return 1;//bad record
                    }
                }
                if ( strstr ( buffer, "age")) {//does the line contain age
                    if ( ( sscanf ( buffer, " %*[^=\n]=%d", age)) != 1) {// scan and discard up to an =, scan = and scan an integer
                        return 1;//bad record
                    }
                }
                if ( strstr ( buffer, "};")) {//does the line contain };
                    break;//found end of record
                }
            }
            return 0;//found the matching name
        }
        else {//did not match. read the remaining lines of record
            while ( fgets ( buffer, sizeof ( buffer), fp)) {
                if ( strstr ( buffer, "};")) {//does the line contain };
                    break;//found end of record
                }
            }
        }
    }
    fclose ( fp);
    return 1;//match not found
}

int main()
{
    char name[30] = {0};
    char sex[7] = {0};
    int age = 0;

    strcpy ( name, "stephan");
    if ( ( check_person_data ( name, &age, sex)) == 0) {
        printf ( "name %s age %d sex %s\n", name, age, sex);
    }
    else {
        printf ( "%s not found\n", name);
    }
    return 0;
}

【讨论】:

  • 我总是很高兴看到用于解析内容的中间缓冲区的 sscanf。
  • 您的解决方案帮助了我,谢谢。现在我对格式字符串有另一个问题。例如,值 = “0x1000”;我用 fgets 阅读了这一行,并在处理格式时卡住了。我试过 sscanf(buffer, " %*[^\"\n]\"%D[^;\"\n]", keyIntValue); 也试过 %x 但不起作用。请帮忙?跨度>
【解决方案2】:
fread(&person, sizeof(struct personS), 1, fp);  

人现在是您文件中的数据副本,当您需要更改文件数据时,您不能只更改副本,您需要fwrite(..)您更改的新数据

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多