Как найти файл в многомерном массиве - PullRequest
0 голосов
/ 22 ноября 2018

Сценарий: у меня есть файл в следующем формате.

@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 я пытаюсь распечатать первые 2 символа первого раздела строки 0.

Возможная проблема, о которой я могу подумать:

1) Я не могу открыть argv [1] напрямую, как это.

2) Возможно, мне нужно добавить *или & где-то, но я не могу его найти.

(ОАО)

1 Ответ

0 голосов
/ 23 ноября 2018

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