c-使用fscanf读取数据



嘿,我有一个关于从文本文件中读取信息的快速问题。我有一个格式化的.txt文件,里面有客户信息。该文件包含多个客户,每个客户都有不同的订单类型、购买的产品、地址、城市、州、总成本等。当我使用fscanf()时,它没有返回任何值,并且在调试器中,分配给我的变量的所有值都不正确。

以下是来自文本文件的数据:

0
Programming With C
Larry Page
1600 Amphitheatre Parkway
Mountain View
California
94043
81.07
1
Data Structures and Algorithms in Java
Elon Musk
3500 Deer Creek Road
Palo Alto
California
94304
32.50
2
Computer Science Distilled
James Gosling
1234 Main Dr.
San Francisco 
California
94122
35.70

这是我使用的代码。

int orderType, zipCode;
double totalCost;
char product[MAXSIZE], customer[MAXSIZE], address[MAXSIZE], city[MAXSIZE], state[MAXSIZE];
// Scan in the order type, product name, customer, address, city, state, zip code, order cost
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);

任何建议都会被认为是非常有用的。

说明数据之前

检查fscanf()的返回值,得到一个会抱怨fscanf()滥用的编译器,比如GCC。您需要一个格式字符串参数,其中所有转换都在一个字符串中,然后是存储数据的指针参数。与CCD_ 3类似。

您有:

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")] = '';
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: %sn%sn%sn%s %s %.5dn%f",
orderType, product, customer, address, city, state, zipCode, totalCost);
return 0;

请注意,没有错误报告;错误时代码返回-1,成功时返回0。你可能想做得更好。您可以将"integer read and assign"代码封装到类似于所示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)

但是错误恢复是不值得考虑的。如果你最想使用这种怪物,你应该阅读《远离scanf()的初学者指南》。

相关内容

  • 没有找到相关文章

最新更新