why pointer to a string is is giving me blank output - c++

i am running this in vs code.
its just taking input and then it terminates.
the output is blank.
this is the output
///
PS D:\c++\string> cd "d:\c++\string" ; if ($?) { g++ chararray.cpp -o chararray } ; if ($?) { .\chararray }
uu uugg gg
///
heres the code.
#include <iostream>
using namespace std;
int main()
{
char *u;
cin.getline(u, 19);
cout << "well " << u;
}

The local buffer char *u; hasn't been initialized, it may cause a SEGV crash, since calling getline will lead to writing into the address stored in u, and it's a random value now.
It would be better to use the alternative std::getline and std::string as the target string type, then we read an arbitrary length of the string (We void buffer overflow and other kinds of memory issues):
#include <iostream>
int main() {
std::string line;
std::getline(std::cin, line);
std::cout << "well " << line;
return 0;
}

A better way would be to do some allocation of mem before you store some data there.
#include <iostream>
using namespace std;
int main()
{
char *u = new char[20];
// char u[20] = { "\0" }; // with this you do not need to delete the mem
cin.getline(u, 19);
cout << "well " << u;
delete [] u; // do not forget to free your heap memory
}

Related

how to read a const char* from keyboard input and perform strlen() on it?

So I have been trying for 1.30 hour to get this to work. I am new indeed, but I have searched all over the place and couldn't find an exact answer. I do not wish to do this another way, as it would take away the entire purpose of learning to code. I have to find why this thing isn't working. I tried dozens if not hunderds of syntaxes, but nothing works.
I want to read in a const char* name, than count the number of elements in it, so I thought had to be strlen(), and than output the name and the number of elements. If that works I can write the rest of the code.
#include <iostream>
using namespace std;
int main()
{
//writing your name, and counting the characters including \0
int a;
const char* name;
a = int strlen(name);
cin.getline(name);
cout << name;
cout >> a;
return 0;
}
There are a lot of problems with your code.
You are not allocating any memory for cin.getline() to read into. const char* name; is declaring an uninitialized pointer to nothing. You have to allocate memory for name before you can then read any data into it.
cin.getline() expects two input parameters (a pointer to an allocated buffer, and the max number of characters the buffer can hold), but you are only passing in one value.
You are calling strlen() before you have read anything into name (and there is a syntax error on your strlen() statement anyway).
You are passing a to std::cout using >>, but std::ostream does not implement the >> operator. You have to use << instead.
And lastly, don't use using namespace std;.
Try this instead:
#include <iostream>
#include <cstring>
int main()
{
//writing your name, and counting the characters including \0
int a;
char name[32];
std::cin.getline(name, 32);
a = std::strlen(name);
std::cout << "You entered: " << name << std::endl;
std::cout << "It is << a << " chars in length" << std::endl;
return 0;
}
Or, if you really don't like using std:: everywhere, at least use using <identifier>; instead of using namespace std;:
#include <iostream>
#include <cstring>
using std::cin;
using std::strlen;
using std::cout;
using std::endl;
int main()
{
//writing your name, and counting the characters including \0
int a;
char name[32];
cin.getline(name, 32);
a = strlen(name);
cout << "You entered: " << name << endl;
cout << "It is " << a << " chars in length" << endl;
return 0;
}
Now, that being said, the preferred solution is to use std::getline() instead of cin.getline():
#include <iostream>
#include <string>
int main()
{
int a;
std::string name;
std::getline(std::cin, name);
a = name.length();
std::cout << "You entered: " << name << std::endl;
std::cout << "It is " << a << " chars in length" << std::endl;
return 0;
}
I found a working solution, although I don't see where I had gone wrong. But this does exactly what I want using const char* and strlen() without using std::string.
Thanks for all your help, you have all pointed me to the correct direction.
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int main ()
{
const char *name;
int len;
name = "stephane";
len = strlen(name);
cout << name;
cout << len;
return(0);
}
As another user has pointed out, I think it's a good idea for you to take a few steps back and read the basics until you understand how pointers work.
A const char* is that: const. It could be used usually while doing things like this:
const char* cpName = "Stephane"; //expected not to change through the program's lifetime
char* pName = "Stephane"; //can be changed to point to something else
char *pOther = "Vada";
pName = pOther; //pName now points to the string "Vada"
cpName = pOther; //this won't compile as cpName is const

Assign a integer to char pointer using stringstream

I want to assign integer to a char pointer using stringstream. But I am getting error while running this program at line ss >> p. Please help me here i want integer to go into the buffer first and the it must be assigned to a char*.
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
using namespace std;
int main ()
{
stringstream ss;
int n=100;
char *p;
ss << n;
ss >> p; //not working
cout << ss;
return 0;
}
Use stringstream::str to get a C++ string, then use .c_str() on the string:
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
using namespace std;
int main ()
{
stringstream ss;
int n = 100;
char* p;
ss << n;
string tmp = ss.str();
p = const_cast<char*>(tmp.c_str());
cout << "p: " << p << '\n';
return 0;
}
Beware that the char pointer becomes invalid as soon as the string goes out of scope. If you need some kind of factory function behavior, return a string by value, use strlcpy or maybe new and shared_ptr.
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
using namespace std;
int main ()
{
stringstream ss;
int n=100;
char buffer[100];
char *p = buffer;
ss << n;
ss >> p;
cout << p;
return 0;
}
This is fixing only the problem you directly encountered - there's no storage behind p so it will crash. Stylistically there are many other things to improve / fix, but this should show you what part of this was actually wrong.

try to understand the pointers maintained by a string object

Ran a simple program to test the pointer in string object, got
0x1875028
Hello
0x1875058 0x1875028
Hello world!!!
0x1875028
I am trying to understand why would s.c_str() change value after erase() call but not st.c_str().
Here is the simple code:
#include <vector>
#include <unordered_map>
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
string st;
void dum() {
string s("Hello world!!!");
printf("%p\n", s.c_str());
st = s;
s.erase(6);
cout << s << endl;
printf("%p %p\n", s.c_str(), st.c_str());
}
int main(int argc,char *argv[]) {
dum();
cout << st << endl;
st.erase(6);
printf("%p\n", st.c_str());
return 0;
}
This actually depends on the version you're using. See, for example Is std::string refcounted in GCC 4.x / C++11?. When you write for two strings, a, and b
a = b;
Then there's a question of whether they're internally pointing to the same object (up until one of them is modified). So either behavior your program exhibits is not very surprising.
First of all, I think this goes under the implementation details umbrella.
I tried that with VS2013.
After you call erase(), the string pointer returned by c_str() is not changed because I think the internal string implementation just updates the end of string (changing some internal data member), instead of doing a new heap reallocation for the internal string buffer (such an operation would likely return a new pointer value).
This is a behavior that I noted both for your local s string and the global st string.
Note that the STL implementation that comes with VS2013 doesn't use COW (COW seems to be non-standard C++11 compliant), so when you copy the strings with st = s, you are doing a deep copy, so the two strings are completely independent and they point to different memory buffers storing their respective string contents. So, when you erase something from one string, this operation is in no way reflected to the other copied string.
Sample Code
#include <iostream>
#include <string>
using namespace std;
// Helper function to print string's c_str() pointer using cout
inline const void * StringPtr(const string& str)
{
// We need a const void* to make cout print a pointer value;
// since const char* is interpreted as string.
//
// See for example:
// How to simulate printf's %p format when using std::cout?
// http://stackoverflow.com/q/5657123/1629821
//
return static_cast<const void *>(str.c_str());
}
string st;
void f() {
string s{"Hello world!!!"};
cout << "s.c_str() = " << StringPtr(s) << '\n';
st = s;
s.erase(6);
cout << s << '\n';
cout << "s.c_str() = " << StringPtr(s)
<< "; st.c_str() = " << StringPtr(st) << '\n';
}
int main() {
f();
cout << st << endl;
st.erase(6);
cout << "st.c_str() = " << StringPtr(st) << '\n';
}
Output
C:\Temp\CppTests>cl /EHsc /W4 /nologo test.cpp
test.cpp
C:\Temp\CppTests>test.exe
s.c_str() = 0036FE18
Hello
s.c_str() = 0036FE18; st.c_str() = 01009A40
Hello world!!!
st.c_str() = 01009A40

Cannot push C style strings into std::vector

I'm trying to push some const char* into a vector, but the vector remains unpopulated after performing the operations I would presume to fill it.
Here's my attempt, where dict is my command-line argument.
test.cc
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main(int argc, char **argv)
{
ifstream dict;
size_t dict_size;
dict.open(argv[1]); // Dictionary
vector<const char*> dictionary;
string line;
getline(dict, line);
while(!dict.fail()) {
dictionary.push_back(line.c_str());
getline(dict, line);
}
dict_size = dictionary.size();
for(int i = 0; i < dict_size; i++)
cout << "dictionary[" << i << "] is " << dictionary[i] << endl;
}
dict
Hello
World
Foo
Bar
After compiling this, I get the following output:
dictionary[0] is
dictionary[1] is
dictionary[2] is
dictionary[3] is
However, if I change the dictionary's type to vector and push back line instead of line.c_str(), I get the expected output:
dictionary[0] is Hello
dictionary[1] is World
dictionary[2] is Foo
dictionary[3] is Bar
I'm not terribly familiar with C style strings, so maybe it has something to do with null termination?
You are storing dangling pointers.
std::string::c_str() isn't a pointer to some permanent copy of data — just think, that would be leaked!
Store the std::strings instead.
Your code invokes undefined behavior, because after you do
dictionary.push_back(line.c_str());
On the next line that pointer may get deleted:
getline(dict, line); // line now is a different string
You are pushing into the dictionary pointers that point to the same address and at the last iteration it fills the memory area with an empty string. If you don't care about memory leakage you can try like this:
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main(int argc, char **argv)
{
ifstream dict;
size_t dict_size;
dict.open(argv[1]); // Dictionary
vector<char *> dictionary;
while(!dict.fail()) {
string * line = new string();
getline(dict, *line);
if(line->length()>0)
{
dictionary.push_back((char *)line->c_str());
}
}
dict_size = dictionary.size();
for(int i = 0; i < dict_size; i++)
cout << "dictionary[" << i << "] is " << dictionary[i] << endl;
}

Segmentation 11 in Linux issue

I am doing a buffer overflow problem and I trying to print hello world. Below is my code to
but I am getting a segmentation 11 issue when I run this file with another one. "./executable < input.cpp(This is the file below). I am doing something wrong to solve a buffer overflow issue?
#include<stdio.h>
using namespace std;
main()
{
printf("A");
//00000b00
for (int i = 0; i < 4; i++)
printf("%c%c%c%c",0x00,0x0b,0x00,0x00);
}
Below is the actual code that I am trying to print hello world. Above is my input string.
#include <iostream>
using namespace std;
int i;
unsigned int* p;
void f1() {
int a=10;
char str[4];
cout << "Please enter a string:";
while (!cin.eof()) {
cin.get(str[i]);
i++;
}
printf("address of str is:%x\n",str);
cout << "The string you entered is:";
printf("address of a is:%x\n",&a);
cout << str << endl;
}
void f2()
{
cout << "Hello World!\n";
}
main()
{
printf("The address of function f2:%08x\n",f2);
f1();
}
I am getting a segmentation 11 issue when I run this file with another one.
./executable < input.cpp
I am doing something wrong to solve a buffer overflow issue?
Yes. Buffer overflow attacks don't work like that - dumping a bunch of C source code into memory does not magically make the machine compile and run it. To generalize wildly, the data you dump into memory must contain:
Padding to force the following data to lie in the right place in the stack
A replacement address in the location of the old return address, pointing to the following executable code
Some more padding, usually a "NOP slide"
Some executable code
Please read the classic "Smashing the stack for fun and profit", and keep in mind that you may have to disable some protections (non-executable stack, ASLR, stack canary) to get these exploits to work on a modern system.
Use the %x modifier to print hexadecimal values
If this is a C program, then the use of namespace std makes no sense
#include<stdio.h>
int main(void)
{
puts("A");
for (int i = 0x0; i < 4; i++)
printf("%x\n", i);
return 0;
}
Op's post was updated:
#include<stdio.h>
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int i = 0; //Initialise i
void f1() {
int a=10;
char str[4];
cout << "Please enter a string: ";
while (!cin.eof() && i < 4 ) { //Have a condition on length of string
cin.get(str[i]);
i++;
}
str[i] = '\0'; //Set the eof character at end of the string
printf("address of str is: %p\n", str);
printf("address of a is: %p\n", &a);
cout << "The string you entered is: " << str << endl;
}
void f2() {
cout << "Hello World!\n";
}
int main()
{
printf("The address of function f2: %p\n", f2); //To print address use the %p option
f1();
return 0;
}