读取文本文件并用分隔符分隔

Reading text file and breaking it by delimiters

我正在尝试读取具有以下结构的文本文件:

Item 1 - 50, Item 2 - 400, Item 3 - 120, Item 4 - 15;

在遍历文件时,我想将价格和商品名称存​​储在两个字符串中。 为了更清楚,我有 int credit,我想将其与价格进行比较,如果信用更大,我将打印价格。

我用这个功能打印了所有的产品:

int credit = 1000; //For the example purpose
int displayProducts(){

    int row=0;
    char line[MAX_LINE_SIZE + 1]; // ptr to the current input line
    FILE *fp;

    fp = fopen("machinedata.txt", "r");
    if (fp == NULL)
    {
        printf("Error while opening the file.\n");
    //  exit(EXIT_FAILURE);
    }

    while (fgets(line, MAX_LINE_SIZE, fp)) {
        char *next_item;  // ptr to the next item extracted from the current line
        char* name = NULL;
        int price;

        next_item = strtok(line, " ,");

        while (next_item != NULL){
            printf("%s\n", next_item);
            next_item = strtok(NULL, " ,");
            /*WHAT CAN I DO HERE TO EXTRACT EACH PRICE AND COMPARE WITH CREDIT??*/
        }
    }

    fclose(fp);
    return 1;
}

我正在迈出 C 语言的第一步,但我不知道该怎么做。 有什么帮助吗?

在阅读一行之后,您需要将其拆分为项目条目。由于您使用的是 strtok(),我假设您不需要识别分隔符。此外,不喜欢 strtok() and preferring Microsoft's strtok_s() on Windows and POSIX strtok_r() 的原因之一是您不能对 strtok() 进行嵌套调用,但您需要它们。或者您需要使用 scanf() 或其他一些技术。

警告:none此代码已接近编译器!

char *next_ptr = NULL;
char *next_item = strtok_r(line, ",;", &next_ptr);

while (next_item != NULL){
    char *item_ptr = NULL;
    char *name = strtok_r(next_item, "-", &item_ptr);
    if (name == NULL)
    {
        fprintf(stderr, "Failed to scan name out of [%s]\n", next_item);
        break;
    }
    int price;
    next_item = strtok_r(NULL, " ,", &item_ptr);
    assert(next_item != NULL);
    if (sscanf(next_item, "%d", &price) != 1)
        fprintf(stderr, "Failed to convert [%s] to integer\n", next_item);
    else
        printf("Item: [%s] price %d\n", name, price);
    next_item = strtok_r(NULL, ",;", &next_ptr);
}

错误的break是因为我懒惰。理想情况下,您应该继续该行中的下一项,但这涉及将循环重写为 for 循环:

for (next_item = strtok_r(line, ",;", &next_ptr);
     next_item != NULL;
     next_item = strtok_r(NULL, ",;", &next_ptr))
{
    ...body of loop except for final call to strtok_r()...
}

现在可以使用continuenext_item = strtok_r(NULL, ",;", &next_ptr)语句就会被执行,这很关键。您可能需要担心分号后的空项;将 && *next_item != '[=23=]' 添加到循环条件。

如果你因为某些原因(什么?)不能使用strtok_r()strtok_s(),那么你可以考虑使用:

char name[30];
int price;
if (sscanf(next_item, "%29[^-] - %d", name, &price) != 2)
{
    fprintf(stderr, "Failed to extract item name and price from [%s]\n", next_item);
    continue; // Or break!
}

还有其他选择——事实上有很多。

请注意 strtok() 及其亲戚都 (a) 破坏输入字符串 (b) 不告诉您哪个字符标记结束,并且 (c) 将多个分隔符视为一个,因此您可以不要在两个分隔符之间发现空项(在本例中这不是问题)。破坏是通过在找到分隔符的地方插入空字节,将原始字符串切成更短的子字符串。

请注意,如果项目名称包含破折号,则表示您已使用此系统。您会将 'Vacuum-24' 解释为名为 'Vacuum' 且价格为 24 的商品。你也可以解决这个问题,但它更难(例如 strstr() 找到 " - "(空白、破折号、空白)作为项目名称和价格之间的分隔符)。