PGFDBUG
PGFDBUG

Reputation: 45

Using tr in cygwin

I know you guys will prob. laugh me out of here but here goes. Im a complete novice at programming, completely self taught and dealing with code someone else wrote.

I need to delete excess null characters from a file, they serve no purpose and are not the end of line or end of file marker. Looking around i found the tr utility and can not for the life of me make it work. I keep getting : 'tr' undeclared (first use in this function).

Can anyone help

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

Upvotes: 0

Views: 1350

Answers (3)

ShinTakezou
ShinTakezou

Reputation: 9681

Are you mixing C with a pipe like if it is a shell interpreter? You can't do it. Your line is like assign to c the result of bitwise or of pktdata[i-1] with tr, subtract d ... syntax error (since '\000' has no a syntactical "place").

To operate on files in C you need fopen, fclose, fread, fwrite, fsetpos: you "move" to the end of the file and read it backward until something != 0 is reached; then you can use ftruncate to trunc its length to the desidered — but ftruncate is POSIX, not C99 or similar (likely cygwin has it).

You could read all the file (if it is not big) into a buffer with fread, then find the correct length, and write it back to another file or the same opened as read/write.

E.g. a trunc little program could look like

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

(important there are no error checks at all). But this is not the best to work with huge files (currently it handles at most files less than 1024 bytes long).

Using ftruncate is surely better; you can read last N bytes, search for zeros and decrease length accordingly, if the chosen "window" contains only 0, then read backward other N bytes and so on; at last, your final computed length will be the length of your file, and you can use ftruncate.

EDIT

For some reason I've interpreted your question as removing trailing nulls. Being not so, you need, after you read the file in the buffer (keeping the same defect i.e. reading all into the buffer instead of just chunks...), output bytes after bytes, if they are not 0 (you again can optimize it to find blocks that do not contain 0s and fwrite them at once).

The previous code is modified so that you loop from 0 up to the length (not inclusive) and fwrite a single byte iff it is != 0, otherwise continue.

Upvotes: 2

hari
hari

Reputation: 9733

Just for your learning, if you want any of shell like functionality in C, use system. What you are trying to do will be easy with a shell cmd call.

Upvotes: 0

prusswan
prusswan

Reputation: 7101

Your example is almost like a shell script, so perhaps you need something along these lines:

cat <yourfile> | tr -d '\000'

Upvotes: 0

Related Questions