C - прочитать конкретную строку из файла - PullRequest
0 голосов
/ 12 апреля 2011

Я пытаюсь прочитать конкретную строку из файла, и я могу получить номер строки, но я не уверен, как это сделать, вот что у меня так:

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

int main(int argc, char **argv)
{
  FILE *file;
  file = fopen("temp.txt","r");
  char tmp[256]={0x0};
  char *tmpline;
  int numline = 1;
  while(file != NULL && fgets(tmp, sizeof(tmp),file) !=NULL)
  {
    tmpline = strstr(tmp,"status:green");

    if(tmpline) {
      printf("%d - %s", numline, tmpline);
    }

    numline++;
  }
  if (file != NULL) fclose(file);

  return 0;
}

Тестовый файл выглядит следующим образом:

s1.server.com
127.0.0.1 
status:green

s2.server.com
127.0.0.1 
status:red

s3.server.com
127.0.0.1 
status:red

s4.server.com
127.0.0.1 
status:green

Вывод, который у меня есть:

3 - status:green 
15 - status:green

Но я действительно хочу, чтобы это было показано:

s1.server.com
s4.server.com

Я хочу, чтобы он выполнил поиск "status: green", а затем вернулся на несколько строк, чтобы показать, какому серверу он принадлежит

Ответы [ 3 ]

1 голос
/ 12 апреля 2011

Если тестовый файл (и рабочий файл) правильно сформирован, то вы можете сделать что-то вроде следующего (проверка ошибок исключена для краткости!):

typedef struct _SERVERSTATUS
{
    char* name;
    char* ip;
    char* status;
} SERVERSTATUS;


SERVERSTATUS ss;

ss.name = calloc(256);
ss.ip = calloc(256);
ss.status = calloc(256);

while (!feof(file))
{
    fgets(ss.name, file);
    fgets(ss.ip, file);
    fgets(ss.status, file);

    if (!strcmp(ss.status, "status:green"))
       printf("%s\n", ss.name);
}

free(ss.name);
free(ss.ip);
free(ss.status);

Редактировать: Вы также должны обрабатывать пробелы между записями файла! Это оставлено в качестве упражнения для спрашивающего

1 голос
/ 12 апреля 2011

Звучит так, как будто вам нужно сделать одну из двух вещей.

Более простая опция : сохранить небольшой круговой буфер строк. Прочитайте строку 0, строку 1, строку 2, ..., строку n-1, строку 0, строку 1 и т. Д. Затем, когда вы увидите нужный текст, посмотрите в записи (current_index - 2) мод buffer_size. (Здесь звучит так, как будто размера буфера будет достаточно 3).

Более сложная опция : фактически проанализируйте входные данные, чтобы для каждого блока вы работали с именем сервера, его IP-адресом и его состоянием, а затем отображали нужную вам информацию, используя это.

«Более сложный вариант» будет значительно более трудоемким, но более надежным, если синтаксис вашего ввода когда-либо изменится (например, с дополнительными дополнительными строками с дополнительной информацией о сервере - возможно, с несколькими IP-адресами или несколькими именами) .

Есть и другие вещи, которые вы могли бы сделать, я думаю, хуже. (1) Вызовите ftell в каждой строке и поместите результаты , что в круговой буфер, а затем используйте fseek, когда увидите «status: green». (2) Прочитайте весь файл, используя код, который у вас есть на данный момент, составив список номеров строк «хороших» серверов. Затем снова просмотрите файл и сообщите о хороших. Я думаю, что они более уродливы и менее эффективны, чем подходы, которые я перечислил выше. Есть одно возможное преимущество: вы можете адаптировать их для подсчета в «строфах», разделенных пустыми строками, без необходимости правильного разбора. Это даст вам часть гибкости «более сложного» подхода, о котором я говорил, без необходимости правильного парсера.

И вот гибридная возможность: не используйте круговой буфер, но тот, размер которого может увеличиться, если это будет необходимо. Начните с первой записи в буфере каждый раз, когда вы видите пустую строку. Пусть буфер растет, если есть "длинные" строфы. Затем, когда вы увидите «status: green», выполните любую необходимую обработку в (предположительно завершенном) разделе, который теперь содержится в вашем буфере.

Ничего из вышеперечисленного не требуется, конечно, если вы уверены, что формат файла никогда не изменится.

0 голосов
/ 12 апреля 2011

Прочитайте первую и третью строки в каждой группе. Найдите status:green и, если найдено, напечатайте имя сервера.

...