streams binary and text

Discussion in 'C Programming' started by Bill Cunningham, Aug 29, 2012.

  1. Do the functions fread and fwrite specifically deal with binary data and
    not text? Can fgetc and fputc be used to deal with binary or are they only
    for text streams. I know *nixs do not discriminate in texual or binary data
    but the 'b' in fopen statements for opening streams is portabile across
    platforms. But with a linux can I alter the data of an AVI? It is binary
    isn't it and I would want to open a stream and use fprintf would I with the
    %x conversion.

    Bill
    Bill Cunningham, Aug 29, 2012
    #1
    1. Advertising

  2. Don't make my brown eyes China Blue wrote:
    > In article k1jr5h$aha$,


    [snip]

    Whether
    > the resulting file is still an AVI depends on whether your changes
    > conform to the AVI format.


    Say the file signature of an AVI is RIFF which represents four bytes. I
    have to find where that is in the stream with for example fseek. How would I
    do that? Simple enough with a hex editor but lives streams is harder.

    Bill
    Bill Cunningham, Aug 29, 2012
    #2
    1. Advertising

  3. בת×ריך ×™×•× ×¨×‘×™×¢×™, 29 ב×וגוסט 2012 03:27:46 UTC+1, מ×ת Bill Cunningham:
    >
    > Say the file signature of an AVI is RIFF which represents four bytes. I
    > have to find where that is in the stream with for example fseek. How would I
    > do that? Simple enough with a hex editor but lives streams is harder.
    >

    /*
    find a tag / string in a stream.
    Params: fp - pointer to open file
    tag - return for tag.
    Returns: 0 = no tag in file, 1 = seek to tag , -1 error or some sort
    Notes: Not tag structure aware, so some tags may be be spurious.
    Notes: untested
    */
    int seektag(FILE *fp, char *tag)
    {
    int ch;
    char *buff;
    int N;
    long pos;

    N = strlen(tag);
    buff = malloc(N);
    if(!buff)
    return -1;
    while( (ch = fgetc(fp)) != EOF)
    {
    if(ch == buff[0])
    {
    ungetc(ch, fp);
    pos = ftell(fp);
    if( fread(buff, 1, N, fp) != N)
    {
    free(buff);
    return -1;
    }
    if(!strncmp(buff, tag, N))
    {
    fseek(fp, pos, SEEK_SET);
    free(buff);
    return 1;
    }
    }
    }
    /* weve got to the end without finding the tag */
    free(buff);
    if(ferror(fp))
    return -1;
    return 0;
    }
    Malcolm McLean, Aug 29, 2012
    #3
  4. On Wed, 29 Aug 2012 04:27:43 -0700 (PDT), Malcolm McLean
    <> wrote:

    >?????? ??? ?????, 29 ??????? 2012 03:27:46 UTC+1, ??? Bill Cunningham:
    >>
    >> Say the file signature of an AVI is RIFF which represents four bytes. I
    >> have to find where that is in the stream with for example fseek. How would I
    >> do that? Simple enough with a hex editor but lives streams is harder.
    >>

    >/*
    > find a tag / string in a stream.
    > Params: fp - pointer to open file
    > tag - return for tag.
    > Returns: 0 = no tag in file, 1 = seek to tag , -1 error or some sort
    > Notes: Not tag structure aware, so some tags may be be spurious.
    > Notes: untested
    >*/
    >int seektag(FILE *fp, char *tag)
    >{
    > int ch;
    > char *buff;
    > int N;
    > long pos;
    >
    > N = strlen(tag);
    > buff = malloc(N);
    > if(!buff)
    > return -1;
    > while( (ch = fgetc(fp)) != EOF)
    > {
    > if(ch == buff[0])


    At this point, isn't buff[0] indeterminate during the first iteration
    of the while loop? buff doesn't receive a value until the fread
    below.

    > {
    > ungetc(ch, fp);
    > pos = ftell(fp);
    > if( fread(buff, 1, N, fp) != N)
    > {
    > free(buff);
    > return -1;
    > }
    > if(!strncmp(buff, tag, N))
    > {
    > fseek(fp, pos, SEEK_SET);
    > free(buff);
    > return 1;
    > }
    > }
    > }
    > /* weve got to the end without finding the tag */
    > free(buff);
    > if(ferror(fp))
    > return -1;
    > return 0;
    >}


    --
    Remove del for email
    Barry Schwarz, Aug 29, 2012
    #4
  5. Malcolm McLean <> writes:

    > בת×ריך ×™×•× ×¨×‘×™×¢×™, 29 ב×וגוסט 2012 03:27:46 UTC+1, מ×ת Bill Cunningham:
    >>
    >> Say the file signature of an AVI is RIFF which represents four bytes. I
    >> have to find where that is in the stream with for example fseek. How would I
    >> do that? Simple enough with a hex editor but lives streams is harder.
    >>

    > /*
    > find a tag / string in a stream.
    > Params: fp - pointer to open file
    > tag - return for tag.
    > Returns: 0 = no tag in file, 1 = seek to tag , -1 error or some sort
    > Notes: Not tag structure aware, so some tags may be be spurious.
    > Notes: untested
    > */
    > int seektag(FILE *fp, char *tag)


    A note the anyone learning C: Malcolm objects to both "const" and
    "size_t" so this function won't work with const char * arguments
    (without a cast) and it contains a lot of needless signed/unsigned int
    conversions. I'd add const above and declare N below as size_t.

    (Malcolm: I'm not trying to convert you, but I think your opinion is
    singular enough to merit being pointed out.)

    > {
    > int ch;
    > char *buff;
    > int N;
    > long pos;
    >
    > N = strlen(tag);
    > buff = malloc(N);
    > if(!buff)
    > return -1;
    > while( (ch = fgetc(fp)) != EOF)
    > {
    > if(ch == buff[0])


    Typo: you mean tag[0] of course.

    > {
    > ungetc(ch, fp);
    > pos = ftell(fp);
    > if( fread(buff, 1, N, fp) != N)
    > {
    > free(buff);
    > return -1;
    > }
    > if(!strncmp(buff, tag, N))
    > {
    > fseek(fp, pos, SEEK_SET);
    > free(buff);
    > return 1;
    > }
    > }
    > }
    > /* weve got to the end without finding the tag */
    > free(buff);
    > if(ferror(fp))
    > return -1;
    > return 0;
    > }


    I think this is working too hard. I'd match as we go, mainly because it
    avoid using a buffer. I think the result is clearer:

    int seektag(FILE *fp, const char *tag)
    {
    int ch;
    size_t match = 0, tlen = strlen(tag);
    long pos;

    while (match < tlen && (ch = fgetc(fp)) != EOF)
    if (ch == tag[match]) {
    if (match == 0) {
    ungetc(ch, fp);
    pos = ftell(fp);
    fgetc(fp);
    }
    match += 1;
    }
    else match = 0;

    if (match == tlen) {
    fseek(fp, pos, SEEK_SET);
    return 1;
    }
    if (ferror(fp))
    return -1;
    return 0;
    }

    I'd be inclined protect against empty tag strings, but your code did not
    so I copied that decision.

    It's even simpler if you are prepared to rely on SEEK_CUR (i.e. a binary
    stream):

    int seektag(FILE *fp, const char *tag)
    {
    int ch;
    size_t match = 0, tlen = strlen(tag);

    while (match < tlen && (ch = fgetc(fp)) != EOF)
    if (ch == tag[match])
    match += 1;
    else match = 0;

    if (match == tlen) {
    fseek(fp, -(long)tlen, SEEK_CUR);
    return 1;
    }
    if (ferror(fp))
    return -1;
    return 0;
    }

    --
    Ben.
    Ben Bacarisse, Aug 29, 2012
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Adam Warner

    Dual binary/character streams?

    Adam Warner, Nov 6, 2005, in forum: Java
    Replies:
    18
    Views:
    994
    Roedy Green
    Nov 8, 2005
  2. Tron Thomas
    Replies:
    3
    Views:
    483
    Tron Thomas
    Nov 8, 2004
  3. , India

    text and binary streams

    , India, Aug 23, 2008, in forum: C Programming
    Replies:
    4
    Views:
    403
    Peter Nilsson
    Aug 25, 2008
  4. Leslaw Bieniasz
    Replies:
    2
    Views:
    1,012
    Thomas J. Gritzan
    Jan 15, 2010
  5. Replies:
    2
    Views:
    230
Loading...

Share This Page