input size depending on input - c++

If it makes sense.
This is how it looks so far.
#include <iostream>
int main()
{
char *buffer;
buffer = new char[100];
std::cin >> buffer;
const int size = strlen(buffer);
char input[size];
delete buffer;
return 0;
}
I know I can use the string library but I'm trying to do without it.
I want to make the char size (in the code char input) depending on the input size.
The errors which I am getting is
expression did not evaluate to a constant
expression must have a constant value
on line 12 which is the
char input[size];

I know I can use the string library but I'm trying to do without it.
You can use std::vector<char>. If that is not an option either, allocate memory yourself and make sure that you deallocate the memory.
char* input = new char[size+1]; // Add an extra for the terminating null characterr
....
delete [] input;

For std::cin you need to pre-allocate a buffer. If you plan on using char[] and you really have to avoid strings you have to make sure you allocate enough memory.
Alternatively you can read char by char with scanf("%c",&newChar) until user inputs an escape character and allocate memory for array as you go.
I don't suppose you're limited to using iostream ?

If it is the length of used space in the buffer array you are trying to assign to size for the input array, there are two methods you can use...
#include <iostream>
using namespace std;
int main()
{
char *buffer = new char[100];
cin >> buffer;
int spaceUsed = 0;
for (unsigned int i = 0; i < 100; i++)
{
if (buffer[i] != '\0')
spaceUsed++;
}
char input[spaceUsed];
delete [] buffer;
return 0;
}
OR...
#include <iostream>
using namespace std;
int main()
{
char *buffer = new char[100];
cin >> buffer;
int spaceUsed = 0;
while (*buffer++)
spaceUsed++;
char input[spaceUsed];
delete [] buffer;
return 0;
}
Both code snippets do the exact same thing. Of course, using the string library would make your life much easier though.

Related

Adding spaces at the beginning of an array of chars

As in the title, I need to add user-specified number of spaces at the beginning of some word, using array of chars. I need to do it in a function which takes my array as a parameter and returns it. Here's my code:
#include <iostream>
using namespace std;
void writeDownCharArray(char t[], int sizee)
{
for (int i=0;i<sizee;i++)
{
cout<<t[i];
}
}
char * addSpaces(char t[], int ammountOfSpaces)
{
int numberOfCharacters=0;
for (int i=0; t[i]!=NULL; i++){numberOfCharacters++;} //checking the amount of characters in my array
char t2[numberOfCharacters+10];
for (int i=0; i<ammountOfSpaces; i++) {t2[i]=' ';} //adding the sapces
for (int i=ilosc;i<numberOfCharacters+ammountOfSpaces;i++) {t2[i]=t[i-ammountOfSpaces];} //filling my new array with characters from the previous one
return t2;
}
int main()
{
int numberOfSpaces;
char t[10];
cout << "Text some word: ";
cin.getline(t,10);
cout<<"How many spaces?: ";cin>>numberOfSpaces;
writeDownCharArray(addSpaces(t, numberOfSpaces), HERE);
return 0;
}
And now: How do I print it to the screen? If I say cout<<addSpaces(t, numberOfSpaces); it actually prints something strange to the screen (not numbers, just strange characters). And if I say writeDownCharArray, then what should I put in "HERE" place?
The C++ way to solve this would be to use a std::string like
std::string add_spaces(const std::string & line, std::size_t number_of_spaces)
{
std::string spaces(number_of_spaces, ' ');
return spaces + line;
}
If you cannot use std::string then you are doing to have to deal with dynamic memory allocations and change
char t2[numberOfCharacters+10];
to
char * ts = new char[numberOfCharacters + ammountOfSpaces + 1];
We have to have this as Variable length arrays are not standard and trying to return a pointer to an array declared in a function will leave you with a dangling pointer and trying to use it is undefined behavior.
Since new[] was used in the function you will need to remember to call delete[] on the pointer that is returned after you are done with it. This is another benefit of using a std::string as it takes care of itself.
As far as writeDownCharArray is concerned you do not need a size parameter as cout can handle null terminated c-strings. You can simply have
void writeDownCharArray(char t[])
{
cout<<t;
}
And then you main would look like
char * foo = addSpaces(t, numberOfSpaces);
writeDownCharArray(foo);
delete [] foo;

Reading unlimited length input line without using string

I would like to read unlimited length line of text from the input. I wish not to use string or any of it.
I tried that but it seems does not work. I always get the same output.
I do not want to use: string, the input has to be of any length.
#include <iostream>
#include <stdio.h>
using namespace std;
char * getline(){
char * buf = new char[10];
int result = scanf("%as\n", &buf);
if (result < 0) {
if (NULL != buf)
delete []buf;
return NULL;
}
return buf;
}
int main(){
char* haha = getline();
cout <<haha << endl;
return 0;
}
char * buf; just creates the pointer variable, but does not allocate memory.
use: buf = new char[...].
Obviously, since your computer has not got unlimited memory, you will need to specify a size instead of ...
And delete it as: delete [] buf
But, I think the best solution is:
std::string s;
std::cin >> s;
You can't read into a buffer that doesn't exist! Here buf points to an undefined location in memory, and the most likely outcome of this code is a crash. You must allocate some space (using new[]) before you can read data into it; and of course, that space must be of some well-defined size. You can always allocate a new, large buffer at any time, and copy the contents of the smaller one into it; this is how you "grow" memory blocks in C++, and it's how string works internally.

wrong memory allocation new char [n]

What is wrong with this program?
#include<iostream>
using namespace std;
void main()
{
int n = 5;
char* p = new char [n];
int i;
for(i=0;i<n;i++)
{
p[i] = 'A'+i;
}
cout<<p<<endl;
}
Why do I get "ABCDExxxx" instead of "ABCDE" ?
What is wrong with memory allocation?
There's nothing wrong with the memory allocation, except that the memory is never released. Don't forget to delete [] p; before main returns.
The problem with the output is that the string that p points to does not have a terminating '\0'. In general, you should allocate an array with room for at least one more character than you're going to put into the array, and put a '\0' after the last one. Of course, a better solution is to use std::string, which takes care of all that for you.
C Strings need to be null-terminated. Add one more byte containing 0.
You can allocate the storage for char using new this way, it is OK. However if you are going to use it later with functions that relates on null terminating character (like strlen i.e, or printing this out) then when allocating the storage for a char* you need to allocate the number of characters + 1 more to store the \0. C Strings need to be null-terminated.
Why do I get "ABCDExxxx" instead of "ABCDE" ? What is wrong with
memory allocation?
your data is not null terminated (doesn't contain '\0' at the end so you are printing garbages until character '\0' is found somewhere else). To make it work as expected you can do:
int n = 5;
char* p = new char [n+1];
p[n]='\0';
for(i=0;i<n;i++)
{
p[i] = 'A'+i;
^
side note: this is OK, however if your p has been pointing to a string
literal, i.e. if it was defined as char*p = "string literal\n";
then according to section 2.14.5 paragraph 11 of the C++ standard,
it would invoke undefined behavior:
The effect of attempting to modify a string literal is undefined.
so be aware :p !
}
cout<<p<<endl;
remember then to deallocate storage with
delete [] p;
and as others commented, it might be a better idea to use std::string instead.
First of all, please don't use C style when you're already on C++
Use std::string instead
It has a member function c_str() that helps to work with C api/functions
#include<iostream>
using namespace std;
int main()
^^ main should return int
{
int n = 5;
//C string needs to be null terminated, so an extra
char* p = new char [n+1];
int i;
for(i=0;i<n;i++)
{
p[i] = 'A'+i;
}
p[i] = '\0'; //Insert the null character
cout<<p<<endl;
}
You are simply not putting a null character. Use this code:
#include<iostream>
using namespace std;
void main()
{
int n = 5;
char* p = new char [n];
int i;
for(i=0;i<n;i++)
{
p[i] = 'A'+i;
}
cout<<p<<endl;
}
As you are using c++ i recomend using std::string.
#include<iostream>
#include<string>
using namespace std;
void main()
{
//int n = 5;
//char* p = new char [n];
string s;
int i;
for(i=0;i<n;i++)
{
s.append("/*whatever string you want to append*/");
}
cout<<s<<endl;
}
when the endl met '\0' ,it return,so if you dont have a '\0' in the char[],until found it,it will continue to read memoery.

Getting the Content of String into a Char Array

#include <stdio.h>
#include <string.h>
int main()
{
std::string data;
data = "hello world";
char string1[] = data;
}
If I must use char string1[] and not char *string1, is there a way I can copy content of string data into this char string1[]?
file.cpp: In function ‘int main()’:
file.cpp:13:22: error: initializer fails to determine size of ‘string1’
You can call method c_str on std::string object and copy result to your array.
Since the size of data may be variable, it cannot be copied via initialization of a static array.
One way you can do it is with dynamic allocation (which C++ string handles automatically):
char *string1 = strdup(data.c_str());
// do stuff with string1
free(string1);
If you are familiar with loops, then the easiest way is to copy the contents of string to char array one by one. As you are not going to use char pointer so you have to fix the size of char array, say 20.
int main()
{
string data;
data = "hello world";
int size = data.size(); // size of data
char string1[20]; //you can change the size of char array but it must be greater than size of data string
for (int i = 0; i < size; i++) {
string1[i] = data[i];
}
return 0;
}
Using stack memory (only if you are sure that the data.size() is less than 1000.):
char result[1000];
strcpy(result, data.c_str());
Or using heap memory:
char* result = new char[data.size() + 1];
strcpy(result, data.c_str());
// ...
delete[] result;

C++ char* problems [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
#include<iostream>
using namespace std;
int main()
{
char *name="Siva",*str;
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
cout<<str;
return 0;
}
The first program gives output Sivaœ> i.e siva with some garbage values....
But the second program show segmentation fault...Please help me to find out
exact answer...
#include<iostream>
using namespace std;
int main()
{
int i=0;
char *name="Siva",*str;
for(i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
cout<<str;
return 0;
}
char *name="Siva",*str;
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
str is a pointer, but it doesn't yet point to anything.
Since you're in C++, you should be using std::string:
#include<iostream>
#include <string>
using namespace std;
int main()
{
char *name="Siva";
std::string str;
for(int i=0;i<strlen(name);i++)
{
str += name[i];
}
cout<<str;
return 0;
}
Even better, get rid of the hand-written loop:
#include <algorithm>
int main()
{
char *name="Siva";
std::string str;
std::copy (name, name + strlen (name), std::back_inserter (str));
cout<<str;
return 0;
}
Better even still, there's no reason in this particular example why you need to do any of that at all:
char* name = "Silva";
std::string str = name;
cout << str;
By the way, string literals in C++ are inherently const:
const char* name = "Silva";
If you really must use a char*, first I would strongly question why, and then I would tell you to do this:
int main()
{
const char *name="Siva";
char* str = new char [strlen (name)+1]; // +1 for the null terminator
strcpy (name, str);
cout << str;
delete [] str;
return 0;
}
I would even more strongly question your need to copy it byte-by-byte:
int main()
{
const char *name="Siva";
char* str = new char [strlen (name)+1]; // +1 for the null terminator
for (size_t i = 0; i < strlen (name); ++i )
str [i] = name [i];
str [strlen (name)] = '\0';
cout << str;
delete [] str;
return 0;
}
You have undefined behaviour here:
str[i]=name[i];
str has not been initialized to anything. You are writing to places you shouldn't.
There are two problems with this.
The pointer str doesn't point to allocated memory, so writing through it is undefined behavior.
Even if it did point to valid memory, you're not writing the correct amount of data. When copying a string, you need to copy the 0 byte at the end which marks the end of the string; so the upper limit of your loop should bt strlen(name) + 1. Or you could use a library method like strdup() instead of your own for loop.
The reason the "working" version prints some garbage characters is that there's no 0 at the end of the copied string to tell iostreams to stop printing. The reason the "working" one doesn't crash, and the other one does, is pure dumb luck: the garbage in str, by chance, points to memory you're allowed to write to, while in the crashing program, it points to memory you're not allowed to write to. Simple as that.
It is because you have no memory allocated for str. (it will cause an undefined behavior)
You can mix that by using a merory allocation function like in this example :
#include<iostream>
using namespace std;
int main()
{
char *name="Siva",*str;
// Allocate memory with malloc
str = (char*)malloc( (strlen(name)+1) * sizeof(char) );
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
str[strlen(name)] = 0;
cout<<str;
// Free the allocated memory
free(str);
return 0;
}
As you are using c++, you can do :
#include<iostream>
using namespace std;
int main()
{
char *name="Siva",*str;
// Allocate memory with new
str = new char[strlen(name) + 1];
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
str[strlen(name)] = 0;
cout<<str;
// Free the allocated memory
delete []str;
return 0;
}
EDIT :
The reason you have some weird caracters at the end of your ouput is that because you string is not terminated with a '\0', it will continue to print it. (This will occur only if you don't have a segmentation fault )
There are a couple problems with your code.
Firstly, *str is not allocated, so it starts off by pointing to whatever bit of memory the pointer value happens to start off as.
Secondly, strlen() returns the length of the string excluding the terminating null character. So what you are doing is copying all the values of name into some random bit of memory, not terminating it, then telling the system to print that off, which could be any length.
str[i]=name[i]; is illegal, causes Undefined behavior, because you have not allocated memory for str.
Before for loop allocate memory for destination string str:
str = malloc (strlen(name) + 1 );
Also you forgetting string termination, after for-loop add terminate string str[i] = '\0';
Undefined behavior refers to computer code whose behavior is unpredictable.
You code should be:
char *name="Siva", *str;
str = malloc (strlen(name) + 1 ); // mistake
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}
str[i] = '\0'; // forgetting
To understand further you can read this answer: strcat() implementation works but causes a core dump at the end
Your problem is using char arrays and pointers to represent strings in language which has proper string type.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name = "Siva", str;
str = name;
cout << str;
return 0;
}
Problem is with str[i]=name[i] you must know that C++ does not care for memory leaks
as Java or some others. So you must allocate memory to a variable or pointer in order to avoid these problems. Already there are number of answers, you can also try
str=new char[strlen(name)+1];
and do not forget to terminate the char array with null when you done copy. In this case
str[strlen(name)]='\0';