0

I'm trying to generate passwords and copy them to a string. Here is what I want to do:

char generatePassword(int npasswords) {
    int i, z;
    char c, fullPw[300];

    for(z = 0; z < npasswords; z++) {
        for (i = 0; i < 3; ++i) {
            c = rand() % 23 + 'a';
            strcpy(fullPw, c); // ERROR HERE
            printf("%c", c);
        }
        for (i = 0; i < 3; ++i) {
            c = rand() % 23 + 'A';
            printf("%c", c);
            strcat(fullPw, c);
        }
        for (i = 0; i < 3; ++i) {
            c = rand() % 9 + '1';
            printf("%c", c);
            strcat(fullPw, c);
        }
        for (i = 0; i < 4; ++i) {
            c = rand() % 10 + '!';
            printf("%c", c);
            strcat(fullPw, c);
            strcat(fullPw, "\n");
        }
    }
    return fullPw;
}

I'm getting an error

Invalid conversion from 'char' to 'const char*'

Anyone can help how to fix it?

anatolyg
  • 26,506
  • 9
  • 60
  • 134
GoncaloS10
  • 17
  • 4
  • Possible duplicate of [Append Char To String in C?](https://stackoverflow.com/questions/10279718/append-char-to-string-in-c) – Max Vollmer Oct 12 '19 at 09:01
  • There are plenty of good solutions on the duplicate. Just go through the answers and you will find something that fits your needs. – Max Vollmer Oct 12 '19 at 09:04
  • @MaxVollmer: "*plenty [...] solutions*": [Mine](https://stackoverflow.com/a/58352567/694576) is missing ... ;) – alk Oct 12 '19 at 09:16
  • @alk Wouldn't the correct process be to add your answer to the other question and still vote to close this as duplicate? Unless of course you disagree that this is a duplicate at all. – Max Vollmer Oct 12 '19 at 11:28
  • @MaxVollmer: Probably, still I wasn't aware of the dupe, when writing my answer here. – alk Oct 12 '19 at 11:38

2 Answers2

1

strcpy() and strcat() are functions which operate on "strings". A single char is not a string (in C).

strcpy() as well as strcat() take pointers to the 1st element of a 0-terminated char-array (which in fact is what C is using as what other languages call a "string").

The code you show does not pass this for the functions' 2nd argument, but passes as single char only.

So far to what the error-message tells you.

To fix this there are several approaches.

To stay with using functions operating on strings you need to somehow make the char to append a string. This can be done by using a compound literal like so:

    strcpy(fullPw, (char[2]){c});

This (char)[2] defines an unnamed variable of type char[2], initialises its 1st element to c and implicitly initialises the 2nd element to '\0'. Which all in all is a 1-char size "string". Passing it to strcpy() makes it decay to the address of the 1st element, to a char*.

Same for strcat().

BTW, this strcat(fullPw, "\n"); is correctly used as "\n" is a string literal, which defines a 2-char array, with the 1st element being set to '\n' and the 2nd to '\0'. Following the above approach this can as well be written as strcat(fullPw, (char[2]){'\n'});

Also please note that the life time of such "unnamed" variables is the current scope. So if you want to make sure they were deallocated right after there usage, that is inside the functions called, then enclose those calls into there own scope each, like so:

    {
      strcpy(fullPw, (char[2]){c});
    }
alk
  • 69,737
  • 10
  • 105
  • 255
  • This idea is so ugly, it becomes beautiful. Thank you! – anatolyg Oct 12 '19 at 09:14
  • @anatolyg: "*ugly*"? Well, I love compound literals! So am I a pervert? ;) – alk Oct 12 '19 at 09:24
  • Still giving error [Error] expected primary-expression before 'char' [Error] expected ')' before 'char' [Error] invalid conversion from 'char' to 'const char*' [-fpermissive] – GoncaloS10 Oct 12 '19 at 10:13
  • I had three typos. Just fixed them. Please excuse. It should be `(char[2]){c}`. – alk Oct 12 '19 at 10:19
0

first, when compiling, always enable the warnings, then fix them.

For gcc, at a minimum use: -Wall -Wextra -Wconversion -pedantic -std=gnu11

Note: other compilers use different options to produce the same result.

Compiling with the warnings enabled results in:

gcc    -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11  -c "untitled.c"  (in directory: /home/richard/Documents/forum)
untitled.c: In function ‘generatePassword’:
untitled.c:12:17: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
             c = rand() % 23 + 'a';
                 ^~~~
untitled.c:13:28: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
             strcpy(fullPw, c); // ERROR HERE
                            ^
In file included from untitled.c:2:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
untitled.c:17:17: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
             c = rand() % 23 + 'A';
                 ^~~~
untitled.c:19:28: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Wint-conversion]
             strcat(fullPw, c);
                            ^
In file included from untitled.c:2:0:
/usr/include/string.h:129:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
untitled.c:22:17: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
             c = rand() % 9 + '1';
                 ^~~~
untitled.c:24:28: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Wint-conversion]
             strcat(fullPw, c);
                            ^
In file included from untitled.c:2:0:
/usr/include/string.h:129:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
untitled.c:27:17: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
             c = rand() % 10 + '!';
                 ^~~~
untitled.c:29:28: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Wint-conversion]
             strcat(fullPw, c);
                            ^
In file included from untitled.c:2:0:
/usr/include/string.h:129:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
untitled.c:33:12: warning: return makes integer from pointer without a cast [-Wint-conversion]
     return fullPw;
            ^~~~~~
untitled.c:33:12: warning: function returns address of local variable [-Wreturn-local-addr]
Compilation finished successfully.

also, the posted code, even after the above problems are fixed will not compile because it is missing the statements:

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

Note: just because the list of compiler warnings ends with:

Compilation finished successfully.

Does NOT mean the code is correct. It just means the compiler was able to incorporate some kind of workaround for each of the problems in the code. Usually the result is NOT what you intended

Also, the function: rand() should be preceded, usually at the top of the main() function via a call to: srand() similar to:

#include <time.h>
...
int main( void )
{
    ...
    srand( (unsigned)time( void ) );

to initialize the random number sequence with a random value

strongly suggest reading/understanding the MAN pages for the functions that your program is calling

user3629249
  • 16,402
  • 1
  • 16
  • 17