【问题标题】:C reading in multiple lines from fileC从文件中读取多行
【发布时间】:2011-03-23 16:42:54
【问题描述】:

我遇到的问题是使用标准输入从文件中读取多行整数。文件看起来像:

123
423
235
523
..etc

我现在的代码是:

/*
 * Read in the initial puzzle configuration.
 * Each line is 4 characters long:
 *   Row    as a character '0' .. '9'
 *   Column as character '0' .. '9'
 *   Digit  as character '0' .. '9'
 *   Terminating newline.
 * Exits with an error message if there are syntactic
 * or semantic errors with any configuration line.
 */

void configure(FILE *puzzle_file) {
        int row;
        int column;
        int value;

        while((fscanf(puzzle_file, "%i%i%i\n", row, column, value)) != EOF){
                fscanf(puzzle_file, "%i%i%i\n", row, column, value);
                puzzle[row][column] = value;
                fixed[row][column] = 1;
        }

}

我尝试使用 fscanf,因为文件格式正确(根据函数配置上面的注释),但我无法让它工作。

如果有另一种更简单的方法来解决这个问题,那将会很高兴。

语言:C

编辑:

关于编译错误:

xxxxxxx@linus:~/350/sudoku$ make
gcc -c puzzle.c
puzzle.c: In function ‘configure’:
puzzle.c:95: warning: format ‘%i’ expects type ‘int *’, but argument 3 has type ‘int’
puzzle.c:95: warning: format ‘%i’ expects type ‘int *’, but argument 4 has type ‘int’
puzzle.c:95: warning: format ‘%i’ expects type ‘int *’, but argument 5 has type ‘int’
puzzle.c:96: warning: format ‘%i’ expects type ‘int *’, but argument 3 has type ‘int’
puzzle.c:96: warning: format ‘%i’ expects type ‘int *’, but argument 4 has type ‘int’
puzzle.c:96: warning: format ‘%i’ expects type ‘int *’, but argument 5 has type ‘int’
gcc -o sudoku main.o puzzle.o arguments.o

运行我的测试错误:

xxxxxxx@linus:~/350/sudoku$ make test_l2 
./sudoku -e p+s/good_puzzle.txt < p+s/script_good_quit.txt
/bin/sh: line 1:  9143 Segmentation fault      ./sudoku -e p+s/good_puzzle.txt < p+s/script_good_quit.txt
make: *** [good_configured] Error 139

【问题讨论】:

  • 这将无法编译,因为拼图未定义 - 你的代码如何不起作用 - 错误消息或其他可见行为是什么?
  • 我在问题中添加了编译和测试错误。

标签: c stdio scanf


【解决方案1】:

你正在做的事情有两个问题:

首先,您将跳过文件中的一堆行,因为您在 while 循环中调用 fscanf,然后在检查循环条件后立即调用。你只需要在while循环条件中调用一次。

    while((fscanf(puzzle_file, "%i%i%i\n", row, column, value)) != EOF){
            // fscanf(puzzle_file, "%i%i%i\n", row, column, value);  REMOVE THIS!
            puzzle[row][column] = value;
            fixed[row][column] = 1;
    }

其次,您可能希望将这些整数中的每一个都读取为单独的字符,即。 %c%c%c 而不是 %i%i%i,并将这些字符代码转换为整数值。 IE。减 ((int)ch - 48) 其中 ch 是 fscanf 读入的字符之一。

更新:

您还向 fscanf 传递了错误的值,您想传递变量的内存位置而不是它们的值。

char row,value,column;
fscanf(puzzle_file, "%c%c%c\n", &row, &column, &value);

更新 2:

还可以查看 ladenedge 对我的回答的评论,关于使用整数值的宽度说明符,而不是读取字符并转换它们。

【讨论】:

  • 我相信%1i%1i%1i 也能正常工作,无需转换。
  • @ladenedge:哦,我不知道那很好。
  • @ladenedge: %c%c%c 然后将它们转换为我需要的字符值,%1i%li%li 并将它们与 int 相同会做同样的事情吗?
  • 您的代码将无法在没有终止 '\n' 的情况下结束行!
  • @user411313:我知道,对于我正在处理的部分,我被告知要“假设”每一行都有一个终止 '\n'。
【解决方案2】:

警告清楚地表明了运行时可能出现的问题 -

 puzzle.c:95: warning: format ‘%i’ expects type ‘int *’, but argument 3 has type ‘int’

所以改变

(fscanf(puzzle_file, "%i%i%i\n", row, column, value)

(fscanf(puzzle_file, "%i%i%i\n", &row, &column, &value)
// Added & symbol

【讨论】:

    【解决方案3】:

    最好始终使用伪代码!看看上面的拼图/规范,我会做类似的事情:

    1. 打开文件
    2. 当你不在 EOF 时抓住第一行(它可能是一个字符串)
    3. 将 3 位数字分成单独的变量
    4. 谜题[num1][num2] = num3
    5. 固定[num1][num2] = 1
    6. 转到#2

    可能会在一两个地方关闭,因为我没有完全检查规格。

    【讨论】:

      猜你喜欢
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多