gpt4 book ai didi

c - 以空格作为分隔符的 fscanf - 我应该使用什么格式?

转载 作者:太空宇宙 更新时间:2023-11-04 00:59:46 24 4
gpt4 key购买 nike

我有一个txt文件,它的行如下

[7 chars string][whitespace][5 chars string][whitespace][integer]

我想使用 fscanf() 将所有这些读入内存,但我对应该使用什么格式感到困惑。

下面是这样一行的例子:

hello   box   94324

注意每个字符串中的填充空格,除了分隔空格。

编辑:我知道首先使用 fgets() 的建议,我不能在这里使用它。

编辑:这是我的代码

typedef struct Product {
char* id; //Product ID number. This is the key of the search tree.
char* productName; //Name of the product.
int currentQuantity; //How many items are there in stock, currently.
} Product;

int main()
{
FILE *initial_inventory_file = NULL;
Product product = { NULL, NULL, 0 };

//open file
initial_inventory_file = fopen(INITIAL_INVENTORY_FILE_NAME, "r");

product.id = malloc(sizeof(char) * 10); //- Product ID: 9 digits exactly. (10 for null character)
product.productName = malloc(sizeof(char) * 11); //- Product name: 10 chars exactly.

//go through each line in inital inventory
while (fscanf(initial_inventory_file, "%9c %10c %i", product.id, product.productName, &product.currentQuantity) != EOF)
{
printf("%9c %10c %i\n", product.id, product.productName, product.currentQuantity);
}

//cleanup...
...
}

这是一个文件示例:(实际上是 10 个字符、9 个字符和 int)

022456789 box-large  1234
023356789 cart-small 1234
023456789 box 1234
985477321 dog food 2
987644421 cat food 5555
987654320 snaks 4444
987654321 crate 9999
987654322 pillows 44

最佳答案

假设您的输入文件格式正确,这是最直接的版本:

char str1[8] = {0};
char str2[6] = {0};
int val;
...
int result = fscanf( input, "%7s %5s %d", str1, str2, &val );

如果 result 等于 3,则您成功读取了所有三个输入。如果它小于 3 但不是 EOF,那么您的一个或多个输入有匹配失败。如果是EOF,则说明您已经到达文件末尾存在输入错误;使用 feof( input ) 测试此时的 EOF。

如果您不能保证您的输入文件格式正确(我们大多数人做不到),您最好将整行作为文本阅读并自己解析。你说你不能使用 fgets,但是有一种方法可以使用 fscanf:

char buffer[128]; // or whatever size you think would be appropriate to read a line at a time

/**
* " %127[^\n]" tells scanf to skip over leading whitespace, then read
* up to 127 characters or until it sees a newline character, whichever
* comes first; the newline character is left in the input stream.
*/
if ( fscanf( input, " %127[^\n]", buffer ) == 1 )
{
// process buffer
}

然后您可以使用 sscanf 解析输入缓冲区:

int result = sscanf( buffer, "%7s %5s %d", str1, str2, &val );
if ( result == 3 )
{
// process inputs
}
else
{
// handle input error
}

或通过其他方法。

编辑

需要注意的边缘情况:

  1. 每行缺少一个或多个输入
  2. 格式错误的输入(例如整数字段中的非数字文本)
  3. 每行输入多于一组
  4. 超过 7 个或 5 个字符的字符串
  5. 值太大,无法存储在 int

编辑 2

我们大多数人不推荐 fscanf 的原因是它有时会使错误检测和恢复变得困难。例如,假设您有输入记录

foo     bar    123r4
blurga blah 5678

然后您使用 fscanf( input, "%7s %5s %d", str1, str2, &val ); 读取它。 fscanf 将读取 123 并将其分配给 val,将 r4 留在输入流中。在下一次调用时,r4 将被分配给 str1blurga 将被分配给 str2,而您将在 blah 上得到匹配失败。理想情况下,您希望拒绝整个第一个记录,但当您知道存在问题时为时已晚。

如果你首先把它读成一个字符串,你可以解析和检查每个字段,如果其中任何一个是坏的,你可以拒绝整个东西。

关于c - 以空格作为分隔符的 fscanf - 我应该使用什么格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44853055/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com