When does a char* ends with null in c? - c

I have confusion on char* null-termination so i have decided to make a study of cases i can find. Do these string literals end with a null?
char str1[512]="This is a random string"
char *str2 = strtok(buffer,"\n,") I have found its answer. This ends with null.
fgets(stdin, str3, 512)
scanf("%s",str4)
The code snippet:
char str[5];
for(int i=0; i<5; i++) scanf("%c",&str[i]);
Note 1: I have an assumption that all standard functions in c library that returns a char*, null terminates the string.
Note 2: How do I check if a string is null terminated or not? (I tried this approach but it prints random stuffs imo.)
Edit: Just showing me a way to determine whether a string literal is null-terminated will be enough. I will go through each case and update here for future readers.

Such an example is by no means exhaustive, but it brings some clarity. The answer is actually simple. Any array of characters ending in '\0' is called a string. The programmer independently decides what he needs .
#include<stdio.h>
int main(void)
{
char w[]="mamamia";
int i;
for(i=0;i<sizeof(w);i++)
{
if(w[i]=='\0')
printf("w[%d]==null\n",i);
else
printf("w[%d]== %c \n",i,w[i]);
}
return 0;
}

Related

Char array in C yields extra characters than required [duplicate]

This question already has an answer here:
What are null-terminated strings?
(1 answer)
Closed 7 months ago.
I have this simple program in which I initialize a string with "HELLO". I need the output to be printed as HLOEL, i.e) all the even indexes (0,2,4) followed by the odd ones (1,2). I could not infer what's wrong with my code, but it yields "HLOELHLO" instead of "HLOEL". Could someone explain what is happening here?
#include <stdio.h>
int main() {
int i,loPos=0,hiPos=0;
char *str="HELLO";
char lo[2];
char hi[3];
for(i=0;i<5;i++)
{
if(i%2==0)
{
hi[hiPos++]=str[i];
}
else
{
lo[loPos++]=str[i];
}
}
printf("%s%s",hi,lo);
return 0;
}
Thanks in Advance!
After the for loop, you need to put string terminating 0 bytes to the new strings, and also make sure they habe room for it:
char lo[2+1];
char hi[3+1];
for(...) {
}
hi[hiPos] = '\0';
Lo[loPos] = '\0';
Otherwise any string functions will have buffer overflow, causing undefined behavior. Generally they will keep reading bytes until by chance they encounter byte with value 0. But as always with undefined behavior, even this can cause your program to do anything.
because C style string need extra one char '\0' as its end. With your code,
the memory layout around two arrays maybe looks like:
lo[0], lo[1], hi[0], hi[1], hi[2], something else equal 0,
printf stops when it meets a '\0'
you should declare arrays as:
char lo[3];
char hi[4];
lo[2] = '\0';
hi[3] = '\0';

Converting string to char* [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
When I try to convert a char[] to char* there are unneeded characters added to the char* variable
int keySize = getKeySize(key2);
char* key = (char*)malloc(sizeof(keySize));
int i;
char s[keySize-1];
int i2;
for(i2=0; i2<keySize; i2++)
{
s[i2] = getCharacter(key2, i2);
}
strncpy(key, s, keySize);
There is no string data type in C programming language. Strings in C are represented as array of characters.
Note: C-Strings are actually character array terminated by '\0' character. That means, last character in any C-String in C will be used to store a '\0' character which marks the end of the string. To store n characters in C-String in C, you should define a character array of size (n+1).
Why should we terminated it by '\0'?
The '\0' termination is what differentiates a char array from a c-string in C programming language. Most string-manipulating functions (like strcpy) relies on '\0' character to know when the string is finished (and its job is done!), and won't work with simple char-array (eg. they'll keep on working past the boundaries of the array, and continue until it finds a '\0' character somewhere in memory - often corrupting memory as it goes).
Therefore, storing a '\0' character (at the end) is necessary if you want to use functions of #include <string.h> like strcpy() as they rely on '\0' character to mark the end of the character array.
'\0' is defined to be a null character - that is a character with all bits set to zero (and thus has a value 0). This has nothing to do with pointers. Read more about it here.
In your program, you want two character arrays key (dynamically allocated) and s to hold a copy of another character array key2 of size keysize. Then, both character arrays should be of atleast keysize + 1 (+1 to hold a '\0' character) size.
Change:
char* key = (char*)malloc(sizeof(keySize));
To:
char* key = malloc(keySize+1); // Don't Type-Cast malloc
And
Change:
char s[keySize-1];
To
char s[keySize+1];
While allocating, you should allocate one more than the size. Currently you are allocating 4 bytes only.
char* key = (char*)malloc(keySize+1);
//instead of
char* key = (char*)malloc(sizeof(keySize));
s should have a size of keySize+1
char s[keySize+1];
// instead of
char s[keySize-1];
What about this?
There are some errors about the dimension of s, I suggest you tu use strncpy
#include <string.h>
int main(){
//bla bla ...
int keySize = getKeySize(key2);
char* key = malloc(keySize+1);;
int i2;
for(i2=0; i2<keySize; i2++){
s[i2] = getCharacter(key2, i2);
}
char s[keySize+1];
strncpy(s, key, sizeof s - 1);
s[keySize] = '\0';
r
return 0;
}
Anyway more information about it please,I supposed you wanted this

unexpected results on simple string reverse algorithm

I'm relatively new to C. I wanted to lern the language a bit by solving coderbyte challenges.
But I'm stucked at the first. It is supposed to be a simple String reverse algorithm.
When I input things like "asdf" or "1234567" the output is correct ("fdsa", "7654321"). But when I type "12345678" or "thisiscool" I get "87654321▒#"/"loocsisiht#" as a result. I don't know where the # are comming from.
This is my code:
#include <stdio.h>
#include <string.h>
void FirstReverse(char str[]) {
int len = strlen(str);
char nstr[len];
int i;
for(i = 0; i < len; i++) {
nstr[i] = *(str+len-1-i);
}
printf("%s\n", nstr);
}
int main(void) {
char str[100];
FirstReverse(gets(str));
return 0;
}
Can someone please tell me where I can find the error?
Thanks in advance :)
In C, strings are zero-terminated. A string "cat", for example, has 4 characters, and is represented as ('c','a','t',(char)0). You forgot about the final 0.
Note that strlen returns the string length without the final 0, so a string foo contains strlen(foo)+1 characters. Remember this when you allocate strings.
As the other answers have mentioned, you're missing a terminator.
It should also be noted that it's bad practice to allocate strings the way you did. An array should always have a fixed size if you create it that way.
You should instead do:
char * nstr = malloc(sizeof(char) * (len+1));
Thereby allocating the size of each character (1 byte) times the lenght.
Note the +1 because you need room for the string terminator.
When you call printf(, string); , it's gonna start from the first letter and print everything up to the terminator. Since you have no terminator here, it prints random characters, such as #.
What you're gonna wanna do to fix that, is adding:
nstr[i] = '\0';
after your loop.
Also remember to free the allocated memory.
You forgot to allocate a char for the terminating '\0' in nstr[].
So, better use: char nstr[len + 1]; and set nstr[len] = 0;
Furthermore: gets() is evil: from the glibc manual page:
Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.

why is my printf doing this?

it seems like such a silly thing to ask but i seriously don't know why this is happening. Could be that it's almost 5am and i'm still doing this but..
It should print -CA but why when i compile it, it is printing
-
CA?
instead of -CA, there isn't a '\n' anywhere in sight.
Can you guys think of anything logical that would explain it?
int main(int argc, char* argv[]){
int check = 0;
char *thing = (char*)malloc(2 * sizeof(char));
strcpy(char, "CA");
some code..
do{
more code...
if(condition== 1) {
more code....
if(check == 0) {
printf("-");
check++;
}
if (some conditon != NULL){
printf("%s\n",thing);
}while(condition)
return 0;
}
You didn't allocate enough space for your string. Every string has a null terminator, so a 2-character string needs 3 bytes in the array. Your strcpy() is writing outside the bounds of the thing array when it copies the null byte, which results in undefined behavior.
Use
char *thing = malloc(3);
You can also use strdup(), which makes a copy of a string in dynamic memory, automatically allocating enough space based on the length of the original string.
char *thing = strdup("CA");
printf prints a null terminated string to the stdout. if the sting is not null terminated the printf will go on printing garbage to the stdout till a null terminator is met
so you should all one to your character array
char thing[3] = {'C','A',0};
now printf will print
-
CA

The basics of using strings and substrings in C programming [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I've been trying to learn C programming by reading a textbook, but am confused about how strings and substrings work.
I have an idea of what strings and substrings are from java, but can't figure out the syntax in C.
Here's a question from the book that I thought might be easy, but I can't get it.
Write and test a function hydroxide that returns a 1 for true if its string argument ends in the substring OH.
It recommends testing the function with KOH and NaCl.
Also, how would I remove and add letters at the end of the string?
Like, if for some reason I wanted to change NaCl to NaOH?
Any help and explanations would be really appreciated.
ETA:
I guess what I'm most confused on is how to make the program look at the last two letters in the string and compared them to OH.
I'm also not sure how to pass strings to functions.
String is a sequence of characters that ends with special null-terminated character '\0'. If there is no \0, functions that work with string won't stop until the \0 symbol is found. This character may happen in any place after the end of pseudo string (I mean a string without \0) and only then stop.
The following example shows the necessity of this null-terminated character:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char string[] = "Hello!";
printf("original string:\n%s\n\n", string);
memset(string, '-', 5);
printf("memset doesn't affect the last two symbols: '!' and '\\0':\n%s", string);
memset(string, '-', 6);
printf("\n\nmemset doesn't affect the last symbol: '\\0':\n%s\n\n", string);
memset(string, '-', 7);
printf("memset affects all symbols including null-terminated one:\n%s", string);
return 0;
}
/* OUTPUT:
original string:
Hello!
memset doesn't affect the last two characters: '!' and '\0':
-----!
memset doesn't affect the last character: '\0':
------
memset affects all characters including null-terminated one:
-------#↓#
*/
Substring is a char sequence that is in a string. It may be less or equal to the string.
Suppose, "NaOH" is a string. Then substring may be: "N", "a", "O", "H", "Na", "aO", "OH", "NaO", "aOH", "NaOH". To find whether substring is in the string or not you can use strstr function. It's prototype is char * strstr ( char * str1, const char * str2 );.
This code shows this function's results:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *ptrCh = NULL;
ptrCh = strstr("hello", "h");
printf("ptrCh: %p\n", ptrCh);
printf("%s\n\n", ptrCh);
ptrCh = strstr("hello", "z");
printf("ptrCh: %p\n", ptrCh);
printf("%s\n\n", ptrCh);
return 0;
}
/* OUTPUT:
ptrCh: 00403024
hello
ptrCh: 00000000
(null)
*/
As for the first printf, it prints characters beginning from the position of 'h' and when it reaches null-terminated character, which is next after 'o', it stops, exactly as in previous program.
To make your program more interactive, you can declare array and then a pointer to it. Array size must be enough to store the longest formula. Suppose, 100 will be enough:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char buf[100] = {0};
char *ptr = &buf[0];
scanf("%s", ptr);
// printf() gets a pointer as argument
printf("%s\n", ptr);
// printf() gets also a pointer as argument.
// When you pass arrays name without index to a function,
// you pass a pointer to array's first element.
printf("%s", buf);
return 0;
}
And as for rewriting letters in the end of the string. Here is a small program that does it. Pay attention at comments:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char buf[100] = {0};
char formula[100] = {0};
char compound[100] = {0};
char *ptr = &buf[0];
char *pFormula = &formula[0];
char *pCompound = &compound[0];
printf("Enter formula: ");
scanf("%s", pFormula);
printf("Enter chemical compound: ");
scanf("%s", pCompound);
// Copying the first chemical elements without the last
// several that will be replaced by another elements.
strncpy(ptr, pFormula, strlen(pFormula) - strlen(pCompound));
// Adding new compound to the first elements.
// Function also adds a null-terminated character to the end.
strncat(ptr, pCompound, strlen(pCompound));
printf("The new chemical compound is: ");
printf("%s", ptr);
return 0;
}
/* OUTPUT:
Enter formula: NaOH
Enter chemical compound: Cl
The new chemical compound is: NaCl
*/
In C, we use null-terminated strings. That is the "invisible", 0 value. Not ASCII "0", but the zero value, like 8-bit 0x00. You can represent it in literal text with '\0' or "\0" or unquoted 0, however, in a literal string it is redundant because most functions like strcmp() or strstr() or strcat() all expect and work with null terminated strings. Null char is the stops sign for the C standard string functions.
One easy way to implement this with C library calls is to test for existence of the substring and then test that substring's length, which verify it is at end of string.
Assume buf is some big string buffer, char buf[1024] and char *temp is a temporary variable.
temp = strstr(buf, "OH") returns the pointer to "OH" if exists in buf at any offset.
strlen(temp) Get length of temp, if at end of string, it will be 2 (doesn't include null terminator), so if the original string is "OHIO" or "SOHO" it wont match because it'll be 4 and 3 respectively.
The above is the core of the code, not the full robust implementation. You need to check for valid return values, etc.
char buf[1024];
char *temp;
strcpy(buf, "NaOH");
if((temp = strstr(buf, "OH")) != 0)
{
// At this point we know temp points to something that starts with "OH"
// Now see if it is at the end of the string
if(strlen(temp) == 2)
return true; // For C99 include stdbool.h
return false;
}
You could get obscure, and check for the null terminator directly, will be a smidge quicker. This code is safe as long as it is inside the if() for strstr(), otherwise never do this if you don't know a string is a least N characters long.
if(temp[2] == '\0')
return true; // For C99 include stdbool.h
As far as appending to a string, read the docs on strcat. Keep in mind with strcat, you must have enough space already in the buffer you are appending into. It isn't like C++ std::string or Java/C# string where those will dynamically resize as needed. In C, you get to do all of that yourself.

Resources