0

I have the passed argument argv[1] in my C program, and I want to convert that string into a character array. How may I do this?

int main(int argc, char* argv[])
{
    char c [] = argv[1]; // This is what I want to do...
}

EDIT:

What I'm trying to do is get certain characters from argv[1] and check if they are numbers. So, ideally, I would do something like:

int a = argv[1][2] 

But this just runs into another problem - how can I check the type of a variable in C?

Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
Waffles
  • 47
  • 2
  • 2
  • 5
  • What exactly is your goal here? You can already access `argv[1]` in the same way you can an array (`argv[1][0]`, `argv[1][1]`, ...). – Cascabel Nov 01 '10 at 01:45
  • 2
    Trick question! A C string *is* a null-terminated character array. – Kevin Stricker Nov 01 '10 at 01:45
  • 1
    @mootinator: A character pointer and a character array (the types) are not totally identical. – Cascabel Nov 01 '10 at 01:47
  • @Jefromi: How so? C doesn't do bounds-checking on array values. – Christian Mann Nov 01 '10 at 01:49
  • @Christian Mann: See for example [C: differences between pointer and array](http://stackoverflow.com/questions/1335786/c-differences-between-pointer-and-array). One is a variable containing an address, one is not. – Cascabel Nov 01 '10 at 03:10

4 Answers4

3

First of all, it already is a character array, NULL-terminated. You can simply choose to make another pointer to it, by saying char *c = argv[1];, or you can copy the entire string (null-terminator and all) into another array using the strcpy(char *destination, char *source)function http://www.cplusplus.com/reference/clibrary/cstring/strcpy/ like this:

char c[BUFFER]; //This has to be big enough to hold length + 1
strcpy(c, argv[1]);

Either approach is valid.

Christian Mann
  • 8,030
  • 5
  • 41
  • 51
  • It is not already a character array. It is a pointer to a contiguous block of memory containing characters. There is a (subtle) difference, though they behave the same in many ways. – Cascabel Nov 01 '10 at 03:12
3

You can treat argv[1] as though it were an array of char (i.e., you can subscript it as argv[1][i]). You can pass it as an argument to any function that doesn't try to modify it (e.g., printf, strtol, strchr, etc.). You cannot write to it, though, so if you need to modify the contents for any reason (either directly or through a function like strtok or strcpy), you'll have to create a local copy and manipulate that.

If you are using C89 or earlier, use this method:

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

int main(int argc, char **argv)
{
  char *c = NULL;
  if (argc >= 2)
  {
    c = malloc(strlen(argv[1]) + 1);
    strcpy(c, argv[1]);
  }
  /**
   * Do stuff with c
   */
  free(c);
  return 0;
}

If you are using C99, you can use a VLA:

#include <string.h>

int main(int argc, char **argv)
{
  if (argc < 2)
    return 0;

  size_t len = strlen(argv[1]);
  char c[len+1];
  strcpy(c, argv[1]);
  /**
   * do stuff with c
   */
  return 0;
}

Just remember a few things:

  1. The type of argv is char **, not char *[N]; similarly, the type of argv[i] is char *, not char [M]. In most circumstances it doesn't matter; you can use a subscript operator on a pointer as though it were an array (array subscripting is defined in terms of pointer arithmetic), but remember that pointers and arrays are not the same thing and are not always interchangeable;

  2. The value of argv[argc] is always NULL;

  3. Except when it is the operand of the sizeof or unary & operators or is a string literal being used as an initializer in a declaration, an expression of array type is converted ("decays") from "N-element array of T" to "pointer to T", and the value of the expression is the location of the first element;

  4. C doesn't have a string data type as such; strings are represented as 0-terminated sequences of char. String literals such as "hello" are stored in such a way that they exist over the lifetime of the program, and you can access them via a pointer value; attempting to modify them results in undefined behavior (i.e., don't do that).

John Bode
  • 119,563
  • 19
  • 122
  • 198
1

argv[1][2] is of type char, always (<pedantry>accessing it causes undefined behavior if there are less than two arguments or if the length of the second argument is less than two - so its questionable whether it has a type in those cases</pedantry>). The character itself may represent a number however, and to check that, use isdigit() from header <ctypes.h>

#include <ctypes.h>
...
if (argc > 1) {
  int digits = 0;
  for (int i = 0, len = strlen(argv[1]); i < len; ++i)
    if (isdigit(argv[1][i]))
      digits++;
  printf("Digits in %s: %d\n", argv[1], digits);
}
eq-
  • 9,986
  • 36
  • 38
  • NOTHING has a true "type" in C -- it's all you access it. Watch: `char c; int i; c = 'A'; i = c; //i is now 65`. Sheesh, I could access a pointer value as an integer and it would let me. Remember, it's just binary. – Christian Mann Nov 01 '10 at 03:21
  • 3
    @Christian: Your comment is not pedantic but incorrect. Objects do have types in C, and except for a few specific cases defined in the standard, accessing an object through a pointer of different type is undefined behavior. BTW your comment has nothing to do with accessing as different types, only with implicit conversion from int to char and then char to int, which are *value* conversions, not reinterpretations of binary data. – R.. GitHub STOP HELPING ICE Nov 01 '10 at 04:03
0

Technically, argv[1] is already a character array. There really isn't such a thing as a "string" in standard C.

What do you want to do with it? Do you just want a copy of it? In that case, you'd need to malloc some space for a new character array and then use "strcpy" to copy from argv[1] into your character array.

Michael Patterson
  • 1,750
  • 13
  • 11