2016-05-13 60 views
0

我有以下的文本文件:如何读取与文本文件中特定字符串一致的值?

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 

正如你可以看到有三个人(简奥克兰,Adeeva谢里夫和杰罗姆韦伦采)在文本文件中但每种都连接到他们的价值和周围蔓延文本文件正在被其他人分开..

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

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. 
} 

在我想要做的是个体化每个人有自己的价值观总结,并把通过该值我税务功能,并打印出一张工资单并检查每个人,如示例中所示。

在此先感谢。

+0

您的文本文件的第一个问题是,名称组件由分隔字段的相同分隔符分隔。使用不同的分隔符,如标签''\ t''或分号'''',这样就没有问题了。 –

+0

没有标准功能可以直接跳到最终目标。如果您将流程分解为文件解析和最终结果整理,那么最好。也就是说,读取每一行,解析它,存储解析的信息,然后在文件完全解析后整理最终结果。 – kaylum

+0

您的方法可能会使问题变得困难。为什么不把文件中的所有值读入一个struct *数组,然后按名称对数组进行排序,并简单地将每个名称的值相加?你甚至可以创建一个单独的结构体来存储名称,并且从你从文件中读取的详细列表中填充每个人的总和。 –

回答

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); 

Confident OP可以处理剩余的所需代码来查找税和打印输出。

0

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

此代码注释,并且每一个细节进行了说明

#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; 
} 

唯一缺少的东西,你已经实现了,如果你愿意,你可以用这个代码中使用它。

相关问题