-2

Am I doing something wrong ? I'm trying to compare test and msg with strcmp. They are exactly the same but strcmp returns a negative value.

I'm trying to code a stenography chat.

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


void encode(char* msg, const char * argv[], int argc)  {

   // exit(0);


    const int bmp_header_size = 54;
    int read_code;
    int msg_idx = 0;
    int img_idx = 0;
    int bit_idx = 0;
    char c;
    FILE *img_in = NULL;
    FILE *img_out = NULL;

    if( argc < 3 ){
        printf( "Usage: %s source_bmp output_bmp message.\n", argv[0] );
        exit(1);
    }

    img_in = fopen( argv[1], "rb" );
    if( img_in == NULL ){
        printf( "Could not open the input image file.\n" );
        exit(1);
    }

    img_out = fopen( argv[2], "wb" );
    if( img_out == NULL ){
        printf( "Could not open the output file.\n" );
        exit(1);
    }



    while( ( read_code = fgetc( img_in )) != EOF ){
        c = (char)read_code;

        if( img_idx >= bmp_header_size && msg_idx <= strlen( msg ) ){
            char bit_mask = 1 << bit_idx;

            if( ( msg[msg_idx] & bit_mask) > 0 )
                c |= 1;
            else
                c &= 254;

            bit_idx++;

            if( bit_idx >= 8 ){
                bit_idx = 0;
                msg_idx++;
            }           
        }

        fputc( c, img_out );
        img_idx++;
    }


    fclose(img_in);
    fclose(img_out);

}

char* decode(const char * argv[], int argc) {

    const int bmp_header_size = 54;
    const int max_msg_size = 1000;

    int i;
    int c;
    int img_idx = 0;
    int msg_idx = 0;
    int bit_idx = 0;

    char msg[max_msg_size];
    FILE *img_in = NULL;

    img_in = fopen( argv[2], "rb" );

    if( img_in == NULL ){
        printf( "Could not open the input image file.\n" );
        exit(1);
    }

    for( i=0; i < max_msg_size; i++ )
        msg[i] = 0;

    while( ( c = fgetc( img_in )) != EOF ){
        if( img_idx >= bmp_header_size ){
            char bit_mask = 0;
            if( ( c & 1 )  > 0 )
                bit_mask |= 1 << bit_idx;

            msg[msg_idx] |= bit_mask;

            bit_idx++;

            if( bit_idx >= 8 ){
                if( msg[msg_idx] == '\0' )
                    break;
                bit_idx = 0;
                msg_idx++;
            }           
        }

        img_idx++;
    }

    fclose(img_in);

    char* output = msg;

  //  printf("%s\n",output);

    return output;
}




int main(int argc, const char * argv[]) {

    char message[1000];


  /*  printf("\n Send : ");

    fgets(message, 1000, stdin);
    message[strlen(message) -1] = '\0';


    encode(message, argv, argc);
    decode(argv, argc); */


   while (1) {

       printf("\n Send : ");

        fgets(message, 1000, stdin);


        encode(message, argv, argc);

       char *test;
       char *msg;

       msg = message;
       test = decode(argv, argc);


       long sizem = strlen(msg);
       long sizet = strlen(test);

       printf("size of message : \t %ld\n", sizem);
       printf("size of test : \t %ld\n", sizet);
       printf("Test = \t %s\n", test);
       printf("Message = \t %s\n", msg);


       long debug = strcmp(test, msg);
       printf("strcmp = \t%ld\n", debug);


      /* sizem = strlen(message);
       sizet = strlen(test);

       printf("%ld\n", sizem);
       printf("%ld\n", sizet);
       printf("%s\n", test);
       printf("%s\n", message); */

       // printf("%ld", debeug);

        exit(1);

        while (strcmp(test, message) == 1) {

        }


    }



    return 0;
}

Debug 1 Debug 2

Output :

Send : test
size of message :    5
size of test :   5
Test =   test

Message =    test

strcmp =    -116
Program ended with exit code: 1

Thank you for your help !

John Graig
  • 83
  • 1
  • 6
  • 1
    Please post code here in text, not screenshots! – dbush Oct 16 '15 at 02:30
  • 1
    There should be enough code as well as sample input/output for someone to be able replicate your problem, i.e. a [Minimal, Complete, Verifiable Example](http://stackoverflow.com/help/mcve) – dbush Oct 16 '15 at 02:33
  • Sorry about that, i'll edit. – John Graig Oct 16 '15 at 02:35
  • 3
    `decode` is returning a local variable which goes out of scope when the funciton exits. That is undefined behaviour. – kaylum Oct 16 '15 at 02:37
  • 1
    @kaylum: More precisely, it's returning *a pointer* to an object with automatic storage duration. – EOF Oct 16 '15 at 02:39
  • @EOF Yep, that's what I meant - but you said it better :-) – kaylum Oct 16 '15 at 02:40
  • @EOF Thanks guys :)! How I should fix that, I tatted with Java and I'm trying to learn C, it's a pain in the ass! – John Graig Oct 16 '15 at 02:45
  • @EricSchaal: You can `malloc()` an appropriately-sized buffer to return. Note that you will need to `free()` the allocation when you no longer need it, since c has no automatic garbage collection. – EOF Oct 16 '15 at 02:48
  • @EOF thank ! I tried `char *output; output = malloc(sizeof(msg)); output = msg; // printf("%s\n",output); return output; }` Doesn't work, I don't understand what is wrong... – John Graig Oct 16 '15 at 03:07
  • 1
    @EricSchaal: That doesn't fix anything. It just leaks your allocation. *Instead*, you could do `char *output = strdup(msg); return output;`. – EOF Oct 16 '15 at 03:09

1 Answers1

1

The decode function is returning a pointer to an array which is local to the decode function.

Local variables are destroyed when a function returns, so this is a dangling pointer. Using it in main causes undefined behaviour. What you are seeing could be explained by the memory where that array was being used for some other purpose by the strcmp function, or any other reason.

To make your code work you will have to think a bit more carefully about where you allocate memory for the decoded string to be stored.

M.M
  • 138,810
  • 21
  • 208
  • 365