0

I am converting (from javascript) a program that will take a string of variable length (but always under 100 char) and return the data contained in the string in individual variables. This is the first portion of my code, and obviously, I am new to C and programming in general. This code is for the first section of the code, but learning how to properly code this would give me the know how to code the rest.

I need:

  • the first 4 digits to be stored as 'stringID'
  • the 5th digit to be stored as 'myindicator'
  • the 6th through (indicator + 6) digits to be stored as 'var1'

Example input:

'12345678901234567890123'

Example output:

  • stringID = 1234
  • myindicator = 5
  • var1 = 67890123456

When I run the program, it returns 'String ID: H>a' and then the program crashes. Any help would be appreciated. No, this is not homework.

int main()

{
char mystring[100];
char *stringID;
int nep;
int *myindicator;
char *var1;


nep = 0;
printf("Please enter your CODE\n");
scanf("%s", &mystring);

stringID = (char *)malloc(4 * sizeof(char));

if(NULL != stringID)
{

    strncpy(stringID, mystring, 4);
    stringID[4] = '\0';
    free(stringID);
    nep = nep +4;
    printf("stringID: %s\n",myindicator);
}


if(NULL != myindicator)
{
    strncpy(myindicator, (mystring+nep, 1);
    nep++; 
    myindicator = *myindicator - '0';
    printf("Indicator : %d\n",myindicator);
}

var1 = (char *)malloc((nep + 6) * sizeof(char));
if(NULL != var1)
{
    strncpy(var1, mystring+nep, (myindicator+nep+6));
    var1[myindicator+nep+6] = '\0';
    free(var1);

    printf("Var 1: %s", var1);

    nep = nep +myindicator+6;
}

getchar();
return 0;
}
user1486548
  • 1,201
  • 4
  • 15
  • 22
  • You're probably going to need to expand on `fails to work properly` to get a good reply. E.g. do you get compile errors? Link errors? Does it do something you didn't expect? Does it print the Gettysburg Address on your toilet paper when you're not looking? – JoeFish Jul 10 '12 at 20:31
  • Suggestion would be to break each part, you have three, into separate functions and make sure each one works exactly how you want them to work separately then work on getting them to work together. – sean Jul 10 '12 at 20:31
  • "My code fails to work properly." Please do some more research and use your debugger to describe how the code is failing, and simplify it down to the simplest possible thing that should work but doesn't. You must also include an example input and expected output if you want people to understand you. – David Grayson Jul 10 '12 at 20:32

2 Answers2

1

I fixed something, find it in the comments. But you need to check a C language manual...!

int main()
{
   char mystring[100];
   char *stringID;
   int nep;
   // Changed to integer, not pointer to int.
   int myindicator;
   char *var1;

   nep = 0;
   printf("Please enter your CODE\n");

   /*
       This scanf is a bad idea for the same reason for which, below, we take
       care to allocate memory enough for whatever we have to do.
       Should someone input 250 characters in a buffer of size 100, those 150
       extra characters would wreak havoc and possibly endanger the system.
   */
   // scanf("%s", &mystring);
   fgets(mystring, sizeof(mystring)-1, stdin);
   // fgets will read at most "sizeof(mystring)-1", that is, 99 bytes,
   // from "stdin" (STanDard INput), the same as scanf. But it will halt
   // when reaching the limit given. It's up to us to give a "real" limit
   // (nothing stops you from saying 15000 -- even if the true value is 100).

   // C strings are made of characters, terminated by a zero byte.
   // So you need 5 here, to store 4 characters
   stringID = (char *)malloc(5 * sizeof(char));

   if (NULL == stringID)
   {
       // Serious out of memory error: no sense going on.
       // fprintf(stderr, "Out of memory\n");
       abort();
   }

   strncpy(stringID, mystring, 4);
   stringID[4] = '\0';

   printf("ID: %s\n", stringID);

   free(stringID);

   nep = nep + 4;
   printf("NEP: %d\n", nep);

   // Now we want to decode the fifth digit.

   // I use '0' as character. So if the fifth digit is '0', '0'-'0' will give 0
   // and if it is '9', '9'-'0' will give 9 (the number).
   // The trick does not work with more than one digit, of course.
   myindicator = mystring[nep] - '0';

   // Had I wanted to read 3 digits, I would have had to copy them into a 
   // temporary buffer, add a zero in the fourth position, then run atol()
   // on the resulting buffer: atol("12345\0" /* A STRING */) = 12345 /* A NUMBER */;

   printf("VLI : %d\n", myindicator);

   // Copy "myindicator" bytes, so alloc myindicator+1 chars
   var1 = (char *)malloc((myindicator + 1) * sizeof(char));

   // Check that var1 is not null and abort if it is
   if (NULL == var1)
        abort();

   strncpy(var1, mystring + 6, myindicator);
   var1[myindicator+1] = '\0';

   // Moved this printf before the free. See why below.
   printf("Prefix : %s\n", var1);

   // NEVER use a variable after you freed it!!!
   // it might APPEAR to work, but will stab you in the back the first chance it gets.
   // Good if paranoid habit: null a var as soon as you've freed it.
   free(var1); var1 = NULL;

   getchar(); 
   return 0;
}
LSerni
  • 55,617
  • 10
  • 65
  • 107
  • 1
    I guess he will be running your code verbatim. please change calls to `scanf()` to a buffered IO. his 'mystring` array will be overflowing in the first chance a kid touches the terminal. – Aftnix Jul 10 '12 at 20:44
  • The formatting has a small mistake. You need to add a space in front of the `int main` and its opening brace `{`. – sfstewman Jul 10 '12 at 20:59
0

why are you freeing your array's ? you are referencing them after you have freed them from heap.

Your code will segfault in these places :

  1. where did you allocated myindicator?

    strncpy(myindicator, (mystring+nep, 1); // it will segfault here.

  2. free(var1);

    printf("Prefix : %s", var1); // again segfault

  3. Again here

    strncpy(var1, mystring+nep, (myindicator+nep+6)) //where is your mystring?

  4. taking string input by scanf() is horrible horrible idea. use buffered IO like fgets().

  5. You are exposing your mystring to buffer overflow. who is preventing the user from inputting a 120 byte string? i can write your stack with careful jump instruction to my malicious code.

Aftnix
  • 4,461
  • 6
  • 26
  • 43