如何将文件扫描到多维数组

时间:2018-11-22 16:33:08

标签: c arrays multidimensional-array scanf argv

场景:我有一个以下格式的文件。

@209.161.198.176/28 209.161.198.160/28 88 : 88 80 : 80 0x11/0xFF
@203.124.178.48/28 203.124.183.192/28 123 : 123 23 : 23 0x11/0xFF
@175.54.90.240/28 209.161.199.160/28 53 : 53 21 : 21 0x11/0xFF
@175.54.96.176/28 209.161.199.160/28 123 : 123 544 : 544 0x11/0xFF
@5.220.189.176/28 5.220.186.176/28 750 : 750 123 : 123 0x11/0xFF
.../*and the file contain about 100000 lines*/

每行可以分为5个部分。

//For example:
(@209.161.198.176/28) (209.161.198.160/28) (88 : 88) (80 : 80) (00x11/0xFF)

我需要读取文件并将其存储到每个部分的5个多维数组中。第一个维度将是它的哪一行,第二个维度将存储其字符串值。

//For example, the array to store the first section might have the following structure:
[line0][@209.161.198.176/28]
[line1][@203.124.178.48/28]
[line2][@175.54.90.240/28]
... 
(array[line][string])

问题是我总是遇到细分错误,我也不知道为什么。

这是我当前的代码:

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

int main(int argc, char *argv[]){
    FILE *f;
    char file1[100000][100], file2[100000][100], file3[100000][100], file4[100000][100], file5[100000][100];

    char file = argv[1];
    f = fopen(file,"r");
    fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
    printf("%c%c",fike1[0][0],file1[0][1]);
    fclose(f);

    return 0;
}

在第10行,我尝试阅读第一行。在第11行,我尝试打印出第0行的第一部分的前2个字符。

我可能想到的问题是:

1)我不能像这样直接打开argv [1]。

2)也许我需要在某处添加*或&,但找不到。

(OAO)

1 个答案:

答案 0 :(得分:0)

fgets可用于读取每一行,然后解析该行的五个部分。
前两节很容易使用sscanf进行解析。 %n说明符将报告扫描处理的字符数。使用该数字作为进一步分析的偏移量。
第三部分和第四部分很困难,因为它们包含空格并且由空格分隔。可以使用sscanf,但是需要分析较小的部分并将其串联成完整的部分。
strspn是一种计数匹配字符组的选项,然后是strncpy个计数字符。
对所有已处理的字符进行计数使使用sscanf轻松解析最后一部分。
三维数组将所有线和节保持在一起。
结构将是组织数据的另一种方式。

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

#define LINES 1000
#define SECTIONS 5
#define SIZE 99
//lenstr so SIZE can be part of sscanf Format String
#define FS_(x) #x
#define FS(x) FS_(x)

int main( int argc, char *argv[]) {
    char input[SIZE + 1] = "";//SIZE + 1 to allow for zero terminator
    char record[LINES][SECTIONS][SIZE + 1] = { { { 0}}};
    char *digits = "0123456789";
    char *colon = " :";
    int offset = 0;
    int span = 0;
    FILE* pf = NULL;

    if ( 2 != argc) {
        fprintf ( stderr, "useage:\n\t%s filename\n", argv[0]);
        return 0;
    }

    if ( NULL == ( pf = fopen ( argv[1], "r"))) {
        fprintf ( stderr, "could not open %s\n", argv[1]);
        return 0;
    }

    int line = 0;
    while ( LINES > line && fgets ( input, sizeof input, pf)) {
        span = 0;
        if ( 2 == sscanf ( input, "%"FS(SIZE)"s%"FS(SIZE)"s%n", record[line][0], record[line][1], &offset)) {
            for ( int each = 2; each < 4; ++each) {//loop for sections 2 and 3
                if ( ! ( span = strspn ( &input[offset], " "))) {//count spaces
                    break;
                }
                offset += span;//skip spaces
                span = strspn ( &input[offset], digits);//count digits
                span += strspn ( &input[offset + span], colon);//count colon and spaces
                span += strspn ( &input[offset + span], digits);//count digits
                if ( ! span || SIZE < span) {
                    break;
                }
                strncpy ( record[line][each], &input[offset], span);//copy span number of characters
                record[line][each][span] = 0;//zero terminate

                offset += span;//advance offset to next section
            }

            if ( span && SIZE > span) {
                sscanf ( &input[offset], "%"FS(SIZE)"s", record[line][4]);
                line++;
                if ( line >= LINES) {
                    break;
                }
            }
        }
    }

    fclose ( pf);

    for ( int item = 0; item < line; ++item) {
        for ( int each = 0; each < SECTIONS; ++each) {
            printf ( "record[%d][%d] %s\n", item, each, record[item][each]);
        }
        printf ( "\n");
    }

    return 0;
}