In addition to Will Dean's version, the following are common for whole buffer initialization:
Copychar s[10] = {'\0'};
or
Copychar s[10];
memset(s, '\0', sizeof(s));
or
Copychar s[10];
strncpy(s, "", sizeof(s));
Answer from Matt Joiner on Stack OverflowIn addition to Will Dean's version, the following are common for whole buffer initialization:
Copychar s[10] = {'\0'};
or
Copychar s[10];
memset(s, '\0', sizeof(s));
or
Copychar s[10];
strncpy(s, "", sizeof(s));
You want to set the first character of the string to zero, like this:
Copychar myString[10];
myString[0] = '\0';
(Or myString[0] = 0;)
Or, actually, on initialisation, you can do:
Copychar myString[10] = "";
But that's not a general way to set a string to zero length once it's been defined.
It depends on what you mean by "empty". If you just want a zero-length string, then your example will work.
This will also work:
buffer[0] = '\0';
If you want to zero the entire contents of the string, you can do it this way:
memset(buffer,0,strlen(buffer));
but this will only work for zeroing up to the first NULL character.
If the string is a static array, you can use:
memset(buffer,0,sizeof(buffer));
Two other ways are strcpy(str, ""); and string[0] = 0
To really delete the Variable contents (in case you have dirty code which is not working properly with the snippets above :P ) use a loop like in the example below.
#include <string.h>
...
int i=0;
for(i=0;i<strlen(string);i++)
{
string[i] = 0;
}
In case you want to clear a dynamic allocated array of chars from the beginning, you may either use a combination of malloc() and memset() or - and this is way faster - calloc() which does the same thing as malloc but initializing the whole array with Null.
At last i want you to have your runtime in mind. All the way more, if you're handling huge arrays (6 digits and above) you should try to set the first value to Null instead of running memset() through the whole String.
It may look dirtier at first, but is way faster. You just need to pay more attention on your code ;)
I hope this was useful for anybody ;)
Videos
Since C-style strings are always terminated with the null character (\0), you can check whether the string is empty by writing
do {
...
} while (url[0] != '\0');
Alternatively, you could use the strcmp function, which is overkill but might be easier to read:
do {
...
} while (strcmp(url, ""));
Note that strcmp returns a nonzero value if the strings are different and 0 if they're the same, so this loop continues to loop until the string is empty.
Hope this helps!
If you want to check if a string is empty:
if (str[0] == '\0')
{
// your code here
}
Define a buffer to hold the string contents:
#define BUFFER_SIZE 256 // or whatever size you need
char buffer[BUFFER_SIZE+1] = {0}; // +1 for string terminator,
// = {0} initializer zeroes out entire buffer
To assign a string to this buffer, use strcpy:
strcpy( buffer, "some string" );
To append a string to this buffer, use strcat:
strcat( buffer, "more string" );
EDIT
Now that you've edited your question, the problem is the line
tempo = "";
An array expression like tempo may not be the target of the = operator; you must use a library function like strcpy to assign string values. If you want to set tempo to an empty string, you can do any one of the following:
strcpy( tempo, "" );
or
tempo[0] = 0;
or
tempo[0] = '\0';
In C you have to create a temporary buffer all the time. The most typical way to do this is to write a line of code like this:
char temp_buffer[256];
This buffer will have 256 characters of space available to be able to put strings in.
Short Answer:
const char *get_string() { return ""; }
or
char *get_string() { return const_cast<char *>(""); }
or
char *get_string() { return NULL; }
or
std::string get_string() { return std::string(); }
Detailed Answer:
Implicit conversion from string literal to char * is supported in C and C++98/C++03, but apparently not in C++11. The deprecation warning is just there to let you know that this should be addressed, particularly if you want to be able to migrate your code C++11.
The empty string literal ("") is not actually empty, it is a string containing a single null character (\0). When you use return "";, you are actually returning a pointer to the memory location of the const string literal so the function return type should be const char *.
If you really must return a non-const pointer to a string literal, you can use the const_cast operator to cast away the const.
A better practice would be to return NULL (or nullptr) for functions that are returning empty, non-const, C-style strings, but only if the calling code is checking for NULL pointers.
Note that C++ has its own string type (std::string), and an even better practice would be to use this rather than a C-style string when possible.
char* foo()
{
static char empty[1];
return empty;
}
Just be aware that this function is absolutely stupid, and whatever your actual problem is, this is not likely the correct solution. But, since you refuse to expound upon your actual problem, here you go.
A couple of ways come to mind. Given that strings in C are usually terminated by an ASCII zero, the easiest would be to set the first byte to zero.
a[0] = '\0';
Now this doesn't erase all the characters in the string, but since the first character is now a termination character the string looks empty to your program.
If you want to erase all the characters in the string then you need to use a loop.
OR
Another way might be to use memset() to set the whole string to zeros.
memset(a, 0, strlen(a));
but this will only work for zeroing up to the first NULL character.
In your case, it should suffice to do:
a[0] = '\0';
This sets the first char in the string to be the null terminating character, such that when you print the string, it prints an empty string.
You should also assign the null terminating character to after the effective last character:
a[0] = 'a';
a[1] = 'b';
a[2] = '\0';
printf("%s", a); //print "ab"
The easy way to do it would be like this:
if (msg[0])
printf("message: %s", msg);
If, at some later date, msg is a pointer, you would first want to assure it's not a NULL pointer.
if (msg && msg[0])
printf("message: %s", msg);
A test program to demonstrate:
#include <stdio.h>
#include <stdlib.h>
char *msg;
void test() {
if (msg && msg[0])
printf("string is %s\n", msg);
}
int main()
{
msg = NULL;
test();
msg = calloc(10, 1);
test();
msg[0] = 'm';
msg[1] = 'e';
test();
free(msg);
}
On my machine the output is:
string is me
Strings in C are represented as character arrays, terminated by a character whose value is zero (often written as '\0'). The length of a string is the number of characters that come before the zero.
So, a string is empty if the first character in the array is zero, since then by definition no characters came before the zero.
This can be checked like so:
if(msg[0] != '\0')
{
/* string isn't empty! */
}
This is very explicit code, the shorter if(msg[0]) or if(*msg) has the exact same semantics but can be slightly harder to read. It's mostly a matter of personal style.
Note though that in your case, when you use scanf() to read into msg, you should check the return value from scanf() before checking the contents of msg. It's perfectly possible for scanf() to fail, and then you can't rely on msg being set to an empty string.
That is perfectly well defined and the assertion passes. The c_str() function will always return a valid zero terminated C string.
One would normally use empty() to test for an empty string.
Yes it will work (if you append () to c_str to make it actually call the function) and the assertion will pass.
In C a string is an array of char and the end of the string is marked with a NUL character (aka '\0') which is nothing else than a byte of value 0.
If you want to have an empty string it is sufficient to do
temp[0] = '\0';
or
*temp = '\0';
which is the same.
If you defined something like
char temp[100];
you could also do
memset(temp, '\0', sizeof temp);
This will overwrite all characters, allowing you to fill in new data character by character without having to care about the terminating '\0'.
With dynamic allocation the answer will be different.
It depends a bit on how you want to assign a new value to temp, but in general it is not necessary to clear the old value before assigning a new value.
In C, a string is a sequence of consecutive char variables that is terminated by the representation of zero as a character, '\0'.
This value acts as a sentinel for the end of the string and allows the idiomatic "string processing" loop below:
char *p = <some string>;
while(*p)
{
dosomething(*p);
p++;
}
Library functions that process strings (i.e. strlen, strcpy, strcat, etc.) use a construct similar to the code above, and when you write your own code that processes arbitrary strings, you will find the null character check useful; even if a string is stored in a char [] array of known length, it decays to a pointer to its first element when passed to a function, losing information about its length.
So, if you want to blank the string, all that is needed is to set the first element of the string to '\0'. If the first value in the string is the null terminator, the condition *p is false and the loop is never entered:
char *p = "\0someotherstuff";
printf("%zu\n", strlen(p));
// Output: 0
Arrays in C must have their size known when they are created, and the size cannot be changed after that.
So you must specify a size for all of your arrays.
You can omit the size number only if you provide an initializer, because the compiler can calculate the size from the initializer.
In your code you should select a size that is large enough to store what you expect. Also you used the wrong arguments to scanf. The code could be:
char first[100] = { 0 }; // avoid garbage in case input fails
scanf("%99s", first);
If you want to allow input of arbitrary size then you have to use dynamic allocation of space.
In order for first and last to be usable in your context they need to have a complete type, that is a type whose size is known at compile time.
Thus you can either manually specify the array dimension (first[20]), or let the compiler deduce the dimension from an initialiser expression (like you did with prompt1 etc).
If you don't want to specify a dimension at compile time, then you need to switch to dynamically allocated memory using malloc and friends.
Note that you should also protect yourself from buffer overflows: scanf as used in your code will read an unknown amount of chars into the buffer you provide, making an overflow possible. See here for a discussion on how to avoid that.
You're right: since calling strcmp() adds up the stack management and the memory jump to the actual strcmp instructions, you'll gain a few instructions by just checking the first byte of your string.
For your curiosity, you can check the strcmp() code here: http://sourceware.org/git/?p=glibc.git;a=blob;f=string/strcmp.c;h=bd53c05c6e21130b091bd75c3fc93872dd71fe4b;hb=HEAD
(I thought the code would be filled with #ifdef and obscure __GNUSOMETHING, but it's actually rather simple!)
strcmp() is a function call and thus has a function call overhead. foo[0] is direct access to the array, so it's obviously faster.
nul pad the string then wen reading out the result skip the nuls
char string[x*y+1]; // you had it too small
...
fgets(string, x*y+1, stdin); //immediatly as \n is still there)
int num_read = strlen(string);
if(num_read < x*y+1 )
memset(string+num_read,'\0',x*y+1-num_read);
if (string[num_read ] == '\n' )
string[num_read ] = '\0';
...
char message[x*y+1]; // was way too small!
for(int j=0; j < x; j++){
for(int i=0; i < y; i++){
if(code[i][j])
message[k] = code[i][j];
k++;
}
}
message[k]='\0'
You have two problems
You need to initialize all the bytes in the
stringvariable, instead of doing with theforloop, you can add this before thefgetsmemset(string, ' ', x * y);so now all bytes in the string are spaces then you can remove the trailing
'\n'and change the terminating'\0'with a space, after thefgetswithsize_t length; length = strlen(string); if (string[length - 1] == '\n') string[length - 1] = ' '; string[length] = ' ';You need to add a terminating
'\0'to themessagevariable, in the loop where you fillmessageyou appendmessage[k] = '\0';after the loop terminatesk = 0; char message[128]; for(int j=0; j < x; j++){ for(int i=0; i < y; i++){ message[k] = code[i][j]; k++; } } message[k] = '\0';
Use whatever you and your team find the most readable.
Other answers have suggested that a new string is created every time you use "". This is not true - due to string interning, it will be created either once per assembly or once per AppDomain (or possibly once for the whole process - not sure on that front). This difference is negligible - massively, massively insignificant.
Which you find more readable is a different matter, however. It's subjective and will vary from person to person - so I suggest you find out what most people on your team like, and all go with that for consistency. Personally I find "" easier to read.
The argument that "" and " " are easily mistaken for each other doesn't really wash with me. Unless you're using a proportional font (and I haven't worked with any developers who do) it's pretty easy to tell the difference.
There really is no difference from a performance and code generated standpoint. In performance testing, they went back and forth between which one was faster vs the other, and only by milliseconds.
In looking at the behind the scenes code, you really don't see any difference either. The only difference is in the IL, which string.Empty use the opcode ldsfld
and "" uses the opcode ldstr, but that is only because string.Empty is static, and both instructions do the same thing.
If you look at the assembly that is produced, it is exactly the same.
C# Code
private void Test1()
{
string test1 = string.Empty;
string test11 = test1;
}
private void Test2()
{
string test2 = "";
string test22 = test2;
}
IL Code
.method private hidebysig instance void
Test1() cil managed
{
// Code size 10 (0xa)
.maxstack 1
.locals init ([0] string test1,
[1] string test11)
IL_0000: nop
IL_0001: ldsfld string [mscorlib]System.String::Empty
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: stloc.1
IL_0009: ret
} // end of method Form1::Test1
.method private hidebysig instance void
Test2() cil managed
{
// Code size 10 (0xa)
.maxstack 1
.locals init ([0] string test2,
[1] string test22)
IL_0000: nop
IL_0001: ldstr ""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: stloc.1
IL_0009: ret
} // end of method Form1::Test2
Assembly code
string test1 = string.Empty;
0000003a mov eax,dword ptr ds:[022A102Ch]
0000003f mov dword ptr [ebp-40h],eax
string test11 = test1;
00000042 mov eax,dword ptr [ebp-40h]
00000045 mov dword ptr [ebp-44h],eax
string test2 = "";
0000003a mov eax,dword ptr ds:[022A202Ch]
00000040 mov dword ptr [ebp-40h],eax
string test22 = test2;
00000043 mov eax,dword ptr [ebp-40h]
00000046 mov dword ptr [ebp-44h],eax
It's implementation defined. §5.1.2.2.1 abridged:
If the value of
argcis greater than zero, the array membersargv[0]throughargv[argc-1]inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. [...]If the value of
argcis greater than zero, the string pointed to byargv[0]represents the program name;argv[0][0]shall be the null character if the program name is not available from the host environment. [...]
So if argc is greater than zero, it's quite the intention that argv[0] never be an empty string, but it could happen. (Note that with argc equal to n, argv[0] through argv[n - 1] are never null and always point to a string. The string itself may be empty, though. If n is zero, argv[0] is null.)
In practice, of course, you just need to make sure the platforms your targetting behave as needed.
Yes.
The C language standard explicitly allows for the possibility that argv[0] can be a null pointer, or that it can point to an empty string (""). N1256 5.1.2.2.1p2:
The value of argc shall be nonnegative.
argv[argc] shall be a null pointer.
[...]
If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters.
On Unix-like systems, programs are invoked by one of the exec() family of functions (execl(), execlp(), etc.), which allow the caller to specify exactly what arguments are passed to the main() function. (It's even possible to invoke a program in ways that violate the requirements imposed by the C standard.)
Note that the standard says that argv[0] (assuming it's neither null nor empty) "represents the program name". The standard is deliberately vague about how it represents the program name. In particular, it needn't provide a name by which the program can be invoked (since the standard doesn't even require that programs can be invoked by name).
Using fgets is pretty simple. As a feature, you can test to see it the input contains a newline. If not, there are pending characters.
scanf is possible using a scanset. %99[^\n] will scan up to 99 characters that are not a newline. %*c will consume the newline. If the only character is a newline then the scanset will fail and scanf will return 0. If more than 99 characters are entered, %*c will consume a character that is not a newline. fgets does not have that problem.
#include <stdio.h>
int main ( void) {
char string[100] = "";
int result = 0;
printf ( "using fgets\nenter a blank line to stop\n");
do {
fgets ( string, sizeof string, stdin);
} while ( string[0] != '\n');
printf ( "using scanf\nenter a blank line to stop\n");
do {
result = scanf ( "%99[^\n]%*c", string);
} while ( result == 1);
return 0;
}
With ungetc, if scanf reads too many characters, the last character can be put back in the stream if it is not a newline.
char last = 0;
do {
result = scanf ( "%99[^\n]%c", string, &last);
if ( EOF == result) {
fprintf ( stderr, "scanf EOF\n");
return 0;
}
if ( '\n' != last) {
ungetc ( last, stdin);
}
} while ( result == 2);
You can use strcmp function to check whether the input is empty or not:
char str[50];
while(strcmp(gets(str), "") != 0){
printf("Output: %s\n", str);
}
strcmp function returns 0 when both strings are found to be identical.
You can use c[i]= '\0' or simply c[i] = (char) 0.
The null/empty char is simply a value of zero, but can also be represented as a character with an escaped zero.
You can't store "no character" in a character - it doesn't make sense.
As an alternative you could store a character that has a special meaning to you - e.g. null char '\0' - and treat this specially.