Использование tr в cygwin - PullRequest
0 голосов
/ 23 июля 2011

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

Мне нужно удалить лишние нулевые символы из файла, они не служат цели и не являются концом строки или концом файламаркер.Оглядываясь вокруг, я нашел утилиту tr и не могу на всю жизнь заставить ее работать.Я продолжаю получать: 'tr' undeclared (первое использование в этой функции).

Может кто-нибудь помочь

c = pktdata[i-1] | tr -d '\000';

Ответы [ 3 ]

2 голосов
/ 23 июля 2011

Вы смешиваете C с каналом, как будто это интерпретатор оболочки?Вы не можете сделать это.Ваша строка подобна присваиванию c результата побитового или pktdata[i-1] с tr, вычитания d ... синтаксической ошибки (так как '\000' не имеет синтаксического «места»).

Для работы с файламив C вам нужны fopen, fclose, fread, fwrite, fsetpos: вы «перемещаетесь» в конец файла и читаете его задом наперед, пока что-нибудь не будет достигнуто! = 0;тогда вы можете использовать ftruncate для сокращения его длины до желаемого - но ftruncate - это POSIX, а не C99 или аналогичный (вероятно, у cygwin есть он).

Вы можете прочитать весь файл (если он не большой)в буфер с fread, затем найдите правильную длину и запишите ее обратно в другой файл или тот же файл, который открыт для чтения / записи.

Например, небольшая программа усечения может выглядеть как

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

#define MAXLEN 1024

int main(int argc, char **argv)
{
  long i;
  if (argc < 2) return EXIT_SUCCESS;
  char *buf = malloc(MAXLEN);
  FILE *fh = fopen(argv[1], "r");
  (void)fseek(fh, 0, SEEK_END);
  long len = ftell(fh);
  if (len > MAXLEN)
  {
    fclose(fh);
    free(buf);
    return EXIT_FAILURE;
  }
  rewind(fh);
  (void)fread(buf, 1, len, fh);
  fclose(fh);
  fh = fopen(argv[1], "w");
  for(i = len-1; i >= 0 && buf[i] == 0; i--) ;
  i++;
  if (i > 0) (void)fwrite(buf, 1, i, fh);
  fclose(fh);
  free(buf);
  return EXIT_SUCCESS;
}

( важно проверка ошибок вообще не производится).Но это не лучший способ работы с большими файлами (в настоящее время он обрабатывает большинство файлов длиной менее 1024 байт).

Использование ftruncate, безусловно, лучше;Вы можете читать последние N байтов, искать нули и соответственно уменьшать длину, если выбранное «окно» содержит только 0, затем читать назад N других байтов и т. д .;наконец, ваша окончательная вычисленная длина будет равна длине вашего файла, и вы можете использовать ftruncate.

EDIT

По какой-то причине я интерпретировал ваш вопрос какудаление завершающих нулей.В противном случае вам нужно после того, как вы прочитаете файл в буфере (сохраняя тот же дефект, т. Е. Считав все в буфер, а не просто куски ...), вывести байты за байтами, если они не равны 0 (вы снова можете оптимизироватьчтобы найти блоки, которые не содержат 0, и записать их сразу).

Предыдущий код изменен так, что вы зацикливаетесь от 0 до длины (не включительно) и записываете один байт, если это так!= 0, иначе continue.

0 голосов
/ 23 июля 2011

Просто для вашего обучения, если вам нужна какая-либо из функций, подобных оболочке в C, используйте system. То, что вы пытаетесь сделать, будет легко с помощью вызова командной оболочки.

0 голосов
/ 23 июля 2011

Ваш пример почти похож на скрипт оболочки, поэтому, возможно, вам нужно что-то вроде этого:

cat <yourfile> | tr -d '\000'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...