2017-02-12 11 views
0

Задача состоит в том, чтобы читать в текстовом файле с аргументом командной строки, в файле есть список неструктурированной информации Список каждый аэропорт в штате Флорида noteэто только фрагмент файла. Есть некоторые данные, которые необходимо игнорировать, такие как ASO ORL PR A 0 18400 - все, что не относится к структурированным переменным в AirPdata.File I/O Экстракция структур в C

У задание запрашивается номер сайта, locID, имя поля, город, штат, широта, долгота, и если есть диспетчерская башня или нет.

ВХОД

03406,20 * H 2FD7 ВОЗДУХА Орландо FL АСО ORL PR-28-26-08.0210N 081-28-23.2590W PR-НЕ-NPIAS Н.А. 0 18400

03406,18 * Н 32FL МКП Орландо Майер-FL АСО ORL PR-28-30-05.0120N 081-22-06.2490W PR-НЕ NPAS Н 0 0

ВЫХОД

Site# LocID Airport Name City ST Latitude Longitude Control Tower   
------------------------------------------------------------------------  
03406.20*H 2FD7 AIR ORLANDO ORLANDO FL 28-26-08.0210N 081-28-23.2590W N 
03406.18*H 32FL MEYER  ORLANDO FL 28-30.05.0120N 081-26-39.2560W N 
etc..  etc. etc..  etc.. .. etc..   etc..   .. 
etc..  etc. etc..  etc.. .. etc..   etc..   .. 

мой код до сих пор выглядит

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

typedef struct airPdata{ 
char *siteNumber; 
char *locID; 
char *fieldName; 
char *city; 
char *state; 
char *latitude; 
char *longitude; 
char controlTower; 
} airPdata; 

int main (int argc, char* argv[]) 
{ 

char text[1000]; 
FILE *fp; 
char firstwords[200]; 


if (strcmp(argv[1], "orlando5.txt") == 0) 
{ 

    fp = fopen(argv[1], "r"); 
    if (fp == NULL) 
    { 
     perror("Error opening the file"); 
     return(-1); 
    } 

    while (fgets(text, sizeof(text), fp) != NULL) 
    { 
     printf("%s", text); 
    } 
} 
else 
    printf("File name is incorrect"); 


fflush(stdout); 
fclose(fp); 


} 

До сих пор я в состоянии прочитать весь файл, а затем выводятся неструктурированный ввод в командной строке.

Следующее, что я попытался выяснить, состоит в том, чтобы извлекать по частям строки и хранить их в переменных внутри структуры. В настоящее время я застрял на этом этапе. Я искал информацию об strcpy и других функциях строковых библиотек, методах извлечения данных, ETL, я просто не знаю, какую функцию использовать правильно в моем коде.

Я сделал что-то очень похожее на это в java, используя подстроки, и если есть способ взять подстроку массивной строки текста и задать параметры того, какие подстроки удерживаются в какой переменной, что потенциально Работа. таких как ... LocID длиной не более 4 символов, поэтому все, что имеет числовую/буквенную комбинацию, состоящую из четырех букв, можно сохранить, например, в airPdata.LocID.

После того, как переменные хранятся внутри структур, я знаю, что я должен использовать strtok, чтобы организовать их в списке по сайту #, locID ... и т. Д. Однако, это мое лучшее предположение, чтобы подойти к этой проблеме, м довольно потеряно.

+1

Вы можете получить строку за строкой с помощью 'fgets()', и они разбиваются на слова с помощью 'strtok'. имейте в виду, что 'strtok' меняет ваши строки и добавляет' \ 0', если вам нужен текст для дальнейшего использования. –

+0

В своем вопросе вы говорите, что знаете, что вам нужно использовать 'strtok', что неплохо начать решение проблемы. Так что ты застрял? Просто сказать, что ваш потерянный не вызывает большой вопрос. –

+0

Я не уверен, что «назначение» означает, что это упражнение. Практический ответ - импортировать его в SQLite и использовать SQL. – Schwern

ответ

0

Я не знаю, какой формат. Он не может быть разделен пространством, некоторые из полей имеют в них пробелы. Он не выглядит фиксированной. Поскольку вы упомянули strtok, я собираюсь предположить его разделение на вкладку.

Вы можете использовать strsep использовать это. strtok has a lot of problems that strsep solves, но strsep не является стандартным C. Я собираюсь предположить, что это какое-то задание, требующее стандартного C, поэтому я буду оскорбительно использовать strtok.

Главное, что нужно сделать, это прочитать каждую строку, а затем разбить на столбцы с strtok или strsep.

char line[1024]; 
while (fgets(line, sizeof(line), fp) != NULL) { 
    char *column; 
    int col_num = 0; 
    for(column = strtok(line, "\t"); 
     column; 
     column = strtok(NULL, "\t")) 
    { 
     col_num++; 

     printf("%d: %s\n", col_num, column); 
    } 
} 
fclose(fp); 

strtok смешно. Он сохраняет свое внутреннее состояние, где он находится в строке. В первый раз, когда вы это называете, вы передаете ему строку, на которую вы смотрите. Чтобы получить остальные поля, вы вызываете его с помощью NULL, и он будет продолжать читать эту строку. Вот почему есть такая забавная петля, которая похожа на ее повторение.

Глобальное состояние опасно и очень подвержено ошибкам. strsep и strtok_r исправить это. Если вам говорят использовать strtok, найдите лучший ресурс для изучения.

Теперь, когда у нас есть каждый столбец и его позиция, мы можем делать то, что нам нравится. Я собираюсь использовать switch, чтобы выбрать только те столбцы, которые мы хотим.

for(column = strtok(line, "\t"); 
     column; 
     column = strtok(NULL, "\t")) 
    { 
     col_num++; 

     switch(col_num) { 
      case 1: 
      case 2: 
      case 3: 
      case 4: 
      case 5: 
      case 9: 
      case 10: 
      case 13: 
       printf("%s\t", column); 
       break; 
      default: 
       break; 
     } 
    } 

    puts(""); 

Вы можете делать все, что захотите, с помощью столбцов на этом этапе. Вы можете распечатать их немедленно или поместить их в список или структуру.

Просто помните, что column указывает на память в line и line будет перезаписан. Если вы хотите сохранить column, вам придется сначала его скопировать. Вы можете сделать это с помощью strdup, но * вздох *, который не является стандартным C. strcpy действительно прост в использовании. Если вы застряли со стандартным C, напишите свой собственный strdup.

char *mystrdup(const char *src) { 
    char *dst = malloc((sizeof(src) * sizeof(char)) + 1); 
    strcpy(dst, src); 
    return dst; 
} 
+0

и не забудьте проверить каждый вызов на 'malloc()', чтобы убедиться, что операция прошла успешно. – user3629249

+0

Функция: 'strdup()' всегда должна быть доступна с помощью '# define' соответствующего имени макроса в исходном коде (или, если вы используете' gcc', может иметь параметр: '-std = gnu99' (аналогичного) в вашем компиляционном заявлении – user3629249

+0

этот ответ не будет надежным, потому что несколько полей (название города, название аэропорта) могут быть 1 или 2 поля. – user3629249