C,从文件输入到2d数组

时间:2022-10-04 13:12:09

Can any one explain to me how to make a C program to read input from a file according to the following scenario:

根据以下场景,任何人都可以向我解释如何使C程序从文件中读取输入:

12
2-4,7,9;
1,4,11-12;
1,4,10,12;
1,4-8,10-12;
1,8;
1,3-6,8,10-12;
1,3,5-6,8,11;
1,8,10-12;
1-8;
;
2;
2-4,7-10,12;

The first number (on the first line) describes what size the grid should be, in this case a 12x12 grid. The following lines describe how many cells are occupied on each row of the grid. For example, in the first row the cells from 2 to 4 and 7 and 9 are occupied; in the second row, the cells 1, 4 and from 11 to 12 are occupied and so on.

第一个数字(在第一行)描述了网格的大小,在这种情况下是12x12网格。以下行描述了网格每行占用的单元数。例如,在第一行中,2到4和7和9的单元被占用;在第二行中,单元1,4和11至12被占用,等等。

Right now I have this code, but it is not solving my problem ...

现在我有这个代码,但它没有解决我的问题......

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

void main()
{   
    char content[3000];

    int value;
    FILE *ptr_file = fopen("data.txt", "r");
    if(!ptr_file)
        return 1;
    int j;

    while(fgets(content, 3000, ptr_file)!=NULL){
        printf("%s", content);
        value = atoi(content);   

        for(j=0; j<3000; j++){
            value = content[j];
            printf("%i", value);
        }
    }
    return 0;
}

Console throws just a bunch of random numbers ...

控制台只抛出一堆随机数......

3 个解决方案

#1


0  

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

enum { EOD = -1, EOL = -2, ERR = -3, OFF = 0, ON = 1 };//End Of Data, End Of Line

int getValue(FILE *fp){
    static int on_yield = OFF, prev, end;

    if(on_yield == ON && prev < end){
        return ++prev;
    }
    on_yield = OFF;

    int n, ch = fgetc(fp);

    if(ch == EOF)
        return EOD;
    else if(ch == ';')
        return EOL;
    else if(ch == ',' || ch == '\n')
        return getValue(fp);//or change to using loop
    else if(isdigit(ch)){
        ungetc(ch, fp);
        fscanf(fp, "%d", &n);
        return prev=n;
    } else if(ch == '-'){
        on_yield = ON;
        fscanf(fp, "%d", &n);
        end = n;
        return getValue(fp);
    }
    fprintf(stderr, "(%c) invalid format in file\n", ch);
    return ERR;
}

int main(void){
    FILE *ptr_file = fopen("data.txt", "r");
    if(!ptr_file){
        perror("fopen");
        return 1;
    }

    int size;
    fscanf(ptr_file, "%d", &size);//check omitted
    char (*cell)[size] = malloc(size * sizeof(*cell));
    memset(&cell[0][0], ' ', size*size);

    int r = 0, c, value;
    while((value=getValue(ptr_file))!=EOD){
        if(value == EOL){
            ++r;
            continue;
        }
        if(value > 0)
            cell[r][value-1] = '*';
    }
    fclose(ptr_file);

    for(r = 0; r < size; ++r){
        for(c = 0; c < size; ++c){
            putchar(cell[r][c]);
        }
        putchar('\n');
    }
    free(cell);

    return 0;
}

#2


1  

Pseudo-code:

伪代码:

Open your file
Read the first line
    Extract the value N
    Allocate your grid
Loop N times
    Read a line
    If not an empty line, ie. semi-colon only
       Split into tokens by comma
       Check for a range or a single digit
       Extract numbers
       Set cells accordingly

#3


1  

The "random" numbers are the byte values from your file and you forgot to stop at end of line. Dave's solution is not quite right for c. After read a line:

“随机”数字是文件中的字节值,您忘记在行尾停止。戴夫的解决方案不太适合c。读完一行后:

while not semicolon
    strtoul a number
    if no number
        exit error
    if next char is hyphen
        shift to next char
        strtoul end of range
        if no number
            exit error
        set cells
    else
        set cell
    if next char is not semicolon
        shift to next char

You should not use atoi for anything ever. Use sscanf or strto….

你不应该使用atoi。使用sscanf或strto ......

#1


0  

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

enum { EOD = -1, EOL = -2, ERR = -3, OFF = 0, ON = 1 };//End Of Data, End Of Line

int getValue(FILE *fp){
    static int on_yield = OFF, prev, end;

    if(on_yield == ON && prev < end){
        return ++prev;
    }
    on_yield = OFF;

    int n, ch = fgetc(fp);

    if(ch == EOF)
        return EOD;
    else if(ch == ';')
        return EOL;
    else if(ch == ',' || ch == '\n')
        return getValue(fp);//or change to using loop
    else if(isdigit(ch)){
        ungetc(ch, fp);
        fscanf(fp, "%d", &n);
        return prev=n;
    } else if(ch == '-'){
        on_yield = ON;
        fscanf(fp, "%d", &n);
        end = n;
        return getValue(fp);
    }
    fprintf(stderr, "(%c) invalid format in file\n", ch);
    return ERR;
}

int main(void){
    FILE *ptr_file = fopen("data.txt", "r");
    if(!ptr_file){
        perror("fopen");
        return 1;
    }

    int size;
    fscanf(ptr_file, "%d", &size);//check omitted
    char (*cell)[size] = malloc(size * sizeof(*cell));
    memset(&cell[0][0], ' ', size*size);

    int r = 0, c, value;
    while((value=getValue(ptr_file))!=EOD){
        if(value == EOL){
            ++r;
            continue;
        }
        if(value > 0)
            cell[r][value-1] = '*';
    }
    fclose(ptr_file);

    for(r = 0; r < size; ++r){
        for(c = 0; c < size; ++c){
            putchar(cell[r][c]);
        }
        putchar('\n');
    }
    free(cell);

    return 0;
}

#2


1  

Pseudo-code:

伪代码:

Open your file
Read the first line
    Extract the value N
    Allocate your grid
Loop N times
    Read a line
    If not an empty line, ie. semi-colon only
       Split into tokens by comma
       Check for a range or a single digit
       Extract numbers
       Set cells accordingly

#3


1  

The "random" numbers are the byte values from your file and you forgot to stop at end of line. Dave's solution is not quite right for c. After read a line:

“随机”数字是文件中的字节值,您忘记在行尾停止。戴夫的解决方案不太适合c。读完一行后:

while not semicolon
    strtoul a number
    if no number
        exit error
    if next char is hyphen
        shift to next char
        strtoul end of range
        if no number
            exit error
        set cells
    else
        set cell
    if next char is not semicolon
        shift to next char

You should not use atoi for anything ever. Use sscanf or strto….

你不应该使用atoi。使用sscanf或strto ......