【问题标题】:Finding certain combination in a text file在文本文件中查找特定组合
【发布时间】:2019-11-01 22:29:27
【问题描述】:

我有一个组合文本文件,不重复从 1 到 10 的 6 个数字,如下所示:

2 3 8 9 6 4 
8 3 1 4 7 9 
1 3 5 7 6 9 
1 5 7 9 8 4 
1 3 5 4 8 7 
2 4 6 8 7 1 
6 7 8 3 5 9 
3 1 6 2 7 9 
1 7 4 2 5 8 
3 4 9 2 1 7 
...

我有一个黄金组合,比如说:2、1、3、9、8、5

我想检查我的文本文件中有多少次与黄金组合的 5 个数字相匹配。这是我的代码尝试:

// Including C Standard Libraries
#include <stdint.h>

#include<stdio.h> 
#include<stdlib.h> 
#include<time.h> 

int main()
{

    // Gold Combination
    int n1 = 2;
    int n2 = 1;
    int n3 = 3;
    int n4 = 9;
    int n5 = 8;
    int n6 = 5;

    // Numbers of Matching Combinations
    int match_comb = 0; 

    // Creating a file to see combinations content
    char ch, file_name[25];
    FILE *fp;

    fp = fopen("combinations.txt", "r");  // Read Mode

    if (fp == NULL)
    {
        perror("Error while opening the file.\n");
        exit(EXIT_FAILURE);
    }

    int j = 0;
    int mn = 0;  // Number of matched numbers
    int x[6] = {0,0,0,0,0,0};

    char c;

    while((c = fgetc(fp)) != EOF)
    {
        if(c == ' ' || c == '\n')
        {

        }
        else
        {

            x[j] = c;


            if (j == 5)
            {
                if(x[0]==n1 || x[0]==n2 || x[0]==n3 || x[0]==n5 || x[0]==n6){
                    mn += 1;
                }if(x[1]==n1 || x[1]==n2 || x[1]==n3 || x[1]==n5 || x[1]==n6){
                    mn += 1;
                }if(x[2]==n1 || x[2]==n2 || x[2]==n3 || x[2]==n5 || x[2]==n6){
                    mn += 1;
                }if(x[3]==n1 || x[3]==n2 || x[3]==n3 || x[3]==n5 || x[3]==n6){
                    mn += 1;
                }if(x[4]==n1 || x[4]==n2 || x[4]==n3 || x[4]==n5 || x[4]==n6){
                    mn += 1;
                }if(x[5]==n1 || x[5]==n2 || x[5]==n3 || x[5]==n5 || x[5]==n6){
                    mn += 1;
                }

                if ( mn == 5)
                {
                    match_comb += 1;  // Adding One the the Match Combinantions counter
                }

                for (int i = 0; i < 6; ++i)  // Resetting x array
                {
                    x[i] = 0;
                }    

                mn = 0;  // Resetting
                j = -1;  // Resetting j

            }

            j += 1;


        }
    }


    printf("Number of Matching Combinations:");
    printf("%d", match_comb);
    printf("\n");

    fclose(fp);

    return 0;
}

但是,我认为代码不起作用,因为它总是说有 0 个匹配的组合.. 有没有办法简化或使我的代码工作?

另外,这仅适用于具有一位数字的数字,但在我有更大范围的情况下,比如 1-20,我不太确定如何从文本文件中收集数字。我是考虑在每个空格后面都有一个计数器的情况下,如果计数器是一,则将字符作为一位数,如果计数器是二,则收集两个字符并做一些事情告诉代码收集两个字符并使用结果数字,但我不知道该怎么做..

编辑:

int main()
{

    // Gold Combination
    int n1 = 20;
    int n2 = 1;
    int n3 = 35;
    int n4 = 9;
    int n5 = 18;
    int n6 = 5;

    // Numbers of Matching Combinations
    int match_comb = 0; 

    // Creating a file to see combinations content
    char ch, file_name[25];
    FILE *fp;

    fp = fopen("combinations.txt", "r");  // Read Mode

    if (fp == NULL)
    {
        perror("Error while opening the file.\n");
        exit(EXIT_FAILURE);
    }

    int j = 0;
    int mn = 0;  // Number of matched numbers
    int x[6] = {0,0,0,0,0,0};

    int c;

    while((c = fgetc(fp)) != EOF)
    {

        //x[j] = fscanf(fp, "%d", &c);

        fscanf(fp, "%d %d %d %d %d %d", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5]);

        printf("%d", x[0]);
        printf(" ");
        printf("%d", x[1]);
        printf(" ");
        printf("%d", x[2]);
        printf(" ");
        printf("%d", x[3]);
        printf(" ");
        printf("%d", x[4]);
        printf(" ");
        printf("%d", x[5]);

        if(x[0]==n1 || x[0]==n2 || x[0]==n3 || x[0]==n5 || x[0]==n6){
            mn += 1;
        }if(x[1]==n1 || x[1]==n2 || x[1]==n3 || x[1]==n5 || x[1]==n6){
            mn += 1;
        }if(x[2]==n1 || x[2]==n2 || x[2]==n3 || x[2]==n5 || x[2]==n6){
            mn += 1;
        }if(x[3]==n1 || x[3]==n2 || x[3]==n3 || x[3]==n5 || x[3]==n6){
            mn += 1;
        }if(x[4]==n1 || x[4]==n2 || x[4]==n3 || x[4]==n5 || x[4]==n6){
            mn += 1;
        }if(x[5]==n1 || x[5]==n2 || x[5]==n3 || x[5]==n5 || x[5]==n6){
            mn += 1;
        }

        if ( mn == 5)
        {
            match_comb += 1;  // Adding One the the Match Combinantions counter
        }

        for (int i = 0; i < 6; ++i)  // Resetting x array
        {
            x[i] = 0;
        }    

        mn = 0;  // Resetting

        printf("\n");


    }

    printf("Number of Matching Combinations:");
    printf("%d", match_comb);
    printf("\n");

    fclose(fp);

    return 0;
}

【问题讨论】:

  • 在传递给perror 的字符串中包含“\n”是不寻常的。包含错误消息中使用的路径非常有用。 IOW,使用perror("combinations.txt")
  • 如果您的输入是文本并且文件的第一个字符是2,那么您不应该期望它匹配整数2。您需要将文本输入转换为整数。

标签: c file combinations


【解决方案1】:

问题出在:

x[j] = c;

这会将 char 分配给整数。您需要将 c 转换为整数。比如减去零的字符码:

x[j] = c-'0';

您可以使用isdigit(c) 来检查c 是否真的是一个数字。

在调试器的帮助下或使用printf 显示x[0], x[1], ... 的确切值,您可以更清楚地了解问题所在。

对于超过1位数字的读取,最好使用fscanf(fp, "%d", &amp;c)之类的函数,它会自动将读取的字符转换为数字。请注意,如果您在此处使用 &amp;cc 必须是 int,而不是 char。

如果您想使用fscanf,您需要删除对fgetc 的调用(在您的while 循环中),否则fgetc 每次都会删除一个字符。当这是一个空格或换行符时,删除一个字符是没有问题的,但对于该行中的第一个数字来说这是一个问题。当fgetc 不能再用于检查文件结束时,使用fscanf 的返回值,如this post 中所述。例如:

while (true)  // endless loop, but will end via a 'break'
{
    //  remove if(c == ' ' || c == '\n')
    if (fscanf(fp, "%d", &c) != 1)  // check whether fscanf found 1 input
        break; // this jumps out of the while loop
    ....  // rest of your code
}

如果你真的想使用fgetc 来读取数字,你需要这样的东西:

if (isdigit(c))
    num = num * 10 + (c - '0');

在遇到非数字之前,尚未将num 放入 X 数组中。 num 之后需要重置为 0。

至于您用于计算匹配数的代码,如果您完全是编程新手,它看起来很聪明。一个改进是将n 值也放入一个数组中,并使用 for 循环来检查匹配的数量。

【讨论】:

  • 警告:格式 '%d' 需要类型为 'int*' 的参数,但参数 2 的类型为 'char*' [-Wformat=] x[j] = scanf("%d", &c);
  • @Delfin 是的,你是对的。在这种情况下,c 需要是一个 int。
  • 但是如果 c 是 int,我怎么知道我什么时候有换行符 '\n' ?
  • @Delfin scanf("%d") 自动跳过换行符和空格。
  • @Delfin 如果您在文档中查找 scanf,您会更好地了解它的工作原理以及不同的选项是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多