【问题标题】:How to fscanf a file into a multi-dimensional array如何将文件fscanf成多维数组
【发布时间】:2019-04-25 09:09:06
【问题描述】:

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

@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)

【问题讨论】:

  • 代码有很多问题,最明显的是您没有声明filetest,所以我不确定它会如何编译?
  • 1) [...] – 不,你不能。使用fopen() 打开文件并确保检查返回值是否有错误。您可能还想检查argc 的值。完成文件后使用fclose()。此外,"%s %s %s %s %s" 不适用于您想要的格式,因为"%s" 会读取到下一个空格。像"88 : 88" 这样的部分你想保持在一起但是包含空格。
  • 代码中有很多错误,使用:f = fopen(argv[1],"r"); fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);

标签: c arrays multidimensional-array scanf argv


【解决方案1】:

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;
}

【讨论】:

    猜你喜欢
    • 2013-08-15
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 2013-05-12
    相关资源
    最近更新 更多