从c文件中读取值

Reading values from a file in c

我有两个文件要读取。其中之一包含两列,例如:

Account Number      Amount
100                 27.14
300                 62.11
400                 100.56
900                 82.17

另一个文件有 5 列,内容如下:

Account Number      Name           Surname        Balance        
100                 Alan           Jones          348.17
300                 Mary           Smith          27.19
500                 Sam            Sharp          0.00
700                 Suzy           Green          -14.22

我想比较两个文件的账号,把第一个文件的余额加到第二个文件的余额上。到目前为止,我试图从第一个文件中获取帐号并将其打印在屏幕上。我尝试使用 fread 函数,但它不起作用。

我的尝试是:

struct clientData{
    unsigned int acctNum;
    char name[20];
    char surname[20];
    double balance;
};
int main(){

FILE *fPtr, *fPtr2;
    
    if(!(fPtr = fopen("transaction_file.txt", "r"))){
        printf("[ERROR] File could not be found!\n");
        return;
    }
    fseek(fPtr, (0) * sizeof(struct clientData), SEEK_SET);
    
    struct clientData client = {0, "", "", 0.0};
    
    //read record from file
    fread(&client, sizeof(struct clientData), 1, fPtr);
    printf("%-6u%10.2lf\n\n", client.acctNum, client.balance);
}

您需要解析输入。虽然它完全不适合生产工作(如果不是不可能可靠地避免意外输入的未定义行为是很困难的),一个简单的方法是使用 scanf。 您将希望使用使查找变得容易的数据结构。最简单的(IMO)实现是不平衡树。类似于:

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

void * xmalloc(size_t s);
FILE * xfopen(const char *path, const char *mode);
int die(const char *fmt, ... );

struct account {
    int number;
    float balance;
    char name[32];
    char surname[32];
    struct account *next[2];
};

void
insert(struct account **root, const struct account *n)
{
    struct account *r = *root;

    if( r == NULL ){
        r = *root = xmalloc(sizeof **root);
        memcpy(r, n, sizeof *n);
    } else if( n->number == r->number ){
        r->balance += n->balance;
        if( *r->name == '[=10=]' ){
            strcpy(r->name, n->name);
            strcpy(r->surname, n->surname);
        }
    } else {
        insert(r->next + (n->number > r->number), n);
    }
}

const char *hdr[2] = {
    "Account Number      Amount\n",
    "Account Number      Name           Surname        Balance\n"
};
void
read_file(struct account **root, FILE *ifp)
{
    size_t cap = 0;
    char *line = NULL;
    struct account n = {0};
    while( getline(&line, &cap, ifp) > 1 ){
        if( 2 == sscanf(line, "%d %f", &n.number, &n.balance) \
        || 4 == sscanf(line, "%d %31s %31s %f",
            &n.number, n.name, n.surname, &n.balance)
        ) {
            insert(root, &n);
        } else if( strcmp(line, hdr[0]) && strcmp(line, hdr[1]) ) {
            die("invalid input: %s\n", line);
        }
    }
    free(line);
}

void
print(struct account *r)
{
    if( r ){
        print(r->next[0]);
        printf("%d %-31s %-31s %.2f\n",
            r->number, r->name, r->surname, r->balance
        );
        print(r->next[1]);
    }
}

int
main(int argc, char **argv)
{
    struct account *root = NULL;
    if( argc > 1 ){
        FILE *fp;
        for(char *const* path = argv + 1; *path; path += 1 ){
            read_file(&root, fp = xfopen(*path, "r"));
            if( fclose(fp) ){
                perror(*path);
            }
        }
    } else {
        read_file(&root, stdin);
    }
    print(root);
}

FILE *
xfopen(const char *path, const char *mode)
{
    FILE *fp = path[0] != '-' || path[1] != '[=10=]' ? fopen(path, mode) :
        *mode == 'r' ? stdin : stdout;
    if( fp == NULL ){
        perror(path);
        exit(EXIT_FAILURE);
    }
    return fp;
}

void *
xmalloc(size_t s)
{
    void *rv = malloc(s);
    if( rv == NULL ){
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    return rv;
}

int
die(const char *fmt, ... )
{
    va_list ap;
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    exit(EXIT_FAILURE);
}

类似于,但具有更强的解析测试。

// if (2 == sscanf(line, "%d %f", &n.number, &n.balance) ||
//     4 == sscanf(line, "%d %31s %31s %f", &n.number, n.name, n.surname, &n.balance)

int end = 0;
sscanf(line, "%d %f %n", &n.number, &n.balance, &end);
if (end > 0 && line[end] == 0) {
  ; // Handle file 1 type line
} else {
  end = 0;
  sscanf(line, "%d %31s %31s %f %n", &n.number, n.name, n.surname, &n.balance, &end);
  if (end > 0 && line[end] == 0) {
    ; // Handle file 2 type line
  }
}