-1

Is my syntax incorrect? Did I make an error somewhere?

These are the error messages I received. I have tried fixing all these errors but I have hit a wall and don't know what to do.

~/workspace/pset1 $ make mario
clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wshadow    mario.c  -lcs50 -lm -o mario
mario.c:27:15: error: incompatible pointer to integer conversion assigning to 'char' from 'char [2]' [-Werror,-Wint-conversion]
        blank = "s";
              ^ ~~~

mario.c:29:14: error: incompatible pointer to integer conversion assigning to 'char' from 'char [2]' [-Werror,-Wint-conversion]
        hash = "#";
             ^ ~~~

mario.c:30:16: error: incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *' [-Werror,-Wint-conversion]
        printf(blank*(h-(i + 1)));
               ^~~~~~~~~~~~~~~~~

/usr/include/stdio.h:362:43: note: passing argument to parameter '__format' here
extern int printf (const char *__restrict __format, ...);
                                          ^

mario.c:30:16: error: format string is not a string literal (potentially insecure) [-Werror,-Wformat-security]
        printf(blank*(h-(i + 1)));
               ^~~~~~~~~~~~~~~~~

mario.c:31:40: error: adding 'int' to a string does not append to the string [-Werror,-Wstring-plus-int]
        printf(hash*((h+1)-(h-(i + 1)))+"\n");
               ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~

mario.c:31:40: note: use array indexing to silence this warning
mario.c:31:16: error: format string is not a string literal (potentially insecure) [-Werror,-Wformat-security]
        printf(hash*((h+1)-(h-(i + 1)))+"\n");
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

6 errors generated.
make: *** [mario] Error 1

Source

#include <stdio.h>
#include <cs50.h>

int main()
{
    int h;
    // asking the user to pick the height of the half pyramid
    do
    {
        printf("Pick a number from 1-23: \n");
        h = GetInt();
    }
    while (h > 23);

    //  if the number is 5 the half pyramid should look like this
    //   ----##
    //   ---###
    //   --####
    //   -#####
    //   ######
    //  like at the end of super mario

    int i;
    for (i = 0; i < h; i++)
    {
        char blank;
        blank = "s";
        char hash;
        hash = "#";
        printf(blank * (h-(i + 1)));
        printf(hash * ((h+1)-(h-(i + 1)))+"\n");
    }
    // I wanted to test my code with s and #
    // because I don't know how to print blank spaces in C
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Ara Yaghsizian
  • 1,279
  • 1
  • 8
  • 10
  • 1
    `blank = ' ';` and `hash = '#';` Double quotes are for strings, single quotes for characters. As for the `printf`, it doesn't work that way. Read the man page, or one of [these fine books](http://stackoverflow.com/a/562377/3386109). – user3386109 Jul 26 '16 at 06:36
  • 2
    And `((h+1)-(h-(i+1)))` can be simplified to: `(i + 2)`, as far as I can see. – Rudy Velthuis Jul 26 '16 at 06:41
  • You can't build a string of multiple chars using `*` like in, say, Python (or Ruby?). You will have to print them one by one in a loop. – Rudy Velthuis Jul 26 '16 at 06:43
  • Thank you everyone. All 3 comments were helpful. – Ara Yaghsizian Jul 26 '16 at 07:21

2 Answers2

3

Use printf with width * and precision .* flags:

char *blank = "";//use char* (or const char*) for string literal
char *hash = "########################";//#*(23+1)
for (int i = 0; i < h; i++)
{
    printf("%*s", h-(i + 1), blank);
    printf("%.*s\n", i + 2, hash);
}

Basic operations of a constant multiple of the string does not exist in C.
(like "#" * 5 => "#####")
So, to implement on their own.
For example, something like the following.

#include <stdlib.h>
#include <string.h>
//...
char *stringXn(const char *string, size_t n){
    size_t len = strlen(string);
    char *ret = malloc(len * n + 1);//allocate myself, +1 : for terminator('\0')
    if(ret == NULL){
        fprintf(stderr, "malloc failed in %s function\n", __func__);
        exit(EXIT_FAILURE);
    }
    *ret = 0;
    for(size_t i = 0; i < n; ++i){
        memcpy(ret + i * len, string, len+1);//+1 : for terminator('\0')
    }
    return ret;
}

With it you can write in the following

for (int i = 0; i < h; i++)
{
    char *blank = stringXn(" ", h-(i + 1));
    char *hash  = stringXn("#", i + 2);
    printf(blank);
    puts(hash);//printf("%s\n", hash);
    free(blank);//deallocate myself
    free(hash);
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • boy do I appreciate your answer. My code works and I can move on. However this is my first day writing anything in C and as a beginner I don't understand the terms width, precision, flags, const, or string literal. My limited background is in Python, which seems to be much more intuitive than C. Is there a way of writing that in a way that a beginner would understand? -- Thanks, Ara – Ara Yaghsizian Jul 26 '16 at 07:37
0

I know this is very old but might help someone

    char *blank = "";
    char *hash = "
    for (int i = 0; i < h; i++)
    {
        //if this code is run the first # will not start with 1 but ## so fix that make changes to the below prinf statements

        printf("%*s", h-(i + 1), blank);
        printf("%.*s\n", i + 2, hash);
    }
    //the fixes are minor as below h as we see here is the var we looping on so total number of loops minus 1 blanks

    printf("%*s", h-i , blank);
    //and add 1 to i fixes it.

    printf("%.*s\n", i + 1, hash);
brunorey
  • 2,135
  • 1
  • 18
  • 26
R.Ovie
  • 323
  • 4
  • 14