如果有的话,C fscanf会丢弃额外的字符

时间:2011-03-27 00:39:34

标签: c stdin scanf

我正在为我的一个课程开展这个项目,它说:“丢弃三位数字后的所有内容,包括下一个换行符或EOF”。

例如,以下是示例测试配置文件:

119
3561234
263abc

我需要将前三位数字符保存到定义为行,列,值(分别)的各个变量中。

我到目前为止的代码如下:

/*
 * 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, column, value; // Variables
    int count = 1; //the counter for what line we are on 

    /*
     * Loops through every line transforming the chars to character int values
     * for each int needed and addes it to puzzle and changes fixed values
     * at same location.
     */
    while((fscanf(puzzle_file, "%1i%1i%1i%*[^\n]", &row, &column, &value)) != EOF){
            if(!in_range(row) || !in_range(column) || !in_range(value)){
                    printf("Illegal format in configuration file at line %i\n", count);
                    exit(1);
            }
            if(puzzle[row][column] != 0){
                    printf("Illegal placement in configuration file at line %i\n",count);
                    exit(1);
            }

            puzzle[row][column] = value;
            fixed[row][column] = 1;

            count++;
    }

}

我希望第9行和第1列,第6行在第3行和第5列,第3行在第2行和第6列。

使用正确的格式化配置文件,它将进入第一个if语句并结束。

正确的配置文件示例:

123
356
235
etc..

我假设我的fscanf使它无法正常工作。你会如何改变它,以便这样做?

编辑1:

in_range函数:

/*
 * Return TRUE iff the value is in the Sudoku range (1 .. 9)
 */
static bool in_range(int value) {

    if(isdigit(value) && value != 0){
            return TRUE;
    }
    return FALSE;
}

2 个答案:

答案 0 :(得分:4)

您认为fscanf()使用正则表达式。

没有。 C没有正则表达式。

你正在寻找:

fscanf(puzzle_file, "%1i%1i%1i%*s", &row, &column, &value)

这会将第1,第2和第3个字符作为整数抓取,然后该行的其余数据将不会存储在变量中。

我从未在scanf中看到[^/n],显然这不是问题所在。

我怀疑问题出在你的in_range()函数中。那是什么?

编辑,因为已发布其他代码:

你的fscanf很好。你的in_range()不是。 isdigit()告诉您字符是否为数字。

重新阅读您的要求,我建议您使用线路阅读逻辑:

char buffer[5];
int row, column, value;
int count = 1;
while(fgets(buffer, 5, puzzleFile) != NULL)
{
    if ( (buffer[3] == '\n') 
          && (sscanf(buffer, "%1i%1i%1i%*[^\n]", &row, &column, &value) == 3))
    {
         puzzle[row][column] = value;
    }
    else
    {
          printf("Illegal format in configuration file at line %i\n", count);
          exit(1);
    }
    count++;

}

这可以保证每行有3个字符和换行符。 sscanf中的%1i保证每个字符都是0-9范围内的数字,如果所有三个匹配并分配给您的变量(它返回赋值数)。

答案 1 :(得分:1)

尝试使用类似getline()之类的内容,一次从文件读取一行到缓冲区。然后使用

sscanf(buffer, "%1d%1d%1d", &row, &column, &value);

将值扫描到变量中。