好的,所以我知道如何将值从文件放入结构中。
我在文件中的值是用逗号分隔的。数据是这样的:
number, product, price, other
只有一些元素具有其他值(value)!
我如何在结构中拥有可选值?
这样的:
typedef struct stockItem {
int number;
char* product;
int price;
char *other;
} stockItem;
我输入的数据是这样的:
while (fgets(str, 255, invf) != NULL){
int numOfItems = atoi(strtok(str, " ,"));
char *stockCode = strtok(NULL, " ,");
int price = atoi(strtok(NULL, " ,"));
char *other = strTok(NULL, " "));
stockItem *item = stockItem_new(numOfItems , stockCode, price, other);
它当然不会执行,因为有些项目有其他项目,我该怎么办?我应该将 null 插入到每个没有其他值的值中吗?
最佳答案
是的,你应该设置other
至 NULL
对于没有该字段的每个项目。这是表示没有指向某物的正常方式。
此外,strtok()
将返回指向 str
的内部指针,您可以将其重复用于每个项目。您应该确保您的 stockItem_new()
函数实际上是在复制该数据(使用 strdup()
或 strcpy()
),而不仅仅是将该字段设置为等于指针,或者在所有 struct
中设置该字段s 最终会指向相同的内存,每次调用 fgets()
时都会发生变化,并且在您的阅读功能返回后可能会完全不复存在。
下面是一些示例代码:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 256
struct stock_item {
int number;
char * product;
int price;
char * other;
};
struct stock_item * stock_item_new(const int num_items,
const char * stock_code,
const int price,
const char * other);
void stock_item_destroy(struct stock_item * item);
void stock_item_print(struct stock_item * item);
int main(void)
{
FILE * fp = fopen("data.txt", "r");
if ( !fp ) {
perror("couldn't open data file");
return EXIT_FAILURE;
}
char buffer[BUFFER_SIZE];
const char * delim = " ,\n";
while ( fgets(buffer, BUFFER_SIZE, fp) ) {
int num_items = atoi(strtok(buffer, delim));
char * stock_code = strtok(NULL, delim);
int price = atoi(strtok(NULL, delim));
char * other = strtok(NULL, delim);
struct stock_item * new_item;
new_item = stock_item_new(num_items, stock_code, price, other);
stock_item_print(new_item);
stock_item_destroy(new_item);
}
fclose(fp);
return 0;
}
struct stock_item * stock_item_new(const int num_items,
const char * stock_code,
const int price,
const char * other)
{
struct stock_item * new_item = malloc(sizeof *new_item);
if ( !new_item ) {
perror("couldn't allocate memory for stock item");
exit(EXIT_FAILURE);
}
new_item->number = num_items;
new_item->price = price;
new_item->product = strdup(stock_code);
if ( !new_item->product ) {
perror("couldn't allocate memory for product name");
exit(EXIT_FAILURE);
}
if ( other ) {
new_item->other = strdup(other);
if ( !new_item->other ) {
perror("couldn't allocate memory for 'other' field");
exit(EXIT_FAILURE);
}
}
else {
new_item->other = NULL;
}
return new_item;
}
void stock_item_destroy(struct stock_item * item)
{
free(item->product);
free(item->other);
free(item);
}
void stock_item_print(struct stock_item * item)
{
printf("%d, %s, %d, %s\n", item->number, item->product,
item->price, item->other ? item->other : "(none)");
}
当使用以下数据文件运行时:
paul@horus:~/src/sandbox/itemfile$ cat data.txt
20, rifle, 99
33, bucket, 30, plastic
50, fish, 5, gold
12, hammer, 45, left-handed
9, backscratcher, 13
paul@horus:~/src/sandbox/itemfile$
产生以下输出:
paul@horus:~/src/sandbox/itemfile$ ./itemfile
20, rifle, 99, (none)
33, bucket, 30, plastic
50, fish, 5, gold
12, hammer, 45, left-handed
9, backscratcher, 13, (none)
paul@horus:~/src/sandbox/itemfile$
stock_item_print()
函数检查是否 other
字段是 NULL
,如果是,则输出 "(none)"
.否则它会正常打印。
另请注意传递 NULL
至 free()
很好,所以我们不必检查 other
stock_item_destroy()
中的字段功能。
最后,我没有对其进行任何更改(除了将 '\n'
添加到分隔符列表中),但是您的解析代码带有 strtok()
非常脆弱,应该扩展以包括更多的错误检查。例如,strtol()
优于atoi()
,你应该每次检查是否strtok()
返回 NULL
.
关于c - 将文件中的值放入结构中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36374252/