Newbie seeking VB to ANSI C Conversion assistance

Discussion in 'C Programming' started by Jeff Goslin, Nov 5, 2003.

  1. Jeff Goslin

    Jeff Goslin Guest

    Hello everyone,

    I'm an MCSD(on the VB track) who has to convert a relatively simple program
    from VB into ANSI compliant C. The problem is that it's giving me memory
    access violation errors when I run the program. The program compiles just
    fine, but when I try to run it, I get the error. I can only assume that
    this problem is associated with my admittedly limited understanding of
    string manipulation and pointer usage in C. Any suggestions at all are
    greatly appreciated.

    The program is a fairly simple registration code generator. Given a user's
    name, it spits out a registration code specific to that user. It's meant to
    be as generic as possible so I can use it in different programs with
    different seeds and decoding strings.

    The code template I was told to follow is this:

    #include <string.h>

    int main(int argc, void *argv[])
    {
    // First parameter is user's full name
    char userName[255];
    char regCode[255];

    strncpy(userName, argv[1], 255);

    // Code or function calls to
    // place registration code into
    // regCode variable

    printf("%s\n",regCode);
    return 0;
    };


    I had to make a few modifications to get it to compile(which leads me to
    believe that something is wrong with my code), so... anyone??? Help???

    The following code COMPILES, but does not RUN. Examples of what is trying
    to be accomplished has been included for ease of following the code. If the
    input from the command line is my name, "Jeff Goslin", the output, given the
    following code, should be "131HFASRR4"

    // RegKeyC.cpp : Defines the entry point for the application.
    //

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

    int main(int argc, void *argv[])
    {
    // First parameter is user's full name
    // EX: "Jeff Goslin"
    char *userName;
    char *regCode;

    char *seed;
    char *decoder;

    char *tmpRevPre;
    char *tmpFwdPre;
    char *tmpFinal;
    char *preencode;
    int curpos=1;
    int totalasc;

    // snag the user name from the passed in arguments
    strcpy(userName, (char *)argv[1]);

    // initialize the seed string, for use in the encoding
    strcpy(seed, "SEEDSTRING\0");

    // initialize the decoder string, for use in the encoding
    strcpy(decoder, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\0");

    // Code or function calls to
    // place registration code into
    // regCode variable

    // reverse the preencode string into a temp variable
    // hack it off to the length of the seed
    // the provided username("Jeff Goslin") is reversed("nilsoG ffeJ"),
    // the seed("SEEDSTRING") is concatenated, and the whole
    // thing is placed in preencode("nilsoG ffeJSEEDSTRING")
    strcpy(preencode,strcat(strrev(userName),seed));

    // the preencode variable is hacked off at 10 characters("nilsoG ffe")
    strncpy(tmpFwdPre, preencode, strlen(seed));

    // the preencode variable is reversed, and hacked off at 10
    characters("GNIRTSDEES")
    strncpy(tmpRevPre, strrev(preencode), strlen(seed));

    // encode the stuff
    while (curpos <= strlen(seed))
    {

    // take the ascii codes of the characters at the specified position
    and add them together
    // in position 1, the codes for G and n will be added
    together(71+110=181)
    totalasc = tmpRevPre[curpos] + tmpFwdPre[curpos];

    // find the remainder when we divide it by the length of the
    decoder(36)
    // 181 mod 36 = 1
    totalasc = (totalasc % strlen(decoder)) + 1;

    // append the character from the decoder string in the position
    calculated to the final string
    // the character in position 1 is a "1"(0 based array, of course)
    strcat(tmpFinal, (char *)decoder[totalasc]);

    // increment the position counter, and repeat until done
    curpos++;
    }

    // put the final string("131HFASRR4") into the right variable
    strcpy(regCode, tmpFinal);

    // output the right variable
    printf("%s\n",regCode);
    return 0;
    };

    --
    Jeff Goslin - MCSD - www.goslin.info
    Jeff Goslin, Nov 5, 2003
    #1
    1. Advertising

  2. On Wed, 05 Nov 2003 09:27:10 -0500, Jeff Goslin wrote:

    > Hello everyone,
    >
    > I'm an MCSD(on the VB track) who has to convert a relatively simple program
    > from VB into ANSI compliant C. The problem is that it's giving me memory
    > access violation errors when I run the program. The program compiles just
    > fine, but when I try to run it, I get the error. I can only assume that
    > this problem is associated with my admittedly limited understanding of
    > string manipulation and pointer usage in C. Any suggestions at all are
    > greatly appreciated.
    >
    > The program is a fairly simple registration code generator. Given a user's
    > name, it spits out a registration code specific to that user. It's meant to
    > be as generic as possible so I can use it in different programs with
    > different seeds and decoding strings.
    >
    > The code template I was told to follow is this:
    >
    > #include <string.h>
    >
    > int main(int argc, void *argv[])


    If this is true then whoever told you to use this template is
    incompetent to teach C. It should be

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

    > {
    > // First parameter is user's full name
    > char userName[255];
    > char regCode[255];


    After a glance at your code, my first comment is that you should
    go back to the template provided. It seems like the template provider
    is trying to save you from some of the problems you are having by
    specifying these arrays. You should be using them. By the way, I
    find the choice of 255 for the length of these array somewhat odd.
    Why not 256?

    > strncpy(userName, argv[1], 255);


    This function is called to copy the first argument (the user's
    name), into the array userName. However, it will cause problems
    for you if a really long name is typed in. Long names will also
    cause problems later in your program. It would be probably be
    smart to truncate long names by (for example) arbitrarily
    truncating them after some number of characters like this:

    userName[64] = '\0';

    64 is just picked out of the air as a number long enough for
    a name and yet a lot shorter than the length of the array - 255.
    Be sure you understand, the userName array is still 255 characters
    long. This line just makes sure that names longer than 64 characters
    are truncated at 64. Shorter names aren't affected in any way.

    > // Code or function calls to
    > // place registration code into
    > // regCode variable
    >
    > printf("%s\n",regCode);
    > return 0;
    > };
    >
    >
    > I had to make a few modifications to get it to compile(which leads me to
    > believe that something is wrong with my code), so... anyone??? Help???
    >
    > The following code COMPILES, but does not RUN.


    It doesn't compile on my computer. What compiler are you using?

    > Examples of what is
    > trying to be accomplished has been included for ease of following the
    > code. If the input from the command line is my name, "Jeff Goslin", the
    > output, given the following code, should be "131HFASRR4"
    >
    > // RegKeyC.cpp : Defines the entry point for the application. //


    Why does a C program have a .cpp extension? The following looks more
    like C than C++ (except for the comments).

    > #include <string.h>
    > #include <stdio.h>
    >
    > int main(int argc, void *argv[])


    once again,
    int main(int argc, char *argv[])


    > {
    > // First parameter is user's full name // EX: "Jeff Goslin"
    > char *userName;
    > char *regCode;
    >
    > char *seed;
    > char *decoder;
    >
    > char *tmpRevPre;
    > char *tmpFwdPre;
    > char *tmpFinal;
    > char *preencode;
    > int curpos=1;
    > int totalasc;
    >
    > // snag the user name from the passed in arguments
    > strcpy(userName,(char *)argv[1]);
    >
    > // initialize the seed string, for use in the encoding
    > strcpy(seed, "SEEDSTRING\0");


    The \0 at the end of this and other string literals in your
    code is unnecessary. String literals automatically have a
    zero byte at the end anyway.

    >
    > // initialize the decoder string, for use in the encoding
    > strcpy(decoder, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\0");


    You are copying these strings into nothingness. That is, the
    variables userName, seed, and decoder, are not strings. They
    are pointers and since there is no space allocated to store
    the strings you are trying to copy, this cannot work.

    I suggest you go back to the template for userName. For the
    other two, you could assign the strings to the pointers
    like this:

    seed = "SEEDSTRING";
    decoder = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ;"

    Let me try to quickly show you why this works and your code
    doesn't. After your original declarations, you have three
    pointers pointing at random places:

    +-----------+
    userName | ----|----> ?
    +-----------+
    +-----------+
    seed | ----|----> ?
    +-----------+
    +-----------+
    decoder | ----|----> ?
    +-----------+

    when you use strcpy you are trying to copy string literals to
    the memory pointed to by these pointers, but you haven't pointed
    the pointers at any valid memory, so it can't work. You could
    allocate some memory into which you could then strcpy, but that
    may be to advanced for you now. What I have suggested is to leave
    userName as an array, so it will look like this:

    +---+---+---+---+---+---+ +---+
    userName | | | | | | | ... | |
    +---+---+---+---+---+---+ +---+
    0 1 2 3 4 5 254

    You can see that there is space in which to copy the user's
    name. The suggestion about simply assigning the string literals
    instead of using strcpy will do this:

    +-----------+
    seed | ----|---+
    +-----------+ |
    +-------------------+
    V
    +---+---+---+---+---+---+---+---+---+---+---+
    | S | E | E | D | S | T | R | I | N | G | 0 |
    +---+---+---+---+---+---+---+---+---+---+---+

    The string literal "SEEDSTRING" is somewhere in memory already.
    The assignment

    seed = "SEEDSTRING";

    will make the pointer seed point at the first character in the
    string literal "SEEDSTRING"; This seems to be what you want.
    Notice that no copy is being made of the characters in this
    case, seed is just pointing to where the characters already were.

    After all of that, however, I will point out that you really
    don't need these variables. You can simply use the string literals
    themselves when you need them. For example:

    strcat(userName, "SEEDSTRING");

    > // Code or function calls to
    > // place registration code into
    > // regCode variable
    >
    > // reverse the preencode string into a temp variable
    > // hack it off to the length of the seed
    > // the provided username("Jeff Goslin") is reversed("nilsoG ffeJ"),
    > // the seed("SEEDSTRING") is concatenated, and the whole
    > // thing is placed in preencode("nilsoG ffeJSEEDSTRING")
    > strcpy(preencode,strcat(strrev(userName),seed));


    There is no function called strrev() in ANSI C. If your code has
    to be ANSI, then you'll have to figure out how to reverse the strings
    yourself.

    The copy "into" preencode can never work. preencode is just a pointer and
    there is no place to copy a string. It's the same situation as above. I
    don't see why you need a preencode variable at all anyway. Why not just do
    the work in the userName array?

    /* first reverse userName */
    ... do whatever you have to do to reverse it here ...

    /* Now copy in the seed */
    strcat(userName, seed);

    Also, there are lots of pitfalls in code like yours. For
    example, what happens if the length of the user name plus the
    length of seed exceeds the length of your userName array? In
    that case the function call

    strcat(userName, seed);

    will be a bug, and will probably crash your program. This is why I
    suggested truncating long names up at the top.

    > // the preencode variable is hacked off at 10 characters
    > // ("nilsoGffe")
    > strncpy(tmpFwdPre, preencode, strlen(seed));


    Not necessary. If you want to "hack off" the string contained
    in an array, just put a zero into the array at the "hack off"
    point:

    userName[10] = '\0';

    Once again, tmpFwdPre is a pointer and you can't copy a
    string into it.

    I'm going to leave off at this point. It is difficult to comment
    on the rest of your code without rewriting it completely since
    you are using variables that shouldn't be there.

    I suggest you go back to the template, don't declare any more
    variables, and try again. Then come back to this newsgroup and
    we can discuss your second attempt.

    -Sheldon
    Sheldon Simms, Nov 5, 2003
    #2
    1. Advertising

  3. Jeff Goslin

    Alan Balmer Guest

    On Wed, 5 Nov 2003 09:27:10 -0500, "Jeff Goslin" <>
    wrote:

    >Hello everyone,
    >
    >I'm an MCSD(on the VB track) who has to convert a relatively simple program
    >from VB into ANSI compliant C.


    The very first thing I see is that you are moving data into char *
    variables, which are pointers to nowhere, since you have allocated no
    memory for them.

    You were told to follow a template. Take another look at that
    template, and notice that your code doesn't look anything like it. In
    particular, note that the sample has

    char userName[255];
    char regCode[255];

    where your code has

    char *userName;
    char *regCode;

    I really don't know what the point of this exercise is, but I'm afraid
    you're going to have to get a book and learn at least a little about
    the C language before tackling this kind of assignment.

    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 5, 2003
    #3
  4. Jeff Goslin <> spoke thus:

    > #include <string.h>


    > int main(int argc, void *argv[])
    > {
    > // First parameter is user's full name
    > char userName[255];
    > char regCode[255];


    > strncpy(userName, argv[1], 255);


    What happens if strlen(argv[1]) is larger than 255? 255 characters will be
    written to userName, giving you an unterminated string. Even if the prototype
    for main were correct (it isn't) and if the code checked argc to make sure
    that argv[1] exists before attempting to use it (it doesn't), this fact makes
    this a dangerous example to follow.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
    Christopher Benson-Manica, Nov 5, 2003
    #4
  5. Jeff Goslin

    Jeff Goslin Guest

    "Alan Balmer" <> wrote in message
    news:...
    > You were told to follow a template. Take another look at that


    The template was, to say the least, "barren". There wasn't anything to it
    other than what you saw.

    > template, and notice that your code doesn't look anything like it. In
    > particular, note that the sample has
    >
    > char userName[255];
    > char regCode[255];
    >
    > where your code has
    >
    > char *userName;
    > char *regCode;


    It was literally the only way I could get the damn thing to compile. ;) It
    appears that there are some things that were left out. However, since that
    attempt, I have gone back and fixed certain things, and now we're back to
    predefined arrays.

    > I really don't know what the point of this exercise is, but I'm afraid
    > you're going to have to get a book and learn at least a little about
    > the C language before tackling this kind of assignment.


    Hence the request for assistance. I'm a fifteen year veteran of the VB
    language, ten years in the field, and it's been over a decade since I even
    had to look at C let alone code in it, and it's probably going to be another
    decade before I have to do it again. I truly appreciate the assistance you
    have offered. I thought I had remembered a fair amount of the language,
    syntax, requirements and nuances. Obviously I was mistaken.

    However, given the fact that I am probably not going to code in C again for
    quite some time, my only concern right now is to get this off my plate. As
    such, I have, with the assistance of yourself and others in this newsgroup,
    managed to piece together something that functions(more or less). It may
    not be the prettiest code in the world, but it should work.

    Again, thank you for your assistance in this matter. It has been much
    appreciated, and much needed!

    --
    Jeff Goslin - MCSD - www.goslin.info
    It's not a god complex when you're always right
    Jeff Goslin, Nov 5, 2003
    #5
  6. Jeff Goslin

    Jeff Goslin Guest

    "Christopher Benson-Manica" <> wrote in message
    news:bobdjt$fh5$...
    > What happens if strlen(argv[1]) is larger than 255? 255 characters will

    be
    > written to userName, giving you an unterminated string. Even if the

    prototype
    > for main were correct (it isn't) and if the code checked argc to make sure
    > that argv[1] exists before attempting to use it (it doesn't), this fact

    makes
    > this a dangerous example to follow.


    Yes, it has been pointed out to me that this code sample is a fairly inept
    sample set of code, but it was the sample template that was provided, so I
    thought I should stick to it as best as possible.

    While technically you are correct that a well written program should handle
    all idiot-user mistakes and all types of input, the practicality of the
    situation is far easier to deal with. We make the variables substantially
    larger than they will ever need to be(who has a 250 character name, after
    all?), and everything more or less takes care of itself. Instead of
    spending all sorts of time figuring out how users will work to break the
    code, it's going to be used so infrequently as to warrant handling
    exceptions on a case by case basis. Risk vs Reward analysis and all that.
    I could spend many hours making DAMN sure the thing never broke, OR I could
    spend a lot less time, and just make it so huge that it'll never be pressed
    like that. I realize that it's not the ideal way to do code, but time is
    money, and this code doesn't warrant any more time than the bare minimum to
    get it working.

    I can hear all you coding purists out there gasping for breath right now...
    on this job, it's just not worth it to totally idiot-proof the thing...
    Besides, I believe the argument being passed in is going to be truncated at
    250 characters or something, so we should be covered.

    --
    Jeff Goslin - MCSD - www.goslin.info
    It's not a god complex when you're always right
    Jeff Goslin, Nov 5, 2003
    #6
  7. Jeff Goslin

    Jeff Goslin Guest

    Thank you for this indepth and informative response. I have used this
    information to assist me in the creation of my code. It is now fully
    functional(except I have to rewrite the string reversal code, given that
    strrev is not ANSI compliant). Your assistance has been greatly
    appreciated.

    --
    Jeff Goslin - MCSD - www.goslin.info
    It's not a god complex when you're always right


    "Sheldon Simms" <> wrote in message
    news:p...
    > On Wed, 05 Nov 2003 09:27:10 -0500, Jeff Goslin wrote:
    >
    > > Hello everyone,
    > >
    > > I'm an MCSD(on the VB track) who has to convert a relatively simple

    program
    > > from VB into ANSI compliant C. The problem is that it's giving me

    memory
    > > access violation errors when I run the program. The program compiles

    just
    > > fine, but when I try to run it, I get the error. I can only assume that
    > > this problem is associated with my admittedly limited understanding of
    > > string manipulation and pointer usage in C. Any suggestions at all are
    > > greatly appreciated.
    > >
    > > The program is a fairly simple registration code generator. Given a

    user's
    > > name, it spits out a registration code specific to that user. It's

    meant to
    > > be as generic as possible so I can use it in different programs with
    > > different seeds and decoding strings.
    > >
    > > The code template I was told to follow is this:
    > >
    > > #include <string.h>
    > >
    > > int main(int argc, void *argv[])

    >
    > If this is true then whoever told you to use this template is
    > incompetent to teach C. It should be
    >
    > int main(int argc, char *argv[])
    >
    > > {
    > > // First parameter is user's full name
    > > char userName[255];
    > > char regCode[255];

    >
    > After a glance at your code, my first comment is that you should
    > go back to the template provided. It seems like the template provider
    > is trying to save you from some of the problems you are having by
    > specifying these arrays. You should be using them. By the way, I
    > find the choice of 255 for the length of these array somewhat odd.
    > Why not 256?
    >
    > > strncpy(userName, argv[1], 255);

    >
    > This function is called to copy the first argument (the user's
    > name), into the array userName. However, it will cause problems
    > for you if a really long name is typed in. Long names will also
    > cause problems later in your program. It would be probably be
    > smart to truncate long names by (for example) arbitrarily
    > truncating them after some number of characters like this:
    >
    > userName[64] = '\0';
    >
    > 64 is just picked out of the air as a number long enough for
    > a name and yet a lot shorter than the length of the array - 255.
    > Be sure you understand, the userName array is still 255 characters
    > long. This line just makes sure that names longer than 64 characters
    > are truncated at 64. Shorter names aren't affected in any way.
    >
    > > // Code or function calls to
    > > // place registration code into
    > > // regCode variable
    > >
    > > printf("%s\n",regCode);
    > > return 0;
    > > };
    > >
    > >
    > > I had to make a few modifications to get it to compile(which leads me to
    > > believe that something is wrong with my code), so... anyone??? Help???
    > >
    > > The following code COMPILES, but does not RUN.

    >
    > It doesn't compile on my computer. What compiler are you using?
    >
    > > Examples of what is
    > > trying to be accomplished has been included for ease of following the
    > > code. If the input from the command line is my name, "Jeff Goslin", the
    > > output, given the following code, should be "131HFASRR4"
    > >
    > > // RegKeyC.cpp : Defines the entry point for the application. //

    >
    > Why does a C program have a .cpp extension? The following looks more
    > like C than C++ (except for the comments).
    >
    > > #include <string.h>
    > > #include <stdio.h>
    > >
    > > int main(int argc, void *argv[])

    >
    > once again,
    > int main(int argc, char *argv[])
    >
    >
    > > {
    > > // First parameter is user's full name // EX: "Jeff Goslin"
    > > char *userName;
    > > char *regCode;
    > >
    > > char *seed;
    > > char *decoder;
    > >
    > > char *tmpRevPre;
    > > char *tmpFwdPre;
    > > char *tmpFinal;
    > > char *preencode;
    > > int curpos=1;
    > > int totalasc;
    > >
    > > // snag the user name from the passed in arguments
    > > strcpy(userName,(char *)argv[1]);
    > >
    > > // initialize the seed string, for use in the encoding
    > > strcpy(seed, "SEEDSTRING\0");

    >
    > The \0 at the end of this and other string literals in your
    > code is unnecessary. String literals automatically have a
    > zero byte at the end anyway.
    >
    > >
    > > // initialize the decoder string, for use in the encoding
    > > strcpy(decoder, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\0");

    >
    > You are copying these strings into nothingness. That is, the
    > variables userName, seed, and decoder, are not strings. They
    > are pointers and since there is no space allocated to store
    > the strings you are trying to copy, this cannot work.
    >
    > I suggest you go back to the template for userName. For the
    > other two, you could assign the strings to the pointers
    > like this:
    >
    > seed = "SEEDSTRING";
    > decoder = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ;"
    >
    > Let me try to quickly show you why this works and your code
    > doesn't. After your original declarations, you have three
    > pointers pointing at random places:
    >
    > +-----------+
    > userName | ----|----> ?
    > +-----------+
    > +-----------+
    > seed | ----|----> ?
    > +-----------+
    > +-----------+
    > decoder | ----|----> ?
    > +-----------+
    >
    > when you use strcpy you are trying to copy string literals to
    > the memory pointed to by these pointers, but you haven't pointed
    > the pointers at any valid memory, so it can't work. You could
    > allocate some memory into which you could then strcpy, but that
    > may be to advanced for you now. What I have suggested is to leave
    > userName as an array, so it will look like this:
    >
    > +---+---+---+---+---+---+ +---+
    > userName | | | | | | | ... | |
    > +---+---+---+---+---+---+ +---+
    > 0 1 2 3 4 5 254
    >
    > You can see that there is space in which to copy the user's
    > name. The suggestion about simply assigning the string literals
    > instead of using strcpy will do this:
    >
    > +-----------+
    > seed | ----|---+
    > +-----------+ |
    > +-------------------+
    > V
    > +---+---+---+---+---+---+---+---+---+---+---+
    > | S | E | E | D | S | T | R | I | N | G | 0 |
    > +---+---+---+---+---+---+---+---+---+---+---+
    >
    > The string literal "SEEDSTRING" is somewhere in memory already.
    > The assignment
    >
    > seed = "SEEDSTRING";
    >
    > will make the pointer seed point at the first character in the
    > string literal "SEEDSTRING"; This seems to be what you want.
    > Notice that no copy is being made of the characters in this
    > case, seed is just pointing to where the characters already were.
    >
    > After all of that, however, I will point out that you really
    > don't need these variables. You can simply use the string literals
    > themselves when you need them. For example:
    >
    > strcat(userName, "SEEDSTRING");
    >
    > > // Code or function calls to
    > > // place registration code into
    > > // regCode variable
    > >
    > > // reverse the preencode string into a temp variable
    > > // hack it off to the length of the seed
    > > // the provided username("Jeff Goslin") is reversed("nilsoG ffeJ"),
    > > // the seed("SEEDSTRING") is concatenated, and the whole
    > > // thing is placed in preencode("nilsoG ffeJSEEDSTRING")
    > > strcpy(preencode,strcat(strrev(userName),seed));

    >
    > There is no function called strrev() in ANSI C. If your code has
    > to be ANSI, then you'll have to figure out how to reverse the strings
    > yourself.
    >
    > The copy "into" preencode can never work. preencode is just a pointer and
    > there is no place to copy a string. It's the same situation as above. I
    > don't see why you need a preencode variable at all anyway. Why not just do
    > the work in the userName array?
    >
    > /* first reverse userName */
    > ... do whatever you have to do to reverse it here ...
    >
    > /* Now copy in the seed */
    > strcat(userName, seed);
    >
    > Also, there are lots of pitfalls in code like yours. For
    > example, what happens if the length of the user name plus the
    > length of seed exceeds the length of your userName array? In
    > that case the function call
    >
    > strcat(userName, seed);
    >
    > will be a bug, and will probably crash your program. This is why I
    > suggested truncating long names up at the top.
    >
    > > // the preencode variable is hacked off at 10 characters
    > > // ("nilsoGffe")
    > > strncpy(tmpFwdPre, preencode, strlen(seed));

    >
    > Not necessary. If you want to "hack off" the string contained
    > in an array, just put a zero into the array at the "hack off"
    > point:
    >
    > userName[10] = '\0';
    >
    > Once again, tmpFwdPre is a pointer and you can't copy a
    > string into it.
    >
    > I'm going to leave off at this point. It is difficult to comment
    > on the rest of your code without rewriting it completely since
    > you are using variables that shouldn't be there.
    >
    > I suggest you go back to the template, don't declare any more
    > variables, and try again. Then come back to this newsgroup and
    > we can discuss your second attempt.
    >
    > -Sheldon
    >
    Jeff Goslin, Nov 5, 2003
    #7
  8. Jeff Goslin

    Alan Balmer Guest

    On Wed, 5 Nov 2003 16:19:41 -0500, "Jeff Goslin" <>
    wrote:

    >We make the variables substantially
    >larger than they will ever need to be(who has a 250 character name, after
    >all?),


    The hacker who's trying a buffer overrun attack?

    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 5, 2003
    #8
  9. [followups set]

    Alan Balmer wrote:

    > On Wed, 5 Nov 2003 16:19:41 -0500, "Jeff Goslin" <>
    > wrote:
    >
    >>We make the variables substantially
    >>larger than they will ever need to be(who has a 250 character name, after
    >>all?),

    >
    > The hacker who's trying a buffer overrun attack?


    This technique is now so well-known, and so malicious, that no hacker is
    ever likely to try it (except, perhaps, on his own system at home, just the
    once, to see how it works).

    It is much more likely to be tried by a cracker or a script-kiddie.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
    Richard Heathfield, Nov 6, 2003
    #9
  10. Jeff Goslin

    Alan Balmer Guest

    On Thu, 6 Nov 2003 06:40:40 +0000 (UTC), Richard Heathfield
    <> wrote:

    >[followups set]
    >
    >Alan Balmer wrote:
    >
    >> On Wed, 5 Nov 2003 16:19:41 -0500, "Jeff Goslin" <>
    >> wrote:
    >>
    >>>We make the variables substantially
    >>>larger than they will ever need to be(who has a 250 character name, after
    >>>all?),

    >>
    >> The hacker who's trying a buffer overrun attack?

    >
    >This technique is now so well-known, and so malicious, that no hacker is
    >ever likely to try it (except, perhaps, on his own system at home, just the
    >once, to see how it works).
    >
    >It is much more likely to be tried by a cracker or a script-kiddie.


    Apologies - I've fallen into the common misuse of the word "hacker." I
    deserve to be severely whipped with a paper tape.

    Anyone have a teletype handy?

    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 6, 2003
    #10
  11. On Thu, 6 Nov 2003 06:40:40 +0000 (UTC), in comp.lang.c , Richard
    Heathfield <> wrote:

    >[followups set]
    >
    >Alan Balmer wrote:
    >
    >> On Wed, 5 Nov 2003 16:19:41 -0500, "Jeff Goslin" <>
    >> wrote:
    >>
    >>>We make the variables substantially
    >>>larger than they will ever need to be(who has a 250 character name, after
    >>>all?),


    The heir assumptive to the throne of the Great Britain for one. And I
    recently worked with a chap from Sri Lanka whose first and last names
    were both over 32 chars long. Which gave him a nasty problem logging
    into Windows NT by the way.

    >It is much more likely to be tried by a cracker or a script-kiddie.


    whats sad is that it still seems to work....

    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>


    ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
    ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
    Mark McIntyre, Nov 7, 2003
    #11
  12. Jeff Goslin

    Alan Balmer Guest

    On Fri, 07 Nov 2003 00:22:00 +0000, Mark McIntyre
    <> wrote:

    >On Thu, 6 Nov 2003 06:40:40 +0000 (UTC), in comp.lang.c , Richard
    >Heathfield <> wrote:
    >
    >>[followups set]
    >>
    >>Alan Balmer wrote:
    >>
    >>> On Wed, 5 Nov 2003 16:19:41 -0500, "Jeff Goslin" <>
    >>> wrote:
    >>>
    >>>>We make the variables substantially
    >>>>larger than they will ever need to be(who has a 250 character name, after
    >>>>all?),

    >
    >The heir assumptive to the throne of the Great Britain for one. And I
    >recently worked with a chap from Sri Lanka whose first and last names
    >were both over 32 chars long. Which gave him a nasty problem logging
    >into Windows NT by the way.
    >
    >>It is much more likely to be tried by a cracker or a script-kiddie.

    >
    >whats sad is that it still seems to work....


    And will continue to work as long as we have the type of programming
    practices espoused by the OP.

    BTW, you missed a step in the attribution chain above - Nothing quoted
    was written by me.

    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 7, 2003
    #12
  13. On Fri, 07 Nov 2003 08:15:38 -0700, in comp.lang.c , Alan Balmer
    <> wrote:

    >
    >BTW, you missed a step in the attribution chain above - Nothing quoted
    >was written by me.


    oops, sorry, clumsy scissors.


    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>


    ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
    ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
    Mark McIntyre, Nov 8, 2003
    #13
  14. On Wed, 5 Nov 2003 16:19:41 -0500, "Jeff Goslin" <>
    wrote:

    >> What happens if strlen(argv[1]) is larger than 255? 255 characters will

    >be

    The problem I forsee isn't with argv[1] being 255 characters. What I
    forsee is the fact that in his original message, he planned on passing
    eg. Jeff Goslin as the name, and argv[1] in that case will return
    Jeff..... You'll need to do something like:

    int main(int argc, char **argv, char **arge) {
    int t;
    char username[255];
    char regcode[255];

    if (argc > 0) {
    strcpy(username,argv[1]);
    for (t=2; t<argc; ++t) {
    strcat(username,argv[t]);
    }
    }

    }

    And yes, you'd want another if/then, or handle if argc is just 1.....
    I just have 2 questions....

    1> Why can't this program be done in Visual Basic?
    2> How do you plang to pass the regcode back to the program?

    >> written to userName, giving you an unterminated string. Even if the

    >prototype
    >> for main were correct (it isn't) and if the code checked argc to make sure
    >> that argv[1] exists before attempting to use it (it doesn't), this fact

    >makes
    >> this a dangerous example to follow.

    >
    >Yes, it has been pointed out to me that this code sample is a fairly inept
    >sample set of code, but it was the sample template that was provided, so I
    >thought I should stick to it as best as possible.
    >
    >While technically you are correct that a well written program should handle
    >all idiot-user mistakes and all types of input, the practicality of the
    >situation is far easier to deal with. We make the variables substantially
    >larger than they will ever need to be(who has a 250 character name, after
    >all?), and everything more or less takes care of itself. Instead of
    >spending all sorts of time figuring out how users will work to break the
    >code, it's going to be used so infrequently as to warrant handling
    >exceptions on a case by case basis. Risk vs Reward analysis and all that.
    >I could spend many hours making DAMN sure the thing never broke, OR I could
    >spend a lot less time, and just make it so huge that it'll never be pressed
    >like that. I realize that it's not the ideal way to do code, but time is
    >money, and this code doesn't warrant any more time than the bare minimum to
    >get it working.
    >
    >I can hear all you coding purists out there gasping for breath right now...
    >on this job, it's just not worth it to totally idiot-proof the thing...
    >Besides, I believe the argument being passed in is going to be truncated at
    >250 characters or something, so we should be covered.
    John H. Guillory, Nov 12, 2003
    #14
  15. Jeff Goslin

    Jimmy Guest

    Try this.
    The issue with the strncpy is that it will always copy 'n' number of chars.
    If the source string is fewer than 'n' then the destination string will be
    padded out to 'n' chars with nulls.
    If you're continuing to parse the command line, such as *(argv+2) into
    regCode, you just repeat the same steps. Obviously change the argc test to
    the equivalent number you're expecting.

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

    int main(int argc, char **argv)
    {
    // First parameter is user's full name
    char userName[255];
    char regCode[255];

    if(argc == 2)
    strncpy(userName, *(argv+1), strlen(*(argv+1)));
    else
    return 1;
    // Code or function calls to
    // place registration code into
    // regCode variable

    printf("%s\n",regCode);
    return 0;
    };

    //alternative 2
    #include <string.h>
    #include <stdio.h>

    int main(int argc, char **argv)
    {
    // First parameter is user's full name
    char userName[255];
    char regCode[255];

    if(argc == 3)
    {
    strncpy(userName, *(argv+1), strlen(*(argv+1)));
    strncpy(regCode, argv[2], strlen(argv[2])); //you can use array
    notation. it does make it easier to read, though there is a little more
    overhead involved at runtime.
    }
    else
    return 1;
    // Code or function calls to
    // place registration code into
    // regCode variable

    printf("%s %s\n",userName,regCode);
    return 0;
    };


    --
    J
    "Jeff Goslin" <> wrote in message
    news:...
    > Hello everyone,
    >
    > I'm an MCSD(on the VB track) who has to convert a relatively simple

    program
    > from VB into ANSI compliant C. The problem is that it's giving me memory
    > access violation errors when I run the program. The program compiles just
    > fine, but when I try to run it, I get the error. I can only assume that
    > this problem is associated with my admittedly limited understanding of
    > string manipulation and pointer usage in C. Any suggestions at all are
    > greatly appreciated.
    >
    > The program is a fairly simple registration code generator. Given a

    user's
    > name, it spits out a registration code specific to that user. It's meant

    to
    > be as generic as possible so I can use it in different programs with
    > different seeds and decoding strings.
    >
    > The code template I was told to follow is this:
    >
    > #include <string.h>
    >
    > int main(int argc, void *argv[])
    > {
    > // First parameter is user's full name
    > char userName[255];
    > char regCode[255];
    >
    > strncpy(userName, argv[1], 255);
    >
    > // Code or function calls to
    > // place registration code into
    > // regCode variable
    >
    > printf("%s\n",regCode);
    > return 0;
    > };
    >
    >
    > I had to make a few modifications to get it to compile(which leads me to
    > believe that something is wrong with my code), so... anyone??? Help???
    >
    > The following code COMPILES, but does not RUN. Examples of what is trying
    > to be accomplished has been included for ease of following the code. If

    the
    > input from the command line is my name, "Jeff Goslin", the output, given

    the
    > following code, should be "131HFASRR4"
    >
    > // RegKeyC.cpp : Defines the entry point for the application.
    > //
    >
    > #include <string.h>
    > #include <stdio.h>
    >
    > int main(int argc, void *argv[])
    > {
    > // First parameter is user's full name
    > // EX: "Jeff Goslin"
    > char *userName;
    > char *regCode;
    >
    > char *seed;
    > char *decoder;
    >
    > char *tmpRevPre;
    > char *tmpFwdPre;
    > char *tmpFinal;
    > char *preencode;
    > int curpos=1;
    > int totalasc;
    >
    > // snag the user name from the passed in arguments
    > strcpy(userName, (char *)argv[1]);
    >
    > // initialize the seed string, for use in the encoding
    > strcpy(seed, "SEEDSTRING\0");
    >
    > // initialize the decoder string, for use in the encoding
    > strcpy(decoder, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\0");
    >
    > // Code or function calls to
    > // place registration code into
    > // regCode variable
    >
    > // reverse the preencode string into a temp variable
    > // hack it off to the length of the seed
    > // the provided username("Jeff Goslin") is reversed("nilsoG ffeJ"),
    > // the seed("SEEDSTRING") is concatenated, and the whole
    > // thing is placed in preencode("nilsoG ffeJSEEDSTRING")
    > strcpy(preencode,strcat(strrev(userName),seed));
    >
    > // the preencode variable is hacked off at 10 characters("nilsoG ffe")
    > strncpy(tmpFwdPre, preencode, strlen(seed));
    >
    > // the preencode variable is reversed, and hacked off at 10
    > characters("GNIRTSDEES")
    > strncpy(tmpRevPre, strrev(preencode), strlen(seed));
    >
    > // encode the stuff
    > while (curpos <= strlen(seed))
    > {
    >
    > // take the ascii codes of the characters at the specified

    position
    > and add them together
    > // in position 1, the codes for G and n will be added
    > together(71+110=181)
    > totalasc = tmpRevPre[curpos] + tmpFwdPre[curpos];
    >
    > // find the remainder when we divide it by the length of the
    > decoder(36)
    > // 181 mod 36 = 1
    > totalasc = (totalasc % strlen(decoder)) + 1;
    >
    > // append the character from the decoder string in the position
    > calculated to the final string
    > // the character in position 1 is a "1"(0 based array, of course)
    > strcat(tmpFinal, (char *)decoder[totalasc]);
    >
    > // increment the position counter, and repeat until done
    > curpos++;
    > }
    >
    > // put the final string("131HFASRR4") into the right variable
    > strcpy(regCode, tmpFinal);
    >
    > // output the right variable
    > printf("%s\n",regCode);
    > return 0;
    > };
    >
    > --
    > Jeff Goslin - MCSD - www.goslin.info
    >
    >
    >
    >
    Jimmy, Nov 23, 2003
    #15
    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. Replies:
    12
    Views:
    439
    Dennis Lee Bieber
    Nov 14, 2006
  2. Replies:
    10
    Views:
    489
    Noah Roberts
    Oct 6, 2006
  3. Replies:
    1
    Views:
    481
  4. Replies:
    11
    Views:
    1,065
    Keith Thompson
    Apr 28, 2008
  5. Frank Iannarilli

    pre-ansi to ansi c++ conversion?

    Frank Iannarilli, Jul 21, 2009, in forum: C++
    Replies:
    2
    Views:
    410
Loading...

Share This Page