Thread: Why can a string be assigned to a 'char' pointer?

  1. #1
    Registered User
    Join Date
    Aug 2018
    Posts
    7

    Why can a string be assigned to a 'char' pointer?

    I was making a program that asked the user for a number and printed the number of points the user typed, but changing the grammatical number of the noun. For example: if I type "1", the program should print "1 point." and if I type "3" the program should print "3 points.".
    The first thing I thought was to assign the different values inside the if statement:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
        char noun[7];
        int points;
        printf("Type a number: ");
        scanf("%i", &points);
        if (points == 1) {
            strncpy(points, "point", 6);
        }
        else {
            strncpy(points, "points", 7);
        }
        printf("%i %s.\n", points, noun);
    }
    But this generates a "Segmentation fault" error, so I had an idea: declare two different strings and a pointer and assign their memory address inside the if statement:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
        char singular[6] = "point";
        char plural[7] = "points";
        char *noun;
        int points;
        printf("Type a number: ");
        scanf("%i", &points);
        if (points == 1) {
            noun = singular;
        }
        else {
            noun = plural;
        }
        printf("%i %s.\n", points, noun);
    }
    This worked flawlessly, but I decided to search on the Internet another possible solution and I found this one here: c - assign a string of variable length in conditional statement - Stack Overflow

    According to that answer, my code could be like this:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
        char *noun;
        int points;
        printf("Type a number: ");
        scanf("%i", &points);
        if (points == 1) {
            noun = "point";
        }
        else {
            noun = "points";
        }
        printf("%i %s.\n", points, noun);
    }
    And this also worked. Now, here's my question: why can I assign a char pointer a string? I thought pointers were assigned a memory address. If I understood correctly, I can assign a pointer an array because an array is actually a pointer to its first element. And as strings are actually also arrays, I can assign a string to a pointer. But I can't do the following:
    Code:
    #include <stdio.h>
    
    int main(void) {
        int *numbers;
        numbers = {1, 2, 3, 4}; /* Wrong */
        for (int i = 0; i < 4; i++) {
            printf("%i\n", numbers[i]);
        }
    }
    Even using malloc() doesn't work:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void) {
        int *numbers = malloc(4 * sizeof(int)); /* Also wrong */
        numbers = {1, 2, 3, 4};
        for (int i = 0; i < 4; i++) {
            printf("%i\n", numbers[i]);
        }
        free(numbers);
    }
    It cannot be assigned without specifying the index. So why can I assign a string to a pointer without specifying its index/length and why can't I do the same with a number?
    I hope I've explained myself well, and thanks in advance.

  2. #2
    Registered User
    Join Date
    Dec 2011
    Location
    Namib desert
    Posts
    85
    In your very first example you try to copy a string into an integer ....
    In your other code snippets, you let a char- pointer point to an already existing array (of chars), that works.
    But in your last code-snippet your assign memory addresses to the 4 integer-pointers

    The following, correct code, might be of some help:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int numbers[] = {1, 2, 3, 4};
        int i;
        int *nrs;
    
        for (i = 0; i < 4; i++)
            printf("%i\n", numbers[i]);
    
        for (nrs = numbers, i = 0; i < 4; i++)
            printf("%i\n", nrs[i]);
    }

  3. #3
    Registered User
    Join Date
    Aug 2018
    Posts
    7
    Quote Originally Posted by ddutch View Post
    In your very first example you try to copy a string into an integer ....
    Yes, my fault. I didn't notice it. strncpy(noun, "point", 6) works as well.

    Quote Originally Posted by ddutch View Post
    In your other code snippets, you let a char- pointer point to an already existing array (of chars), that works.
    Does that mean that when I assign a char pointer a string (e.g., char *noun = "point";) the string I typed is actually an existing array?

    Additionally, I took a look at the "Hunt the Wumpus" game found in the BSDGames package, and it uses a macro to add an "s" depending on the number:
    Code:
    #include <stdio.h>
    
    #define    plural(n) (n == 1 ? "" : "s")
    
    int main(void) {
        int points;
        printf("Type a number: ");
        scanf("%i", &points);
        printf("%i point%s.\n", points, plural(points));
    }
    It can be found here, for those interested: BSDGames/wump.c at master * vattam/BSDGames * GitHub

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    36,491
    > Does that mean that when I assign a char pointer a string (e.g., char *noun = "point";)
    > the string I typed is actually an existing array?
    Yes, all your strings (even those passed to printf etc) are anonymous char arrays generated by the compiler.

    Eg.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
        char *noun;
        int points;
        printf("Type a number: ");
        scanf("%i", &points);
        if (points == 1) {
            noun = "point";
        }
        else {
            noun = "points";
        }
        printf("%i %s.\n", points, noun);
    }
    
    
    $ compile with -S to see the assembler
    $ gcc -S foo.c
            .file   "foo.c"
            .section        .rodata
    .LC0:
            .string "Type a number: "
    .LC1:
            .string "%i"
    .LC2:
            .string "point"
    .LC3:
            .string "points"
    .LC4:
            .string "%i %s.\n"
            .text
            .globl  main
            .type   main, @function
    main:
    .LFB0:
            .cfi_startproc
            pushq   %rbp
            .cfi_def_cfa_offset 16
            .cfi_offset 6, -16
            movq    %rsp, %rbp
            .cfi_def_cfa_register 6
            subq    $32, %rsp
            movq    %fs:40, %rax
            movq    %rax, -8(%rbp)
            xorl    %eax, %eax
            movl    $.LC0, %edi
            movl    $0, %eax
            call    printf
            leaq    -20(%rbp), %rax
            movq    %rax, %rsi
            movl    $.LC1, %edi
            movl    $0, %eax
            call    __isoc99_scanf
            movl    -20(%rbp), %eax
            cmpl    $1, %eax
            jne     .L2
            movq    $.LC2, -16(%rbp)
            jmp     .L3
    .L2:
            movq    $.LC3, -16(%rbp)
    .L3:
    All your strings are stored in the read-only data section with names .LC0 etc.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Aug 2018
    Posts
    7
    I see. I didn't know that. I knew a string is actually an array, and that an array is a pointer to its first element, that's why I was a bit confused when I discovered you can assign a pointer a string without declaring it. I guess you learn something new every day.
    Thanks to both of you, ddutch and Salem.

  6. #6
    Registered User
    Join Date
    Jul 2018
    Posts
    4
    Thank you for clearing my doubt

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 12-02-2012, 05:25 AM
  2. can array be assigned a pointer ?
    By pshirishreddy in forum C++ Programming
    Replies: 8
    Last Post: 06-19-2011, 05:44 AM
  3. finding length of characters in an assigned char array ??
    By charlatanksk in forum C Programming
    Replies: 6
    Last Post: 05-04-2008, 02:34 PM
  4. fgets assigned to a char
    By Astra in forum C Programming
    Replies: 3
    Last Post: 10-22-2006, 03:19 AM
  5. Function Pointer Assigned To Map Overload Resolution Problem!
    By DeepBlackMagic in forum C++ Programming
    Replies: 1
    Last Post: 05-01-2004, 05:41 AM

Tags for this Thread