Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I want make array which will be declared dynamically I imagine something like this. I want make program that recognize characters in the word.

char i;
scanf("%c",&i);
char word[]=i;
printf("%c",word[0]);

I also tried something like this:

char i;
scanf(%c,&i);
char *word=i;
printf("%c",word[0]);

I have no clue how to make it work.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
137 views
Welcome To Ask or Share your Answers For Others

1 Answer

Let's just start with the basics. What you are declaring when your write:

char word[]=i;

is an array of characters which will be initialized based on what is to the right of the = sign. In this case to i which is a single character (even though that technically is an invalid initializer). So essentially you are attempting to declare a character array of size 1.

If that were allowed, word would not a character string because it was not (and could not be) null-terminated. It is simply an array of type char and cannot be used as a string. (note char word[]="i"; would work - and be null-terminated)

When you declare word as:

char *word=i;

you have created a pointer to type char that is incorrectly initialized to hold the memory address of i.

(a pointer simply contains, as its value, the address for something else stored in memory, in this case you have set that address to the value of i which likely is in the system reserved range of memory and will probably cause an immediate segmentation fault.

What you probably intended was:

char *word=&i;

Where you store the address of i as the value of word. While this will give you a character pointer to i, it has nothing to do with dynamic allocation beyond involving a pointer.

To properly allocate word dynamically, you do still need to create a pointer named word, but you then need to allocate a block of memory that word will point to. (pointing to the starting address for that block of memory). So to dynamically allocate space for word you would expect to see something like:

char *word = NULL;            /* initialization to NULL is good practice */
word = malloc (numbytes * sizeof *word); /* allocate numbytes of storage */

You then have a pointer word whose value is the starting address of the new block of memory of (numbytes x sizeof *word) bytes in size. (since sizeof *word is simply the sizeof (char) its value is 1). So you have created a block of memory numbytes in size.

You have two responsibilities regarding that block of memory (1) you must preserve a pointer to the starting address of that block; so (2) you can free the memory when it is no longer needed. (1) means no word++;, etc.. in your code. If you need to iterate a pointer value, create a pointer, e.g.:

char *p = word;

Then you can use pointer arithmetic on p without effecting the value of word.

You can then fill word any way you like as long as you leave room for a null-terminator at the end (if you are going to use it as a string) and don't attempt to write more than numbytes worth of data to it.

So in your case, if your intent was to dynamically allocate word to hold the character i to be printed as a string, you could easily do:

char *word = NULL;

word = malloc (10 * sizeof *word);
if (!word) {  /* always validate each allocation */
    fprintf (stderr, "error: virtual memory exhausted.
");
    return 1;
}

if (scanf ("9%s", word))
    printf ("word contains '%s'
", word);

free (word);

Note: that when using scanf ("9%s", word), you will stop reading as soon as the first space is encountered. You may want to use scanf ("9%[^ ]%*c", word) which essentially says %9[^ ] read up to 9 characters (that do NOT include a ), then %*c read and discard the newline without adding it to the match count returned by scanf. So your test:

if (scanf ("9%s", word))

insures scanf has read at least one character into word as a string (null-terminating word) which on successful read is added to the match count for scanf making the match count = 1. The match count is then returned by scanf insuring that you only print after a successful read.

Note also: the number of character scanf will read is limited to 9 by including a width specifier %9s (or %9[^ ]) in the format string. This insures you cannot write beyond the end of the memory allocated to word while guaranteeing space available to null-terminate the string.

One other nit. If you are expecting a user to enter data, then prompt the user to enter the data, so the user isn't left looking at a blinking cursor on the screen, wondering if the program got hung up, etc.. Putting all this together in a short example.

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

int main (void) {

    char *word = NULL;

    word = malloc (10 * sizeof *word);
    if (!word) {  /* always validate each allocation */
        fprintf (stderr, "error: virtual memory exhausted.
");
        return 1;
    }

    printf ("
Enter up to 9 characters to store in 'word': ");
    if (scanf ("%9[^
]%*c", word))
        printf ("word contains '%s'
", word);

    free (word);

    return 0;
}

Use/Output

$ ./bin/dynalloc

Enter up to 9 characters to store in 'word': dog
word contains 'dog'

$ ./bin/dynalloc

Enter up to 9 characters to store in 'word': 1234567890
word contains '123456789'

$ ./bin/dynalloc

Enter up to 9 characters to store in 'word': my dog
word contains 'my dog'

Let me know if you have any questions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...