How to display binary file contents if it is stored in an integer array?

Discussion in 'C Programming' started by loudking, May 1, 2007.

  1. loudking

    loudking Guest

    Dear all,

    I am writing a client-server application and the client should upload
    a file to the server, then the server should display the content of
    the file in stdout.

    Because I have to deal with binary files, I cannot use character
    strings, so I chose integer array instead.

    But the problem is that how can I display them in stdout? I tried "%c"
    and "%d", but neither will work.

    Client side:

    int fdin;
    int *up_file;
    struct stat buf;

    fdin = open(file, O_RDONLY);
    fstat(fdin, &buf);
    up_file = (int *)malloc(buf.st_size * sizeof(int));
    up_file = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fdin, 0)

    Server Side:

    for (int i = 0; i < iarray_len; i++)
    printf("%d", iarray_val);

    The uploading procedure will be handled by Sun RPC.

    Thanks!
     
    loudking, May 1, 2007
    #1
    1. Advertising

  2. loudking

    Chris Dollin Guest

    loudking wrote:

    > I am writing a client-server application and the client should upload
    > a file to the server, then the server should display the content of
    > the file in stdout.


    (The details of the client-server interaction are off-topic here.)

    > Because I have to deal with binary files, I cannot use character
    > strings, so I chose integer array instead.


    Why not a character array?

    > But the problem is that how can I display them in stdout? I tried "%c"
    > and "%d", but neither will work.


    Both will work (for some value of "work") /if you do them right/.

    What do you expect to display on stdout? The characters, the decimal
    representation of their values, or what?

    What actually happened?

    > Client side:
    >
    > int fdin;
    > int *up_file;
    > struct stat buf;
    >
    > fdin = open(file, O_RDONLY);
    > fstat(fdin, &buf);


    Non-standard magic; I can't speak to it.

    > up_file = (int *)malloc(buf.st_size * sizeof(int));


    You don't need, and should not use, that cast, if you're programming
    in C.

    Assuming that `fstat` puts the file size in `buf.st_size`, you
    should realise that you're probably allocating `sizeof(int)`
    times too much space.

    You should check that `malloc` hasn't returned null.

    > up_file = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fdin, 0)


    More unspeakable magic. It doesn't seem to have anything to do
    with `up_file`. Is that deliberate?

    > Server Side:


    > for (int i = 0; i < iarray_len; i++)
    > printf("%d", iarray_val);


    Presumably some more magic has copied the file mentioned above
    into `iarray_val`, whose type you have not told us.

    If -- I say "if" because there is so much magic buzzing around
    my ears are dizzy -- `iarray_val` (a name from hell, surely) has
    the bytes of the file you mention, you're going to be printing
    out (the decimal representation of) `sizeof(int)` bytes at a
    time. So you'll see numbers like 12386359126 rather than 42
    and 96.

    > The uploading procedure will be handled by Sun RPC.


    Not just magic -- sorcery!

    --
    Yes, Virginia, there is a second Jena user conference: Palo Alto, Sep 2007.

    Hewlett-Packard Limited registered office: Cain Road, Bracknell,
    registered no: 690597 England Berks RG12 1HN
     
    Chris Dollin, May 1, 2007
    #2
    1. Advertising

  3. loudking

    loudking Guest

    Well, what I actually mean is that the client is going to upload a
    file to the server and the server will store the file content in the
    memory. Later, the client will fetch the file from the server and
    display it in stdout.

    So the test script will be

    ../client add server test.pdf
    ../client fetch server > test_2.pdf
    diff test.pdf test_2.pdf

    So in my case, neither printf("%c") nor printf("%d") will work ...

    int i;
    for (i=0; i < integer_array_len; i++)
    printf("%c", integer_array_val);

    On 5ÔÂ1ÈÕ, ÏÂÎç3ʱ34·Ö, loudking <> wrote:
    > Dear all,
    >
    > I am writing a client-server application and the client should upload
    > a file to the server, then the server should display the content of
    > the file in stdout.
    >
    > Because I have to deal with binary files, I cannot use character
    > strings, so I chose integer array instead.
    >
    > But the problem is that how can I display them in stdout? I tried "%c"
    > and "%d", but neither will work.
    >
    > Client side:
    >
    > int fdin;
    > int *up_file;
    > struct stat buf;
    >
    > fdin = open(file, O_RDONLY);
    > fstat(fdin, &buf);
    > up_file = (int *)malloc(buf.st_size * sizeof(int));
    > up_file = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fdin, 0)
    >
    > Server Side:
    >
    > for (int i = 0; i < iarray_len; i++)
    > printf("%d", iarray_val);
    >
    > The uploading procedure will be handled by Sun RPC.
    >
    > Thanks!
     
    loudking, May 1, 2007
    #3
  4. On 1 May, 14:34, loudking <> wrote:

    this may be off-topic to comp.lang.c. comp.programming may be better.

    > I am writing a client-server application and the client should upload
    > a file to the server, then the server should display the content of
    > the file in stdout.
    >
    > Because I have to deal with binary files, I cannot use character
    > strings, so I chose integer array instead.


    so on the server you load the data into an int[]. Consider using
    unsigned char[].


    > But the problem is that how can I display them in stdout? I tried "%c"
    > and "%d", but neither will work.


    what does "will work" mean? Did it display anything? Or just not what
    you
    expected.

    >
    > Client side:
    >
    > int fdin;
    > int *up_file;
    > struct stat buf;
    >
    > fdin = open(file, O_RDONLY);
    > fstat(fdin, &buf);
    > up_file = (int *)malloc(buf.st_size * sizeof(int));
    > up_file = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fdin, 0)


    lots of not standard C stuff there.


    > Server Side:
    >
    > for (int i = 0; i < iarray_len; i++)
    > printf("%d", iarray_val);
    >
    > The uploading procedure will be handled by Sun RPC.


    would %x (hex) in the printf() solve your problem?


    --
    Nick Keighley
     
    Nick Keighley, May 1, 2007
    #4
  5. loudking

    loudking Guest

    I finally realize that I should use write(STDOUT_FILENO) instead of
    printf !!

    Thank you for your messages!
     
    loudking, May 1, 2007
    #5
  6. In article <>,
    loudking <> wrote:

    >I finally realize that I should use write(STDOUT_FILENO) instead of
    >printf !!


    It seems unlikely that this is really the solution. Apart from
    buffering and the text/binary distinction, there is little difference
    between using C's fwrite() and Unix's write(). Buffering can be
    defeated with fflush(), and on a Unix system there's no difference
    between text and binary mode.

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, May 1, 2007
    #6
  7. loudking

    Chris Dollin Guest

    loudking wrote:

    > Well, what I actually mean is that the client is going to upload a
    > file to the server and the server will store the file content in the
    > memory. Later, the client will fetch the file from the server and
    > display it in stdout.
    >
    > So the test script will be
    >
    > ./client add server test.pdf
    > ./client fetch server > test_2.pdf
    > diff test.pdf test_2.pdf
    >
    > So in my case, neither printf("%c") nor printf("%d") will work ...


    You keep saying that, but you don't say why you think it's true.

    > int i;
    > for (i=0; i < integer_array_len; i++)
    > printf("%c", integer_array_val);


    Did you read Chris-Dollin-at-HP's reply? Because he points out that
    if you write the wrong thing out, you'll get the wrong answer.

    Try a simple test case first, for heavens sake. Make sure you can
    write out zero bytes, one byte, two, three, four; five bytes, six
    bytes, seven bytes, eight. At the moment your problem is nothing to
    do with client-server communication: it's about rendering data to
    the output.

    Try some data like:

    unsigned char someData[] =
    { 1, 2, 0, 17, 127, 128, 254, 255, 31, 32 };

    and write it out with loops like:

    for (i = 0; i < sizeof (someData); i += 1)
    writeOutMyData( &someData[0], &someData );

    --
    Signed And Sealed Hedgehog
    Meaning precedes definition.
     
    Chris Dollin, May 1, 2007
    #7
  8. Re: How to display binary file contents if it is stored in an integerarray?

    loudking wrote:
    > Dear all,
    >
    > I am writing a client-server application and the client should upload
    > a file to the server, then the server should display the content of
    > the file in stdout.
    >
    > Because I have to deal with binary files, I cannot use character
    > strings, so I chose integer array instead.


    char is an integer type. You are guaranteed that you can store any
    integral value in the range 0...255 in an unsigned char, and -127...127
    in a signed char. Plain char could be either. There is nothing about a
    stream being 'binary' that keeps you from using char arrays.


    > But the problem is that how can I display them in stdout? I tried "%c"
    > and "%d", but neither will work.


    You display them as they are meant to be interpreted. "Neither will
    work" is a useless description of your problem.

    >
    > Client side:
    >
    > int fdin;
    > int *up_file;
    > struct stat buf;


    "struct stat" is, of course, not provided by any standard C header or
    library.

    > fdin = open(file, O_RDONLY);


    "open" is, of course, not provided by any standard C header or library.
    Nor is "O_RDONLY". The standard function is fopen, when the type of
    fdin would be "FILE *", not "int". The standard attempt to open fdin
    for binary input would be
    #include <stdio.h>
    {
    FILE *fdin;
    fdin = fopen(file, "rb");
    /* error checking here */
    }
    Note the "b" for binary. Perhaps your non-standard "O_RDONLY" needs an
    additional flag for binary input.


    > fstat(fdin, &buf);
    > up_file = (int *)malloc(buf.st_size * sizeof(int));


    Had you followed this newsgroup at all before posting, expected behavior
    in all newsgroups, you would know that casting the return value is
    unneeded and poor programming practice.
    #include <stdlib.h>
    {
    T* up_file; /* char T is the type of the desired array */
    up_file = malloc(buf.st_size * sizeof *up_file);
    /* error checking here */
    }

    > up_file = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fdin, 0)


    "mmap" is, of course, not provided by any standard C header or library.
    Nor are "PROT_READ" or "MAP_SHARED".


    > Server Side:
    >
    > for (int i = 0; i < iarray_len; i++)
    > printf("%d", iarray_val);


    What doesn't work (other than the declaration of 'int' here if your
    compiler is a C89 one)? You store values in an int array, you fprintf
    the contents of that int array as ints. If that doesn't "work" your
    implementation is hopelessly broken.

    I suspect that the reality is that you really haven't thought through
    your problem enough to know what correct behavior might be.


    > The uploading procedure will be handled by Sun RPC.


    Who cares?
     
    Martin Ambuhl, May 1, 2007
    #8
  9. Re: How to display binary file contents if it is stored in an integerarray?

    loudking wrote:
    > I finally realize that I should use write(STDOUT_FILENO) instead of
    > printf !!


    If "write(STDOUT_FILENO)" is right, then you are in the wrong newsgroup.
    That is not standard C and is an implementation-provided invasion of
    the program's namespace.
     
    Martin Ambuhl, May 1, 2007
    #9
  10. loudking <> writes:
    [...]
    > for (int i = 0; i < iarray_len; i++)
    > printf("%d", iarray_val);

    [...]

    Successive printfs will print successive values from your array with
    no blanks between them. For example, if the values in your array are

    123, 234, -987654321, 0

    then your output will be:

    123234-9876543210

    The output will be identical if your first two numbers are any of:

    1, 23234
    12, 3234
    1232, 34
    12323, 4

    Perhaps that's what you meant when you told us that it doesn't work.
    Tell us *how* it doesn't work would have been extremely helpful.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 1, 2007
    #10
    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. kwaj
    Replies:
    2
    Views:
    489
  2. Kamarulnizam Rahim
    Replies:
    4
    Views:
    251
    Robert Klemme
    Jan 28, 2011
  3. Mriganka
    Replies:
    1
    Views:
    129
    kaeli
    May 21, 2004
  4. Angus
    Replies:
    1
    Views:
    125
    Angus
    Apr 17, 2007
  5. Replies:
    0
    Views:
    221
Loading...

Share This Page