Why a dynamically allocated char cannot be outputted? - c++

With reference to this thread: What's the difference between new char[10] and new char(10)
I've this code snippet:
char *temp1 = new char(10);
printf("%s", temp1);
std::cout<< "tmp is" << temp1 << std::endl;
It dynamically allocates a single char initialized with an integer value of 10 and prints its value.
Why the code didn't output anything?
thk U all guys, I finally figure it out.

A single char is not a string, and a pointer to a single char is not a string. Then you have the extra complication that 10 is the ASCII code for \n so you wouldn't be able to see anything even if your code was correct.
This code works, although it's not a good idea to mix C I/O and C++ I/O.
char *temp1 = new char(65); // ASCII for 'A'
printf("%c", *temp1);
std::cout<< "tmp is" << *temp1 << std::endl;

Related

Are std::string with null-character possible?

I initialized a C++ string with a string literal and replaced a char with NULL.
When printed with cout << the full string is printed and the NULL char prints as blank.
When printed as c_str the string print stop at the NULL char as expected.
I'm a little confused. Does the action came from cout? or string?
int main(){
std::string a("ab0cd");
a[2] = '\0'; // '\0' is null char
std::cout << a << std::endl; // abcd
std::cout << a.c_str() << std::endl; // ab
}
Test it online.
I'm not sure whether the environment is related, anyway, I work with VSCode in Windows 10
First you can narrow down your program to the following:
#include <iostream>
#include <string>
int main(){
std::string a("ab0cd");
a[2] = '\0'; // replace '0' with '\0' (same result as NULL, just cleaner)
std::cout << a << "->" << a.c_str();
}
This prints
abcd->ab
That's because the length of a std::string is known. So it will print all of it's characters and not stop when encountering the null-character. The null-character '\0' (which is equivalent to the value of NULL [both have a value of 0, with different types]), is not printable, so you see only 4 characters. (But this depends on the terminal you use, some might print a placeholder instead)
A const char* represents (usually) a null-terminated string. So when printing a const char* it's length is not known and characters are printed until a null-character is encountered.
Contrary to what you seem to think, C++ string are not null terminated.
The difference in behavior came from the << operator overloads.
This code:
cout << a.c_str(); // a.c_str() is char*
As explained here, use the << overloads that came with cout, it print a char array C style and stop at the first null char. (the char array should be null terminated).
This code:
cout << a; // a is string
As explained here, use the << overloads that came with string, it print a string object that internally known is length and accept null char.
string end limit (boundary) is not 0 (NULL) like simple char* but its size keep internally in its member data as it's actually user-defined type (an instantiated object) as opposed to primitive type, so
int main(){
string a("abc0d");
a[3] = 0; // '\0' is null char
a.resize(2);
std::cout << a << std::endl; // ab
std::cout << a.c_str() << std::endl; // ab
}
i'm sorry change your code to be more comfortable, watch as it results in
ab
ab
good learning: http://www.cplusplus.com/reference/string/string/find/index.html

When creating a char array, its length is different from required

I need to create a newStr array with length of str array. But after its created the strlen(newStr) is totally different. For example if a strlen(str) is 5, then strlen(newStr) would be 22. What am I doing wrong?
#include <iostream>
using namespace std;
int main()
{
char *str = "Hello";
int strLength = strlen(str);
std::cout << "str = " << str << "\t" << "strLength = " << strLength << std::endl;
char *newStr = new char[strLength];
std::cout << "newStrLength = " << strlen(newStr) << std::endl;
system("pause");
return 0;
}
In the console will be
str = Hello strLength = 5
newStrLength = 22
You are mixing up two different concepts:
new[] allocates uninitialized memory block to your program,
strlen(...) counts characters in a C string before null terminator '\0' is reached.
The size of the allocated block cannot be measured with strlen. In fact, it cannot be measured at all - your program must know how much memory it has requested, and make sure that it does not go past the limit.
Once you allocated new char[n], you can safely copy a C string of length up to n-1 into that block. C++ guarantees that enough memory would be there for you to complete the operation successfully:
char *newStr = new char[strLength+1]; // Note +1 for null terminator
strcpy(newStr, str);
std::cout << "newStrLength = " << strlen(newStr) << std::endl;
delete[] newStr;
The way strlen works is that it examines the contents of the string passed to it, and counts how many characters there are until the first terminating character. The terminating character for a string is '\0' (or 0).
What you've done is asked for the length of a string that you've not assigned any value to; leading to strlen examining random memory; looking for the first 0. In this case, it found it 22 bytes further down; but it could be anything. It could even crash because you start looking into memory you don't have read access to.
The best way to resolve this is to use std::string and then you can call length and other helper functions without having to worry about the underlying pointers too much; which will also resolve your memory leak.

Printing out the value of pointer to the first index of an char array

I'm new to C++ and is trying to learn the concept of pointer. When I tried to print out the value of pStart, I was expecting its value to be the address of text[0] in hexdecimal (e.g. something like 0x7fff509c5a88). However, the actual value printed out is abcdef.
Could someone explain it to me why this is the case? What parts am I missing?
char text[] = "abcdef";
char *pStart = &text[0];
cout << "value of pStart: " << pStart << endl;
Iostreams provide an overload that assumes a pointer to char points to a NUL-terminated (C-style) string, and prints out the string it points to.
To get the address itself to print out, cast it to a pointer to void instead:
cout << "value of pStsart: " << (void *)pStart << "\n";
Note that you don't really need pStart here at all though. The name of an array (usually, including this case) evaluates to the address of the beginning of the array, so you can just print it directly:
cout << "address of text: " << (void *)text << "\n";
Get out of the habit of using endl as well. It does things you almost certainly don't realize and almost never want.

how to print char array in c++

how can i print a char array such i initialize and then concatenate to another char array? Please see code below
int main () {
char dest[1020];
char source[7]="baby";
cout <<"source: " <<source <<endl;
cout <<"return value: "<<strcat(dest, source) <<endl;
cout << "pointer pass: "<<dest <<endl;
return 0;
}
this is the output
source: baby
return value: v����baby
pointer pass: v����baby
basically i would like to see the output print
source: baby
return value: baby
pointer pass: baby
You haven't initialized dest
char dest[1020] = ""; //should fix it
You were just lucky that it so happened that the 6th (random) value in dest was 0. If it was the 1000th character, your return value would be much longer. If it were greater than 1024 then you'd get undefined behavior.
Strings as char arrays must be delimited with 0. Otherwise there's no telling where they end. You could alternatively say that the string ends at its zeroth character by explicitly setting it to 0;
char dest[1020];
dest[0] = 0;
Or you could initialize your whole array with 0's
char dest[1024] = {};
And since your question is tagged C++ I cannot but note that in C++ we use std::strings which save you from a lot of headache. Operator + can be used to concatenate two std::strings
Don't use char[]. If you write:
std::string dest;
std::string source( "baby" )
// ...
dest += source;
, you'll have no problems. (In fact, your problem is due to the fact
that strcat requires a '\0' terminated string as its first argument,
and you're giving it random data. Which is undefined behavior.)
your dest array isn't initialized. so strcat tries to append source to the end of dest wich is determined by a trailing '\0' character, but it's undefined where an uninitialized array might end... (if it does at all...)
so you end up printing more or less random characters until accidentially a '\0' character occurs...
Try this
#include <iostream>
using namespace std;
int main()
{
char dest[1020];
memset (dest, 0, sizeof(dest));
char source[7] = "baby";
cout << "Source: " << source << endl;
cout << "return value: " << strcat_s(dest, source) << endl;
cout << "pointer pass: " << dest << endl;
getchar();
return 0;
}
Did using VS 2010 Express.
clear memory using memset as soon as you declare dest, it's more secure. Also if you are using VC++, use strcat_s() instead of strcat().

strpbrk doesn't work

char operators[] = "+-*/^(";
char* input = new char[100];
char* output = new char[100];
char* operadores = new char[100];
char* pch = input;
char* pch2 = input;
cout << "Expresion: " <<endl; cin.getline(input,100);
cout << input <<endl;
pch2 = strpbrk (pch2, operators);
pch = strtok (pch, "+-*/^(");
while (pch != NULL){
strcat (output, pch);
pch = strtok (NULL, "+-*/^(");
strcat (operadores, pch2);
}
cout << "Salida: " << output <<endl;
cout << "Operadores: " << operadores <<endl;
cout << "Entrada: " << input <<endl;
cout << "pch2 = " << pch2 <<endl;
Hi! my problem is that the function strpbrk doesnt work, it doesn't return NULL, I've proved it. But I need a char to put in a stack, and cout doesn't show me what character is pointed by pch2.
You are confusing yourself - the program is designed to confuse.
You have both pch and pch2 pointing at the same input string - input. You call strpbrk() to find one of the operators, saving that position in pch2. You then call strtok() on pch, and it finds the character that strpbrk() just found, and writes a NUL '\0' over it. So, it appears that pch2 points to the NUL at the end of a string. In the body of the loop, you then concatenate the empty string that pch2 points to onto your target list of operators.
Personally, I avoid using strtok() precisely because it mangles the input string. If you are going to use it, you are likely to need to work on a duplicate of the string, because strtok() writes NUL bytes over it.
Your diagnostic output at the end should show that the first section of the input - up to the first operator - only.
Beware of casting aspersions at standard library functions or compilers 'not working'. It is the mark of a tyro; 99.9999% of the time, it is a user error and not a system error. On those very, very, very rare occasions when you're correct (ooh, look - I've just won my third multi-million lottery prize; that's more likely, even though I don't buy lottery tickets), the way that you describe the problem is different. You describe the issue as one of utter astonishment; you document the working test cases; then you explain how the edge case you've found should work and the result - and you still aren't sure whether it is a bug in your code or in the system.
As others diagnosed, you do not initialize operadores to an empty string, so concatenating to it leads to undefined behaviour.
There's really no need to allocate the 100-byte strings:
char input[100]; // Cleaner, simpler, more reliable