How to store string in c

Thread Starter

champ1

Joined Jun 4, 2018
121
I want to store unknown string like if I want to store name of any person

Here is my attempt

C:
#include<stdio.h>

int main(void)
{
int i, size;

char Name [];

printf("Enter Size of Name \n");

scanf("%d",&size);

printf(" Size of Name : %d \n", size);

for (int i = 0; i < size; i++)
{
  scanf ("%c", &Name[i]);
  printf ("%c", &Name[i]);
}
  return 0;
}
error: array size missing in 'Name'
char Name [];

warning: format '%c' expects argument of type 'int', but argument 2 has type 'char *'
printf ("%c", &Name);

warning: unused variable 'i' [-Wunused-variable]
int i, size;

Edit : If the size of the array is unknown, is it necessary to allocate the dynamic memory?
 

bignobody

Joined Jan 21, 2020
63
Edit : If the size of the array is unknown, is it necessary to allocate the dynamic memory?
Yes. You would need to use malloc to allocate some memory. The other option is to define your array with a fixed size (which is what your "error: array size missing in 'Name' " problem is related to) and then make sure you don't exceed it.
 
Last edited:

dl324

Joined Mar 30, 2015
10,705
Whether you use a fixed string size or malloc(), the length needs to include the terminating NULL character.
 

WBahn

Joined Mar 31, 2012
25,738
I want to store unknown string like if I want to store name of any person

Here is my attempt

C:
#include<stdio.h>

int main(void)
{
int i, size;

char Name [];

printf("Enter Size of Name \n");

scanf("%d",&size);

printf(" Size of Name : %d \n", size);

for (int i = 0; i < size; i++)
{
  scanf ("%c", &Name[i]);
  printf ("%c", &Name[i]);
}
  return 0;
}
error: array size missing in 'Name'
char Name [];

warning: format '%c' expects argument of type 'int', but argument 2 has type 'char *'
printf ("%c", &Name);

warning: unused variable 'i' [-Wunused-variable]
int i, size;

Edit : If the size of the array is unknown, is it necessary to allocate the dynamic memory?

Oh, so much is wrong -- some blatant and some subtle.

When declare an array variable using the array brackets you have three choices:

type name[] = {initialization list};

The compiler examines the list and allocates at least enough memory to store that list and then stores the list in the array.

type name[size];

The compiler allocates at least enough memory for (size) items of the specified type. The memory is usually uninitialized.

type name[size] = {initialization list}; // number of items in list is no more than size.

The compiler allocates at least enough memory for (size) items of the specified type, Initialize the leading items using the items in the initialization list, and initializes all remaining items to 0.

So if you go

char Name[];

The compiler has no idea how many items to allocate memory for, so it can't do it and throws a compiler error.

Even if you allocated memory for your array, your code makes no effort to stay within those bounds. This is all kinds of problems waiting to happen, including letting someone else take control of your system.

In addition, you are not nul-terminating your string, which is required in C (if you are going to use any of the library functions that work with strings).
 

Thread Starter

champ1

Joined Jun 4, 2018
121
The compiler examines the list and allocates at least enough memory to store that list and then stores the list in the array.

type name[size];
This means if I know the length of the array, then I can use static array.

C:
#include<stdio.h>

int main ()

{
    unsigned char Name[8]; int i = 0;

    printf("Enter each character to store \n");

    for (i=0; i<8; i++)
    {
         scanf(" %c", &Name[i]);
    
    }
    for (i=0; i<8; i++)
    {
         printf ("%c", Name[i]);
    }

    return 0;
}
if I don't know the length of the array, then I can use dynamic array.

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

int main()
{
    int i;

    // Dynamically allocate memory using malloc()
     char * Name  = malloc(8 * sizeof(Name));

    if (Name == NULL) {
        printf("Memory not allocated.\n");
        exit(0);
    }
    else {

        // Memory has been successfully allocated
        printf("Memory successfully allocated using malloc.\n");

        // Get the elements of the array
        for (i = 0; i < 8; ++i) {
           
            scanf(" %c", Name[i]);

        }

        // Print the elements of the array
        printf("The elements of the array are: ");
        for (i = 0; i < 8; ++i) {
            printf("%d, ", Name[i]);
        }
    }

    return 0;
}
warning: format '%c' expects argument of type 'char *', but argument 2 has type 'int'
scanf(" %c", Name);

What's wrong in my program ?
 
Last edited:

MrSoftware

Joined Oct 29, 2013
1,775
For the static code (use this to see if you can fix your dynamic code too):

First a proper string needs to end with a 0, so for an 8 character string you really need 9 characters. Many string functions, such as printf("%s",Name), will continue printing until they run into a 0. If there is no 0 then they will continue on through memory that they shouldn't be reading through. Change your allocation:

C:
unsigned char Name[9];
scanf() wants a pointer to a memory location, you're passing it the data that's in the memory location. So to store the first character, you need to pass the address of the location where the first character is to be stored. Use the address-of operator like this:

C:
scanf(" %c", &(Name[i]));
After you're done reading, be sure the last character is the 0 so you don't run into the problem described above:

C:
Name[8] = '\0';  // ascii code for 0
Your printf to print the name back is printing the numerical values (ascii codes, http://www.asciitable.com/) that were stored by scanf. This isn't necessarily wrong, but I suspect it's not what you want in this case. Instead of %d, use %c so that printf interprets the number that you're passing it as an ascii character. See this page: https://www.tutorialspoint.com/c_standard_library/c_function_printf.htm

C:
printf("%c, ", Name[i]); // One char
printf("%s ", Name); // Whole string
 
Last edited:

WBahn

Joined Mar 31, 2012
25,738
This means if I know the length of the array, then I can use static array.
Whether the array is static or not depends on how/where you define it.

In your example for dynamically allocated memory, you have the size hardcoded as 8, which means that you know the size of the array at compile time.

The way that you are printing out the contents of the array in these examples means that you don't have to have NUL-terminated strings. But in general you do and it is good practice to do so unless you have a damn good reason not to.

warning: format '%c' expects argument of type 'char *', but argument 2 has type 'int'
scanf(" %c", Name);

What's wrong in my program ?
In your first example you have: scanf(" %c", &Name);
In your second example you have: scanf(" %c", Name);

One is throwing a warning and the other isn't, so perhaps you want to examine what the difference is between the two and why it might matter.
 

WBahn

Joined Mar 31, 2012
25,738
Try with "char name[100]"
Two problems with that approach: (1) What if you are targeting a resource-starved processor with very limited memory? (2) What if the person enters a string with 100 or more characters?

Whenever you get input from some source (and especially if it's an uncontrolled source such as the keyboard) you need to always assume that the input will be bad, perhaps being malformed (a string that can't be interpreted as a number when you asked for a number, for instance) or excessively long (the person sat there with a key pressed down and then hit enter, for instance). You also should assume that the malformed and/or lengthy input is the result of malicious intent. Your code should behave properly regardless.
 

BobaMosfet

Joined Jul 1, 2009
1,108
I want to store unknown string like if I want to store name of any person

Here is my attempt

C:
#include<stdio.h>

int main(void)
{
int i, size;

char Name [];

printf("Enter Size of Name \n");

scanf("%d",&size);

printf(" Size of Name : %d \n", size);

for (int i = 0; i < size; i++)
{
  scanf ("%c", &Name[i]);
  printf ("%c", &Name[i]);
}
  return 0;
}
error: array size missing in 'Name'
char Name [];

warning: format '%c' expects argument of type 'int', but argument 2 has type 'char *'
printf ("%c", &Name);

warning: unused variable 'i' [-Wunused-variable]
int i, size;

Edit : If the size of the array is unknown, is it necessary to allocate the dynamic memory?
You have to learn to pick and choose your battles. Normally if you're dealing with small stuff, you just allocated an array with enough space in it that you will likely never exceed it-- and you range check it. You only us allocation for larger blocks (you don't want to fragment your heap). And in embedded development you rarely use allocation, for heap management and performance reasons, unless you understand what you're really doing in memory spaces.

If it's in a function, for something like a name, just declare it:

Code:
char Name[50];
and be done with it. When the function goes away, the stackframe is gone, the variable 'goes away'.

Finally- it's a 'C' string- you need to terminate it with a 0x00 byte. if it doesn't have one already.
 
Top