简体   繁体   English

使用 fscanf 读取 C 中 pgm 文件中的特定行和整数

[英]Read particular lines and integers in pgm file in C using fscanf

P2
5 7
255
100 114 111 100 112
90  110 112 110 111
90  110 124 110 119
80  110 110 110 118
90  110 100 110 109
111 110 163 110 120
100 98  111 145 112

I need to read this pgm file in C using fscanf我需要使用 fscanf 读取 C 中的这个 pgm 文件

I have managed to read line one and store the P2 in a variable called p2 I'm stuck on reading (line 2 integer 1) and (line 2 integer 2) which are 5 & 7 I want to store read them and store them in variables row and col我已设法读取第一行并将 P2 存储在一个名为 p2 的变量中变量行和列

Next I want to read in line 3 "255" and store that also接下来我想在第 3 行“255”中读取并存储它

Them I need to read Everything from line 4 onward and store all the rest of the greyscale values in a variable greyscale.他们我需要从第 4 行开始读取所有内容,并将灰度值的所有 rest 存储在可变灰度中。

I understand everything I need to read the file except reading each line and integer using fscanf can someone help here is my code so far我了解读取文件所需的所有内容,除了使用 fscanf 读取每一行和 integer 有人可以帮助这里是我的代码到目前为止

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    char p2[2];
    int row[3];
    int col[3];
    int max[4];
    int greyscale[35];
    int i;
    FILE *input_fptr;

    if ((input_fptr = fopen("image1.pgm", "r")) == NULL)
    {
        printf("ERROR! File cannot be opened.");

        exit(1);
    }

    // Read in Line 1  using fscanf
    fscanf(input_fptr, "%s", p2);
    printf("Line 1 data is: %s\n", p2);
    
    // Read in Line 2 rows and colulmns
    while ((fscanf (input_fptr, "%d", &row)) == 3)
    {
        printf("%d", row);
    }
    printf("\n");
    
    fclose(input_fptr);
    
    return 0;
    
}

A string in C is a null-terminated character array. C 中的字符串是以空字符结尾的字符数组。 That is, a series of non-null characters followed by a null character.也就是说,一系列非空字符后跟一个 null 字符。

"P2" in memory would be { 'P', '2', '\0' } . memory 中的"P2"将是{ 'P', '2', '\0' } char [2] could only hold the first two bytes here. char [2]在这里只能保存前两个字节。 You must make sure to have enough room to store this terminating byte, or risk running outside of memory boundaries when using functions that expect to work in terms of C strings .您必须确保有足够的空间来存储此终止字节,否则在使用预期以 C字符串工作的函数时,可能会运行在 memory 边界之外。

On the other hand, the format specifier "%s" will read as many characters as it can until it reaches a whitespace character ( isspace ), which may lead to buffer overflows.另一方面,格式说明符"%s"将读取尽可能多的字符,直到它到达一个空白字符 ( isspace ),这可能导致缓冲区溢出。 For this reason, it is a good idea to limit the maximum amount of data read with a field-width specifier .出于这个原因,最好使用字段宽度说明符来限制读取的最大数据量。 This should be the size of your array minus one, as *scanf will always need room to place the null-terminating byte.这应该是数组的大小减一,因为*scanf总是需要空间来放置空终止字节。

char string[3];
scanf("%2s", string);

row , col and max should not be be arrays. rowcolmax不应为 arrays。 They are each a singular value.它们都是一个奇异值。

The dimensions of greyscale would appear to relate to the values of col and row . greyscale的尺寸似乎与colrow的值有关。 As such, it would be more appropriate to size this array at runtime using a variable-length array , or dynamic memory allocation .因此,在运行时使用可变长度数组动态 memory 分配来调整此数组的大小会更合适。

You will want to use the values of col and row as maximums to loop through and populate your array.您将希望使用colrow的值作为最大值来循环并填充您的数组。


Here is an example using a two dimensional variable-length array.这是一个使用二维可变长度数组的示例。 Use rows * cols as the size for a one dimensional array.使用rows * cols作为一维数组的大小。

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

int main(int argc, char **argv) {
    FILE *file;
    char title[16];
    size_t cols, rows;
    unsigned max;

    if (argc < 2 || NULL == (file = fopen(argv[1], "r")))
        /* handle file failure */;

    if (4 != fscanf(file, "%15s%zu%zu%u", title, &cols, &rows, &max))
        /* handle format failure */;

    unsigned data[rows][cols];

    for (size_t i = 0; i < rows; i++)
        for (size_t j = 0; j < cols; j++)
            if (1 != fscanf(file, "%u", &data[i][j]))
                /* handle format failure */;

    printf("%s [%zux%zu] (<=%u):\n", title, rows, cols, max);

    for (size_t i = 0; i < rows; i++) {
        for (size_t j = 0; j < cols; j++)
            printf("%3u ", data[i][j]);

        putchar('\n');
    }

    fclose(file);
}

./read-pgm image1.pgm output: ./read-pgm image1.pgm image1.pgm output:

P2 [7x5] (<=255):
100 114 111 100 112 
 90 110 112 110 111 
 90 110 124 110 119 
 80 110 110 110 118 
 90 110 100 110 109 
111 110 163 110 120 
100  98 111 145 112 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM