C语言中的解析文本文件 - 跳过行 - 重复计算

时间:2015-04-10 19:20:36

标签: c parsing text line skip

我一直在旋转我的车轮一段时间试图解决这个问题但却无法做到。希望你能帮忙!

我目前正致力于解决数独游戏的程序。我在下面显示的当前代码输入一个9x9整数网格(数独谜题),然后生成一个解决方案。这很好。

#include <stdio.h>

int isAvailable(int puzzle[][9], int row, int col, int num)
{
    int rowStart = (row/3) * 3;
    int colStart = (col/3) * 3;
    int i, j;

    for(i=0; i<9; ++i)
    {
        if (puzzle[row][i] == num) return 0;
        if (puzzle[i][col] == num) return 0;
        if (puzzle[rowStart + (i%3)][colStart + (i/3)] == num) return 0;
    }
    return 1;
}

int fillSudoku(int puzzle[][9], int row, int col)
{
    int i;
    if(row<9 && col<9)
    {
        if(puzzle[row][col] != 0)
        {
            if((col+1)<9) return fillSudoku(puzzle, row, col+1);
            else if((row+1)<9) return fillSudoku(puzzle, row+1, 0);
            else return 1;
        }
        else
        {
            for(i=0; i<9; ++i)
            {
                if(isAvailable(puzzle, row, col, i+1))
                {
                    puzzle[row][col] = i+1;
                    if((col+1)<9)
                    {
                        if(fillSudoku(puzzle, row, col +1)) return 1;
                        else puzzle[row][col] = 0;
                    }
                    else if((row+1)<9)
                    {
                        if(fillSudoku(puzzle, row+1, 0)) return 1;
                        else puzzle[row][col] = 0;
                    }
                    else return 1;
                }
            }
        }
        return 0;
    }
    else return 1;
}

int main()
{
    int i, j;
    int row,column;
    int puzzle[9][9];
    //printf("Enter your input:\n");
    for (row=0; row <9; row++){
       for(column = 0; column <9; column ++){
       scanf("%d",&puzzle[row][column]);
       }
    }

    //PRINT INPUT PUZZLE
    printf("Original Puzzle:");
    printf("\n+-----+-----+-----+\n");
    for(i=1; i<10; ++i)
    {
        for(j=1; j<10; ++j) printf("|%d", puzzle[i-1][j-1]);
        printf("|\n");
        if (i%3 == 0) printf("+-----+-----+-----+\n");
    }
    printf("\n");


    //PRINT OUTPUT PUZZLE
    printf("Solved Puzzle:");
    if(fillSudoku(puzzle, 0, 0))
    {
        printf("\n+-----+-----+-----+\n");
        for(i=1; i<10; ++i)
        {
            for(j=1; j<10; ++j) printf("|%d", puzzle[i-1][j-1]);
            printf("|\n");
            if (i%3 == 0) printf("+-----+-----+-----+\n");
        }
        printf("\n");
    }

    else printf("\n\nNO SOLUTION\n\n");

    return 0;
}

我现在想要使用Project Euler(https://projecteuler.net/project/resources/p096_sudoku.txt)中的文本文件,让我的程序生成所有这50个解决方案。文本文件具有以下格式:

Grid 01
003020600
900305001
001806400
008102900
700000008
006708200
002609500
800203009
005010300
Grid 02
200080300
060070084
030500209
000105408
000000000
402706000
301007040
720040060
004010003
...

依此类推50个网格。

我的问题是:将此文件解析为

的最佳方法是什么
  1. 跳过“Grid ##”行
  2. 请阅读接下来的9行输入
  3. 继续浏览文件以重复该程序,直到文件结束
  4. 编辑: 在步骤2和步骤2之间3,这是会发生的事情: 在我阅读了9行数字之后,我将使用它作为程序的输入并让程序运行并生成解决方案,然后回头查看输入文件并获取下一组数字并运行另一个迭代程序

    感谢您提供给我的任何意见和指导! -Colton

2 个答案:

答案 0 :(得分:1)

当文本文件中的数据格式化时,强烈建议您使用fgets()

将每组10行视为记录。它们属于一起,如果1个部分出错,整个组都无效。

// return 0 on success, -1 on EOF and 1 on format failure
int ReadPuzzle(FILE *inf, int puzzle[][9], int *Grid) {
  char buffer[20]; // About 2x expected need

  if (fgets(buffer, sizeof buffer, inf) == NULL)
    return -1;  // File EOF or IO error occurred.
  if (sscanf(buffer, "Grid %d", Grid) != 1)
    return 1;

  for (int row = 0; row < 9; row++) {
    if (fgets(buffer, sizeof buffer, inf) == NULL)
      return 1;  // If Grid line exists, 9 lines _should_ follow
    char *p = buffer;
    for (int col = 0; col < 9; col++) {
      // Use %1d to limit scanning to 1 digit
      if (sscanf(p, "%1d", &puzzle[row][col]) != 1)
        return 1;
      p++;
    }
  }
  return 0;
}

可以添加支票以确保额外的数据不在线上。

答案 1 :(得分:0)

你可能想在第2步和第2步之间做一些事情。 3,但你所概述的听起来合理。