如何读取与文本文件中的特定字符串一致的值?

时间:2016-05-13 03:15:52

标签: c file text

我有以下文本文件:

1 Feb Jane Auckland LF1 190.21
2 Feb Jane Auckland BDHIWAY 390.62 
7 Feb Adeeva Sharif LSZ 2000.00
8 Feb Adeeva Sharif LF2 52.00
4 Feb Jane Auckland ILZERO 101.03 
9 Feb Jerome Velence ILFIVE 4110.00

正如你所看到的那样,文本文件中有三个人(Jane Auckland,Adeeva Sharif和Jerome Velence),但每个人都有附加值,并在文本文件中传播,被其他人分开..

我想要做的是一次只能阅读一个人的文本文件。但是我希望将它们的重合值(最后一个值)加在一起,这样我就可以通过我的税务功能并打印一张工资单并检查每个人。它看起来与此类似:

Pay slip for Jane Auckland from file examplep1.txt
+-------------------------+
| Commission : $   681.86 |
| Tax        : $     0.00 |
|              ---------- |
| Net Pay    : $   681.86 |
+-------------------------+

OFFICIAL CHEQUE FOR BANK 'BBPL'
Please pay Jane Auckland an amount of $681.86
[  ]       WIC - 420 1337 911

Pay slip for Adeeva Sharif from file examplep1.txt
+-------------------------+
| Commission : $  2052.00 |
| Tax        : $   101.65 |
|              ---------- |
| Net Pay    : $  1950.35 |
+-------------------------+

OFFICIAL CHEQUE FOR BANK 'BBPL'
Please pay Adeeva Sharif an amount of $1950.35
[  ]       WIC - 420 1337 911

Pay slip for Jerome Velence from file examplep1.txt
+-------------------------+
| Commission : $  4110.00 |
| Tax        : $   631.78 |
|              ---------- |
| Net Pay    : $  3478.23 |
+-------------------------+

OFFICIAL CHEQUE FOR BANK 'BBPL'
Please pay Jane Auckland an amount of $3478.23
[  ]       WIC - 420 1337 911

这是我的税务功能:

    double calculateTax(double income)
    {
    double centsPerDollar;
    double initialTax;
    double minimumTax;

    income = round(income); //Rounds income to the nearest interger.

    if (income >= 0 && income <= 1517) //First tax bracket.
    {
        centsPerDollar = 0.00;
        initialTax = 0.00;
        minimumTax = 0.00;

        tax = 0.00;
        taxedIncome = income;
    }
    else if (income >= 1518 && income <= 3083) //Second tax bracket.
    {
        centsPerDollar = 0.19;
        initialTax = 0.00;
        minimumTax = 1517.00;

        tax = (income - minimumTax) * centsPerDollar + initialTax;
        taxedIncome = income - ((income - minimumTax) * centsPerDollar + initialTax);
    }
    else if (income >= 3084 && income <= 6667) //Third tax bracket.
    {
        centsPerDollar = 0.325;
        initialTax = 298.00;
        minimumTax = 3083.00;

        tax = (income - minimumTax) * centsPerDollar + initialTax;
        taxedIncome = income - ((income - minimumTax) * centsPerDollar + initialTax);
    }
    else if (income >= 6668 && income <= 15000) //Fourth tax bracket.
    {
        centsPerDollar = 0.37;
        initialTax = 1462.00;
        minimumTax = 6667.00;

        tax = (income - minimumTax) * centsPerDollar + initialTax;
        taxedIncome = income - ((income - minimumTax) * centsPerDollar + initialTax);
    }
    else if (income >= 15001) //Fifth tax bracket.
    {
        centsPerDollar = 0.45;
        initialTax = 4546.00;
        minimumTax = 15000.00;

        tax = (income - minimumTax) * centsPerDollar + initialTax;
        taxedIncome = income - ((income - minimumTax) * centsPerDollar + initialTax);
    }
    else { fprintf(stderr, "Must be a positive number."); } //Error check for negative numbers.
}

总而言之,我想要做的是用每个人个人化自己的价值观,并通过我的税务功能放置所述值,并打印出一张工资单并检查每个人,如示例所示。

提前致谢。

2 个答案:

答案 0 :(得分:0)

  

如何读取与文本文件中特定字符串一致的值?

读取每一行,解析它并测试该值是否与指定的字符串匹配。

可以使用"%n"存储扫描的字符数并测试是否成功。

// open the file
// TBD code 

char buf[100];
while (fgets(buf, sizeof buf, istream)) {
  int count;
  char mon[100], first[100], last[100], code[100];
  double money;
  int n = 0; 
  // 1 Feb Jane Auckland LF1 190.21
  sscanf(buf, "%d %s %s %s %s %lf %n", &count, mon, first, last, code, &money, &n);
  if (n > 0 && buf[n] == 0) {
    if (strcmp(code, "specific string") == 0) {
      // found it!             
      printf("%s\n", code);
    }
  }
}

fclose(istream);

自信的OP可以处理剩余的所需代码来查找税收并打印输出。

答案 1 :(得分:0)

这是一个简单的解决方案。我稍微更改了文件以消除歧义,并使用';'作为每行的字段分隔符。

对此代码进行了注释,并解释了每个细节

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

struct Record {
    char date[6];
    char name[50];
    char type[25];
    float value;
};

int
compare_records(const void *const lhs, const void *const rhs)
{
    /* Compare the names, since this is the field
     * you want to use for matching
     */
    return strcmp(((struct Record *) lhs)->name, ((struct Record *) rhs)->name);
}

int
read_next_record(FILE *file, struct Record *record)
{
    int result;
    /* Simply extract the record from the file.
     *
     * There are many valid methods, some are
     * more robust than this, but this is fast
     * and straight forward given your data.
     */
    result = fscanf(file, "%5[^;];%49[^;];%24[^;];%f\n",
        record->date, record->name, record->type, &record->value);
    return (result == 4);
}

void
display_pay_slip_for(const char *const name, struct Record *first, size_t count)
{
    float value;
    struct Record *next;
    struct Record *found;
    struct Record *final;
    struct Record key;

    /* Make a reacord with the name you want to find */
    strcpy(key.name, name);
    /* Perform a binary search on the data set */
    found = bsearch(&key, first, count, sizeof(*first), compare_records);
    if (found == NULL)
        return;
    /* Compute where the last record is */
    final = first + count - 1;
    /* Store the value in the current record */
    value = found->value;
    /* Search for records appearing BEFORE the
     * on found with binary search and take the
     * important data from them.
     */
    for (next = found - 1 ; ((next >= first) && (compare_records(next, found) == 0)) ; --next)
        value += next->value;
    /* Search for records appearing AFTER the
     * on found with binary search and take the
     * important data from them.
     */
    for (next = found + 1 ; ((next <= final) && (compare_records(next, found) == 0)) ; ++next)
        value += next->value;
    /* Display the result */
    fprintf(stdout, "Total for `%s' -> %f\n", name, value);
}

void
display_file(const char *const filename)
{
    FILE *file;
    struct Record records[100];
    size_t count;

    file = fopen(filename, "r");
    if (file != NULL) /* Check that the file DID open */
    {
        count = 0;
        /* Read records from the file, the specific method for reading
         * is irrelevant, if you have a function that does it the
         * actual implementation of such function is flexible as long
         * as it does what it has to do
         */
        while (read_next_record(file, &records[count]) != 0)
            ++count;
        /* Sort the records to be able to do a binary search.
         * It's not important for a few records, but many records
         * it's really important as it improves performance
         * dramatically.
         */
        qsort(records, count, sizeof(*records), compare_records);
        /* Simply, call a function where you search for all
         * the records associated with a given "match" in this
         * case the person name, and display the result.
         */
        display_pay_slip_for("Jane Auckland", records, count);
        display_pay_slip_for("Adeeva Sharif", records, count);
        display_pay_slip_for("Jerome Velence", records, count);

        /* Of course never forget this */
        fclose(file);
    }
    else
        fprintf(stderr, "error openning `%s'\n", filename);
}

int
main(void)
{
    display_file("data.txt");
    return 0;
}

您唯一缺少的东西已经实现了,如果您愿意,可以将它与此代码一起使用。