expected expression before char

Viewed 473

I have written this program that asks the user for a name and then prints the name. Here are the steps in detail:

  • asks the user for the number of characters the name (i.e. sentence) will have. It includes empty spaces and the terminator character \0, then stores it;
  • it creates a block of memory with num_char addresses, and stores the address of the first item in ptr;
  • within the else section, an array of unknown size is declared, which will be used to store the name and its first address is assigned to ptr;
  • then the array is assigned with size num_char;

Here's the code:

#include <stdio.h>
#include <stdlib.h>
//an attempt at a program that asks for a name, stores it in an array and then prints it

int main() {
    int num_char;
    char *ptr;

    printf("input number of characters of your name (spaces and terminator character included): ");

    scanf("%d", &num_char);

    ptr = char *malloc(num_char * sizeof(char)); //creates a block of mem to store the input name, with the same size, and then returns the adress of the beginning of the block to ptr

    if (ptr == NULL) {
        printf("allocation not possible");
    } else {
        ptr = char name[]; //ptr stores the adress of the first char in string

        char name[num_char], //declaration of an array with num_char elements

        printf("input name: ");

        scanf("%s", name);
        printf("input name was: %s", name);
    }
    return 0;
} 

However I get three compilation errors which are:

  • "expected expression before 'char' " at ptr = char *malloc(num_char * sizeof(char) ); and ptr = char name[];
  • "expected declaration specifiers or '...' before string constant" at printf("input name: ");

I am a college student just beginning at C and programming in general so a detailed explanation of any error of any kind and how to fix it would be very much appreciated :)

2 Answers

These are syntax errors because:

  • ptr = char *malloc(num_char * sizeof(char)); should have been ptr = (char *)malloc(num_char * sizeof(char)); or simply ptr = malloc(num_char * sizeof(char));.

  • ptr = char name[]; is meaningless. You do not need to change ptr at all.

  • char name[num_char], is a C99 variable length array definition, but with a trailing , so the next line is expected to have another definition, hence the second error.

You must choose to either allocate memory from the heap with malloc() or define an array as a local variable.

Here is a modified version:

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

int main() {
    int num_char;
    char *ptr;

    printf("input number of characters of your name (spaces and terminator character included): ");

    if (scanf("%d", &num_char) != 1 || num_char <= 1) {
        printf("invalid input\n");
        return 1;
    }
    /* discard the rest of the input including the newline */
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        continue;

    //allocate a block of memory to store the name
    ptr = malloc(num_char * sizeof(char));

    if (ptr == NULL) {
        printf("allocation not possible");
    } else {
        printf("input name: ");

        if (scanf("%[^\n]", ptr) == 1)
            printf("input name was: %s\n", name);
        else
            printf("no input was given\n");

        free(ptr);
    }
    return 0;
} 

Also note that scanf() may read more than num_char bytes if the input has more non white bytes, so it would be much safer, but non-trivial to given scanf() the information about the array size:

    if (ptr != NULL) {
        char format[32];
        snprintf(format, sizeof format, "%%%d[^\n]", num_char - 1);
        printf("input name: ");
        if (scanf(format, ptr) == 1) {
            printf("input name was: %s\n", name);
            // should discard the rest of the line and the newline
        } else {
            printf("no input was given\n");
        }
    }

As I stated in the comments, this is a wierd set of requirements for, what I assume is an assignment, here is more or less what you should do, with comments:

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

void clear_buffer()
{ // routine to clear standard input
    int c;
    while ((c = getchar()) != '\n' && c != EOF){}
    if (c == EOF)
    {
        exit(EXIT_FAILURE);
    }
}
int main()
{
    int num_char;
    char *ptr;

    printf("input number of characters of your name (spaces and terminator character included): ");
    // less than 9 + 1 null byte characters for the name not allowed
    while (scanf("%d", &num_char) != 1 || num_char < 10)
    { 
        printf("Bad input, try again: ");
        clear_buffer();
    }
    ptr = malloc(num_char); // removed char*, you may wanted a cast, 
                            // but even that is unneeded,
                            // The size of char is always 1 byte
                            // I still don't understand why this is asked, but well...
    if (ptr == NULL)
    {
        perror("allocation not possible"); // perror prints the apropriate error
    }
    else
    {
        char name[num_char]; // declaration of an array with num_char elements
        free(ptr);           // to make ptr point to another memory location, it must be freed
        ptr = name;          // ptr now points to the first element of the name array

        clear_buffer();
        printf("What's the name ? ");
        // read name with spaces from standard input
        if (fgets(name, num_char, stdin))
        {                   
            name[strcspn(name, "\n")] = '\0'; // remove \n 
            printf("input name was: %s", ptr); // print name through ptr 
        }  
        else
        {
            puts("Bad input");
        }                    
       
    }
    return EXIT_SUCCESS;
}

Pending on ambiguous interpretation...

Related