数据说明之前
检查来自 的返回值fscanf()
,并获得一个会抱怨滥用的编译器fscanf()
——例如 GCC。您需要一个格式字符串参数,将所有转换都放在一个字符串中,然后是存储数据的指针参数。与printf()
.
你有:
fscanf(customerDataPtr, "%d", "%s", "%s", "%s", "%s", "%s", "%f", "%f");
printf("%d", "%s", "%s", "%s", "%s", "%s", "%f", "%f",
orderType, product, customer, address, city, state, zipCode, totalCost);
您需要的或多或少的最小版本是:
if (fscanf(customerDataPtr, "%d%s%s%s%s%s%d%f", &orderType, product,
customer, address, city, state, &zipCode, &totalCost) == 8)
{
printf("%d %s %s %s %s %s %.5d %f",
orderType, product, customer, address, city, state, zipCode, totalCost);
}
else
{
…handle error somehow…
}
注意%d
读取和打印邮政编码的用途。
还要注意,产品必须是单字,客户名称必须是单字,地址必须是单字,城市必须是单字,州必须是单字。那套限制是不现实的,但你应该能够从这里到达某个地方。
数据说明后
您需要使用fgets()
或可能是 POSIX
读取行getline()
,然后适当地存储结果。这主要意味着删除换行符,检查溢出等。
处理更复杂;目前尚不完全清楚什么是最好的方法。一个简单的方法应该有效,以代码中的任何拼写错误为模,是:
static int read_line(FILE *fp, size_t buflen, char *buffer)
{
char line[4096];
if (fgets(line, sizeof(line), fp) == 0)
return -1;
line[strcspn(line, "\n")] = '\0';
if (strlen(line) >= buflen)
return -1;
strcpy(buffer, line);
return 0;
}
在其他一些功能中:
char line[4096];
FILE *fp = customerDataPtr; // That name is too damn long!
if (fgets(line, sizeof(line), fp) == 0)
return -1;
if (sscanf(line, "%d", &orderType) != 1)
return -1;
if (read_line(fp, product, sizeof(product) != 0)
return -1;
if (read_line(fp, customer, sizeof(customer) != 0)
return -1;
if (read_line(fp, address, sizeof(address) != 0)
return -1;
if (read_line(fp, city, sizeof(city) != 0)
return -1;
if (read_line(fp, state, sizeof(state) != 0)
return -1;
if (fgets(line, sizeof(line), fp) == 0)
return -1;
if (sscanf(line, "%d", &zipCode) != 1)
return -1;
if (fgets(line, sizeof(line), fp) == 0)
return -1;
if (sscanf(line, "%f", &totalCost) != 1)
return -1;
printf("%d: %s\n%s\n%s\n%s %s %.5d\n%f",
orderType, product, customer, address, city, state, zipCode, totalCost);
return 0;
注意没有报错;代码在错误时返回 -1,在成功时返回 0。您可能希望做得比这更好。您可以将“整数读取和分配”代码封装到类似于所示函数的read_line()
函数中;你会适当地重命名这些函数。您可能还会添加一个函数来处理“浮点读取和分配”。请注意打印格式的变化以更好地处理基于行的输入。您可以随心所欲地使用格式字符串。
我注意到理论上你可以使用fscanf()
这样一个复杂的格式字符串,假设 MAXSIZE 是 128:
if (fscanf(fp, "%d %127[^\n]%*c %127[^\n]%*c %127[^\n]%*c %127[^\n]%*c %127[^\n]%*c %d %f",
&orderType, product, customer, address, city, state, &zipCode, &totalCost) == 8)
但是错误恢复不值得考虑。如果你甚至有点想使用这样的怪物,你应该阅读Beginnner's Guide Away Fromscanf()
。