从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
}
}
我有两个文件要读取。其中之一包含两列,例如:
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
}
}