c - 如何在c中读取文件中的单词后存储值

标签 c arrays string file

我正在尝试用 C 读取文件,然后在读取某个单词后存储值。例如,在我的input.txt文件中,内容如下:

GREETINGS
Hello 13
Namaste 24
Hola 36
FLAVORS
Vanilla 23
Chocolate 78

我想读取过去的GREETINGS,然后存储Hello及其值13,然后存储Namaste及其值24 等。然后读取过去的 FLAVORS 并存储 Vanilla 及其值 23 等。等等...

我知道如何打开文件,但不确定如何从那里继续。

void readInput() {

    char input_file[100];

    FILE *fp;

    printf("Please enter the name of the file you would like to read: \n");
    scanf("%s", input_file);
    printf("You entered: %s\n", input_file);

    fp = fopen(input_file, "r");

    if (fp == NULL) {
        printf("File does not exist.\n");
            exit(1);
    }
    else
        printf("This file exists!\n");
}

最佳答案

从您的示例数据来看,尚不清楚包含数据的行是否始终具有相同的格式。所以我 建议您将当前模式存储在变量中(这意味着 GREETINGSFLAVOR 等),然后调用 每种模式的特定解析函数取决于当前的值 模式。

我首先创建这个枚举

typedef enum {
    MODE_GREETINGS = 0,  // <-- important that this value is 0
    MODE_FLAVORS,
    ...
    MODE_INVALID
} Modes;

和一个具有所有模式的变量(可以是全局变量):

const char *modes_lookup[] = {
    "GREETINGS",
    "FLAVORS",
    ...
};

然后我会编写一个返回模式的函数:

Modes get_mode(const char *src)
{
    if(src == NULL)
        return MODE_INVALID;

    for(size_t i = 0; i < sizeof modes_lookup / sizeof modes_lookup[0]; ++i)
    {
        if(strcmp(src, modes_lookup[i]) == 0)
            return i;
    }

    return MODE_INVALID;
}

现在您可以像这样解析文件:

char line[1024];

Modes mode = MODE_INVALID;

size_t lineno = 0;
while(fgets(line, sizeof line, fp))
{
    lineno++;
    // removing newline
    line[strcspn(line, "\n")] = 0;

    Modes newmode = get_mode(line);

    // check if line is a GREETINGS, FLAVOR, etc line
    if(newmode != MODE_INVALID)
    {
        // sets the new mode and continue with the next line
        mode = newmode;
        continue;
    }

    // parsing depending on the current mode

    if(mode == MODE_GREETINGS)
    {
        if(parse_greetings(line) == 0)
        {
            fprintf(stderr, "Cannot parse data on line %zu\n", lineno);
            break;
        }

        continue;
    } 

    if(mode == MODE_FLAVORS) {
        if(parse_flavor(line) == 0)
        {
            fprintf(stderr, "Cannot parse data on line %zu\n", lineno);
            break;
        }

        continue;
    }

    // more (if mode == MODE_xxx) cases as needed

    if(mode == MODE_INVALID)
    {
        // mode == MODE_INVALID
        fprintf(stderr, "File does not start with a mode line.\n");
        break;
    }

}

然后您必须编写 parse_greetingsparse_flavorparse_xxx 函数。就像我说的 之前,从您的示例中不清楚格式是否始终是 相同,因此取决于您使用 strtok 还是 sscanf 的格式。还 您对如何以及在何处存储值的描述非常模糊,所以 我不知道什么对你来说是最好的。 最简单的是 sscanf,如果数据行变得更复杂,您可以 使用strtok

例如使用sscanf

int parse_greetings(const char *line)
{
    if(line == NULL)
        return 0;

    char name[20];
    int val;

    if(sscanf(line, "%19s %d", name, val) != 2)
        return 0;


    // do whatever you need with 'name' and 'val'

    return 1;
}

还有strtok:

int parse_greetings(char *line)
{
    if(line == NULL)
        return 0;

    char name[20];
    int val;

    const char *delim = " \t\r\n";

    char *token = strtok(line, NULL);

    // line has only delimiters
    if(token == NULL)
        return 0;

    strncpy(name, token, sizeof name / sizeof name[0]);
    name[(sizeof name / sizeof name[0]) - 1] = 0;

    token = strtok(NULL, delim);

    if(token == NULL)
        return 0;

    char *end;

    val = strtol(token, &end, 0);

    // check if token is a number
    if(*end != '\0')
        return 0;

    // do whatever you need with 'name' and 'val'

    return 1;
}

关于c - 如何在c中读取文件中的单词后存储值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49603971/

相关文章:

c - 如何使用 C 中的函数编译 llvm 代码文件?

arrays - 如何在matlab中绘制特定点?

java - Java中这两个语句有什么区别?

java - 在Java中可以使用迭代来生成字符串吗?

java - 十六进制转换为 EBCDIC

python - 替换字符串中的日期时间字符

c - 在二维数组中一次访问一个字符

c - 打印错误的值

未分配 C 结构值

sql - Postgres : Group by clause with predefined set of values