Question

For exercising my programming skills in C I'm trying to write the strncpy function by myself. Doing that I kept hitting errors, solving most of them eventually I'm stuck with no further inspiration to go on.

The error I receive is:

ex2-1.c:29:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
   printf("The copied string is: %s.\n", stringb);

The thing is that it's a very common error and that it's also already described on SO, only I can't seem to apply the tips other people have already pointed out. I get that I'm using a wrong type when printing the variable, and when I use the %d format it will return an integer which is probably the ASCII value of the first character, as it doesn't change when increasing the max number of bytes to copy.

Using GDB I've found out that the b variable when done iterating through the while loop holds the correct string, still I can't seem to print it.

I'm probably lacking a very fundamental part of knowledge about the C language and I apologise for asking this novice question (once again). Also I would appreciate it if you could give feedback or point out other flaws in my code.

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

void strmycpy(char **a, char *b, int maxbytes) {
  int i = 0;
  char x = 0;

  while(i!=maxbytes) {
  x = a[0][i];
  b[i] = x;
  i++;
  }

  b[i] = 0;

}


int main (int argc, char **argv) {
  int maxbytes = atoi(argv[2]);
  //char stringa;
  char stringb;
  if (argc!=3 || maxbytes<1) {
        printf("Usage: strmycpy <input string> <numberofbytes>. Maxbytes has to be more than or equal to 1 and keep in mind for the NULL byte (/0).\n");
        exit(0);
     } else {

  strmycpy(&argv[1], &stringb, maxbytes);
  printf("The copied string is: %s.\n", stringb);

  }

  return 0;
}
Was it helpful?

Solution

There is a slight difference between char and char*. The first is a single character whereas the later is a pointer to char (which can point to variable number of char objects).

The %s format specifier really expects a C-style string, which should not only be of type char* but is also expected to be null-terminated (see C string handling). If you want to print a single character, then use %c instead.

As for the program, assuming that what I think you want is what you want, try something like this:

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

static void strmycpy(char *dest, const char *src, size_t n) {
    char c;
    while (n-- > 0) {
        c = *src++;
        *dest++ = c;
        if (c == '\0') {
            while (n-- > 0)
                *dest++ = '\0';
            break;
        }
    }
}

int main(int argc, char *argv[]) {
    size_t maxbytes;
    char *stringb;

    if (argc != 3 || !(maxbytes = atoll(argv[2]))) {
        fprintf(
            stderr,
            "Usage: strmycpy <input string> <numberofbytes>.\n"
            "Maxbytes has to be more than or equal to 1 and keep "
            "in mind for the null byte (\\0).\n"
        );
        return EXIT_FAILURE;
    }

    assert(maxbytes > 0);
    if (!(stringb = malloc(maxbytes))) {
        fprintf(stderr, "Sorry, out of memory\n");
        return EXIT_FAILURE;
    }

    strmycpy(stringb, argv[1], maxbytes);
    printf("The copied string is: %.*s\n", (int)maxbytes, stringb);
    free(stringb);

    return EXIT_SUCCESS;
}

But frankly speaking, this is so fundamental that explaining might just result in writing a book on C. So you will be a lot better off if you just read one already written. For a list of good C books and resources, see The Definitive C Book Guide and List

Hope it helps. Good Luck!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top