Initialize a string in C to empty string - c

I want to initialize string in C to empty string.
I tried:
string[0] = "";
but it wrote
"warning: assignment makes integer from pointer without a cast"
How should I do it then?

In addition to Will Dean's version, the following are common for whole buffer initialization:
char s[10] = {'\0'};
or
char s[10];
memset(s, '\0', sizeof(s));
or
char s[10];
strncpy(s, "", sizeof(s));

You want to set the first character of the string to zero, like this:
char myString[10];
myString[0] = '\0';
(Or myString[0] = 0;)
Or, actually, on initialisation, you can do:
char myString[10] = "";
But that's not a general way to set a string to zero length once it's been defined.

Assuming your array called 'string' already exists, try
string[0] = '\0';
\0 is the explicit NUL terminator, required to mark the end of string.

Assigning string literals to char array is allowed only during declaration:
char string[] = "";
This declares string as a char array of size 1 and initializes it with \0.
Try this too:
char str1[] = "";
char str2[5] = "";
printf("%d, %d\n", sizeof(str1), sizeof(str2)); //prints 1, 5

calloc allocates the requested memory and returns a pointer to it. It also sets allocated memory to zero.
In case you are planning to use your string as empty string all the time:
char *string = NULL;
string = (char*)calloc(1, sizeof(char));
In case you are planning to store some value in your string later:
char *string = NULL;
int numberOfChars = 50; // you can use as many as you need
string = (char*)calloc(numberOfChars + 1, sizeof(char));

To achieve this you can use:
strcpy(string, "");

string[0] = "";
"warning: assignment makes integer from pointer without a cast
Ok, let's dive into the expression ...
0 an int: represents the number of chars (assuming string is (or decayed into) a char*) to advance from the beginning of the object string
string[0]: the char object located at the beginning of the object string
"": string literal: an object of type char[1]
=: assignment operator: tries to assign a value of type char[1] to an object of type char. char[1] (decayed to char*) and char are not assignment compatible, but the compiler trusts you (the programmer) and goes ahead with the assignment anyway by casting the type char* (what char[1] decayed to) to an int --- and you get the warning as a bonus. You have a really nice compiler :-)

I think Amarghosh answered correctly. If you want to Initialize an empty string(without knowing the size) the best way is:
//this will create an empty string without no memory allocation.
char str[]="";// it is look like {0}
But if you want initialize a string with a fixed memory allocation you can do:
// this is better if you know your string size.
char str[5]=""; // it is look like {0, 0, 0, 0, 0}

It's a bit late but I think your issue may be that you've created a zero-length array, rather than an array of length 1.
A string is a series of characters followed by a string terminator ('\0'). An empty string ("") consists of no characters followed by a single string terminator character - i.e. one character in total.
So I would try the following:
string[1] = ""
Note that this behaviour is not the emulated by strlen, which does not count the terminator as part of the string length.

Related

In this solution, if *inputString is a memory address (and the input is a char type) then does *inputString qualify as an array?

I was solving a challenge on CodeSignal in C. Even though the correct libraries where included, I couldn't use the strrev function in the IDE, so I looked up a similar solution and modified it to work. This is good. However, I don't understand the distinction between a literal string and an array. Reading all this online has left me a bit confused. If C stores all strings as an array with each character terminated by \0 (null terminated), how can there be any such thing as a literal string? Also if it is the case that strings are stored as an array, *would inputString store the address of the array or is it an array itself of all the individual characters stored.
Thanks in advance for any clarification provided!
Here is the original challenge, C:
Given the string, check if it is a palindrome.
bool solution(char * inputString) {
// The input will be character array type, storing a single character each terminated by \0 at each index
// * inputString is a pointer that stores the memory address of inputString. The memory address points to the user inputted string
// bonus: inputString is an array object starting at index 0
// The solution function is set up as a Boolean type ("1" is TRUE and the default "0" is FALSE)
int begin;
// The first element of the inputString array is at position 0, so is the 'counter'
int end = strlen(inputString) - 1;
// The last element is the length of the string minus 1 since the counter starts at 0 (not 1) by convention
while (end > begin) {
if (inputString[begin++] != inputString[end--]) {
return 0;
}
} return 1;
}
A string is also an array of symbols. I think that what you don't understand is the difference between a char pointer and a string. Let me explain in an example:
Imagine I have the following:
char str[20]="helloword";
str is the address of the first symbol of the array. In this case str is the address of h. Now try to printf the following:
printf("%c",str[0]);
You can see that it has printed the element of the addres that is 'h'.
If now I declare a char pointer, it will be poining to whatever char adress I want:
char *c_pointer = str+1;
Now print the element of c_pointer:
printf("%c",c_pointer[0]);
You can see that it will print 'e' as it is the element of the second adress of the original string str.
In addition, what printf("%s", string) does is to printf every elemet/symbol/char from the starting adress(string) to the end adress where its element is '\0'.
The linked question/answers in the comments pretty much cover this, but saying the same thing a slightly different way helps sometimes.
A string literal is a quoted string assigned to a char pointer. It is considered read only. That is, any attempts to modify it result in undefined behavior. I believe that most implementations put string literals in read-only memory. IMO, it's a shortcoming of C (fixed in C++) that a const char* type isn't required for assigning a string literal. Consider:
int main(void)
{
char* str = "hello";
}
str is a string literal. If you try to modify this like:
#include <string.h>
...
str[2] = 'f'; // BAD, undefined behavior
strcpy(str, "foo"); // BAD, undefined behavior
you're broken the rules. String literals are read only. In fact, you should get in the habit of assigning them to const char* types so the compiler can warn you if you try to do something stupid:
const char* str = "hello"; // now you should get some compiler help if you
// ever try to write to str
In memory, the string "hello" resides somewhere in memory, and str points to it:
str
|
|
+-------------------> "hello"
If you assign a string to an array, things are different:
int main(void)
{
char str2[] = "hello";
}
str2 is not read only, you are free to modify it as you want. Just take care not to exceed the buffer size:
#include <string.h>
...
str2[2] = 'f'; // this is OK
strcpy(str2, "foo"); // this is OK
strcpy(str2, "longer than hello"); // this is _not_ OK, we've overflowed the buffer
In memory, str2 is an array
str2 = { 'h', 'e', 'l', 'l', '0', '\0' }
and is present right there in automatic storage. It doesn't point to some string elsewhere in memory.
In most cases, str2 can be used as a char* because in C, in most contexts, an array will decay to a pointer to it's first element. So, you can pass str2 to a function with a char* argument. One instance where this is not true is with sizeof:
sizeof(str) // this is the size of pointer (either 4 or 8 depending on your
// architecture). If _does not matter_ how long the string that
// str points to is
sizeof(str2) // this is 6, string length plus the NUL terminator.

Cant add characters to a char pointer assigned to ""

Say I have this code
char *string = "";
string += 'A';
string += 'B';
string += 'C';
printf("%s\n", string);
It just prints an empty line. Why does it do this and is there an easy way to concatenate single characters starting from an empty string if I don't know how long it'll be?
In statements like this
string += 'A';
there is used the pointer arithmetic. The value of the internal representation of the character 'A' is added to the value of the pointer string and as a result the pointer has an invalid value because it does not point to an actual object.
You need to declare a character array as for example
char string[4] = "";
and then you can set respective elements of the array to character literals like for example
int i = 0'
string[i++] = 'A';
string[i++] = 'B';
string[i++] = 'C';
string[i] = '\0';
printf("%s\n", string);
Also you have a typo in this call
printf("&s\n", string);
If a character array already contains a string like
char string[4] = "AB";
and you want to append a character to the end of the string then either you can write using a character literal
size_t n = strlen( string );
string[n] = 'C';
string[n + 1] = '\0';
Or you can use a string literal and the standard C function strcat like
strcat( string, "C" );
In any case the character array shall have enough space to accommodate a new character.
string is just a pointer to the string literal "", so when you add a char with +, you're actually just moving the pointer instead of concatenating to the string. In C, you can allocate a sufficiently large string and use strcat to add strings into it:
char string[100] = "";
strcat(string, "A");
strcat(string, "B");
strcat(string, "C");
printf("%s\n", string);
If you want to use chars, then you can convert the char to a string first.
string += 'A'; does not append a character to the string, it increments the char pointer string by the value of 'A' which on systems that use ASCII is 65 and makes string point well beyond the end of the "" string literal. Hence this code has undefined behavior.
printf("&s\n", string); should print &s and a newline.
Assuming you mistyped your code in the question, printf("%s\n", string); would have undefined behavior, and printing an empty line is possible, as well as a crash or any other nasty side-effect.
If you want to construct a string one character at a time, use this:
char buf[20];
char *string = buf;
*string++ = 'A';
*string++ = 'B';
*string++ = 'C';
*string = '\0'; // set the null terminator
printf("%s\n", buf);
Conversely, you can use strcat with string literals:
char string[20] = "";
strcat(string, "A");
strcat(string, "B");
strcat(string, "C");
printf("%s\n", string);
It just prints an empty line.
You are unfortunate, but not surprisingly so, that your code's undefined behavior manifests as printing an apparently-empty string. It would have been more indicative of the nature of the problem if it threw a segfault, or some other variety of memory-related violation, as would be entirely appropriate.
Why does it do this
Because you are performing arithmetic on the pointer, not modifying the thing to which it points. This expression ...
string += 'A';
... computes the pointer addition of string with the integer character constant 'A' (whose numeric value is system dependent, but is often the ASCII code for capital letter A), and stores the resulting pointer in string. This makes string point to something different than it previously did. It does not in any way modify the contents of the memory to which string pointed.
and is there an easy
way to concatenate single characters starting from an empty string if
I don't know how long it'll be?
If you have an upper bound on how long the data can be, then the easiest thing to do is declare a large-enough array to contain the data and initialize it to all-zero ...
char string[MAX_LEN + 1] = {0};
You can then add a single character by by writing it to the next available index (which index you may either track, or compute at need via strlen()):
unsigned next_index = 0;
string[next_index++] = 'A';
string[next_index++] = 'B';
string[next_index++] = 'C';
Note that this relies on the zero-initialization -- which is not automatic for local variables -- to ensure that the array contents at all times comprise a null-terminated string. Having done that, you can print the expected result:
printf("%s\n", string);
If you did not know in advance a reasonable upper bound on how long the string may be, or if the upper bound were exceedingly large, then you would need to relying on dynamic memory allocation and reallocation. This is a subject for you to defer until later.

C setting string equal to substring

In C, If I have:
char *reg = "[R5]";
and I want
char *reg_alt = "R5" (equal to the same thing, but without the brackets), how do I do this?
I tried
*char reg_alt = reg[1:2];
but this doesn't work.
There is no built-in syntax for dealing with substrings like that, so you need to copy the content manually:
char res[3];
memcpy(res, &reg[1], 2);
res[2] = '\0';
I suggest you need to read a basic text on C, rather than assuming techniques from other languages will just work.
First, char *reg = "[R5]"; is not a string. It is a pointer, that is initialised to point to (i.e. its value is the address of) the first character of a string literal ("[R5]").
Second, reg_alt is also a pointer, not a string. Assigning to it will contain an address of something. Strings are not first class citizens in C, so the assignment operator doesn't work with them.
Third, 1:2 does not specify a range - it is actually more invalid syntax. Yes, I know other languages do. But not C. Hence my comment that you cannot assume C will allow things it the way that other languages do.
If you want to obtain a substring from another string, there are various ways. For example;
char substring[3];
const char *reg = "[R5]"; /* const since the string literal should not be modified */
strncpy(substring, &reg[1], 2); /* copy 2 characters, starting at reg[1], to substring */
substring[2] = '\0'; /* terminate substring */
printf("%s\n", substring);
strncpy() is declared in standard header <string.h>. The termination of the substring is needed, since printf() %s format looks for a zero character to mark the end.
When using null-terminated strings (the default in C), you can indeed cheaply create a substring of another string by simply changing the starting character pointer, but you cannot make the new substring have a different null-terminator.
An option is to use a Pascal-string library. Pascal-strings are length-prefixed instead of C-strings which are null-terminated, which means Pascal-strings can share contents of a larger string buffer and substring generation is cheap (O(1)-cheap). A Pascal string looks like this:
struct PString {
size_t length;
char* start;
}
PString substring(const PString* source, size_t offset, size_t length) {
// Using C99 Designated Initializer syntax:
return PString { .length = length, .start = source.start + offset };
}
The downside is that most of the C library and platform libraries use null-terminated strings and unless your Pascal-string ends in a null character you'll need to copy the substring to a new buffer (in O(n) time).
Of course, if you're feeling dangerous (and using mutable character buffers) then you can hack it to temporarily insert a null-terminator, like so:
struct CStr {
char* start;
char* end;
char temp;
}
CStr getCStr(PString* source) {
char* terminator = (source.start + source.length);
char previous = *terminator;
*terminator = '\0';
return CStr { .start = source.start, .end = terminator, .temp = previous };
}
void undoGetCStr(CStr cstr) {
*cstr.end = cstr.temp;
}
Used like so:
PString somePascalString = doSomethingWithPascalStrings();
CStr temp = getCStr( somePascalString );
printf("My Pascal string: %s", temp.start ); // using a function that expects a C-string
undoGetCStr( temp );
...which then gives you O(1) PString-to-CString performance, provided you don't care about thread-safety.
Need to be a char?
Because that only work when is a "string"
So maybe you need this
char reg[] = "[R5]";
Then you can do the other thing
or just split the string like this question

pointer from integer without a cast (C programming) - simple error

char str1[20] = "Something";
char *str2 = "Random";
strcat(str1, str2[1]);
It gives the error pointer from integer without a cast
why is str2[1] treated as an integer?
so what should I do if I want to strcat individual elements in a string
Thanks!
Because an element from a char array is a char, which is an integral type. If you want a pointer to the second element, try str2 + 1 or &str2[1].
With str2[1] the 2nd character is meant (starting at index 0), which is the 'a' in 'Random'.
If you want the complete string you need to write str2 instead of str2[1].
strcat is expecting pointers to chars, but str2[1] is a char value,
modify it to be &str2[1] to get back a pointer to the second char in str2.
str2[1] is of type char while in the strcat(), a char * is expected. Here you should have used str2 + 1.
str2[1] is a char which is promoted to an int according to C type promotion rules. If you want to append a single character to a string, try the following:
int len = strlen(str1);
str1[len] = str2[1];
str1[len + 1] = '\0';
In other words, strlen only concatenates two strings, not a string and a character.

C -> sizeof string is always 8

#include "usefunc.h" //don't worry about this -> lib I wrote
int main()
{
int i;
string given[4000], longest = "a"; //declared new typdef. equivalent to 2D char array
given[0] = "a";
printf("Please enter words separated by RETs...\n");
for (i = 1; i < 4000 && !StringEqual(given[i-1], "end"); i++)
{
given[i] = GetLine();
/*
if (sizeof(given[i]) > sizeof(longest))
{
longest = given[i];
}
*/
printf("%lu\n", sizeof(given[i])); //this ALWAYS RETURNS EIGHT!!!
}
printf("%s", longest);
}
Why does it always return 8???
There is no string data type in C. Is this C++? Or is string a typedef?
Assuming string is a typedef for char *, what you probably want is strlen, not sizeof. The 8 that you are getting with sizeof is actually the size of the pointer (to the first character in the string).
It is treating it as a pointer, the sizeof a pointer is obviously 8bytes = 64 bits on your machine
You say "don't worry about this -> lib i wrote" but this is the critical piece of information, as it defines string. Presumably string is char* and the size of that on your machine is 8. Thus, sizeof(given[i]) is 8 because given [i] is a string. Perhaps you want strlen rather than sizeof.
This is common mistake between the array of characters itself, and the pointer to where that array starts.
For instance the C-style string literal:
char hello[14] = "Hello, World!";
Is 14 bytes (13 for the message, and 1 for the null terminating character).
You can use sizeof() to determine the size of a raw C-style string.
However, if we create a pointer to that string:
char* strptr = hello;
And attempt to find it's size with sizeof(), it will only always return the size of a data pointer on your system.
So, in other words, when you try to get the size of the string from a string library, you're truly only getting the size of the pointer to the start of that string. What you need to use is the strlen() function, which returns the size of the string in characters:
sizeof(strptr); //usually 4 or 8 bytes
strlen(strptr); //going to be 14 bytes
Hope this clears things up!

Resources