I know a string concatenation question has been asked to death in SE. But to the best of my knowledge,I've gone through all the questions that could help me, in vain.
This is what I am hoping to accomplish with this program:
Initially I have a=0 and b=1, for n=0 and n=1 respectively.
For the next input i.e from n=3 onwards, my result should be concatenation of the previous two strings. (Like a Fibonacci sequence; only the addition is replaced by concatenation)
So,for example:
For n=3, my output should be "10".
For n=4, my output should be "101"
For n=5, my output should be "10110"
There is no logical problem with the code I've written,but I'm getting a SIGSEGV error and I don't see why.
#include <iostream>
#include<new>
#include<string.h>
using namespace std;
int main()
{
long int n,i;
char *a="0";
char *b="1";
char *c=new char[100000];
cout<<"Enter a number n:";
cin>>n;
for(i=0;i<n;i++)
{
strcat(b,a);
strcpy(a,b);
}
cout<<"\nRequired string="<<b;
}
What am I doing wrong?
strcat(b,a); invokes undefined behaviour because b points to a string literal.
char * strcat ( char * destination, const char * source );
Concatenate strings
Appends a copy of the source string to the destination string.
Since this is C++, I suggest you use std::string and the + operator. Or a std::stringstream.
The problem that you are observing has to do with undefined behavior: you are writing to the memory that has been allocated to a string literal.
To avoid the issue, you should switch to using C++ std::string: it makes your code a lot simpler by taking memory management out of the picture.
string a("0");
string b("1");
int n = 10;
for(int i=0;i<n;i++) {
string tmp(a);
a = b;
b = tmp + b;
}
cout<<"Required string="<<b;
char *a="0";
char *b="1";
"0" and "1" are string-literals (a has address of "0" and b has address of "1"), change of its contains is undefined behaviour.
strcat(b,a);
strcpy(a,b);
UB.
Since you use C++ better use std::string or std::stringstream.
You have declared a and b as
char *a="0";
char *b="1";
These are pointers to constant strings. This means that the memory allocated to these pointers is fixed. When you write past this block of memory, Bad Things(TM) will happen.
You are using strcat but your destination string is a string literal. strcat is then attempting to write past that strings terminating null character and that is where the seg fault comes in. Just don't try to modify string literals at all. Since you have the luxury of using C++ unless this is a learning exercise you would be much better off using std::string.
You can use this code instead, I am showing to you that you need to think of the inital values of n = 1, 2
also you should handle wrong inputs with n < 0
and avoid dynamic allocation as you seems to use new for no obvious reason and you forgot to free the memory with delete at the end.
#include <iostream>
#include<new>
#include<string.h>
using namespace std;
int main()
{
long int n,i;
char a[10];
char b[10];
char c[10];
//char *c=new char[100000];
cout<<"Enter a number n:";
cin>>n;
strcpy(a, "0");
strcpy(b, "1");
if (n == 1)
strcpy(b, a);
else if (n > 2)
{
for(i=2;i<n;i++)
{
strcpy(c, a);
strcat(c, b);
strcpy(a, b);
strcpy(b,c);
}
}
else if (n != 2)
cout<<"\nInvalid input!";
cout<<"\nRequired string="<<b;
}
Related
#include <iostream>
using namespace std;
int main() {
char *s;
printf("enter a word \n");
scanf("%s", s);
int i;
for (i = 0; s[i] != '\0'; i++) {
}
printf("length is = %d", i);
return 0;
}
When I compile this program, a segmentation fault occurs.
Can anyone plz tell me, what is the problem in this code?
char *s;
Is unitialized, you can't assign an input stream to it until it is.
char s[100]; //space for 99 characters plus null terminator
or
char* s = malloc(100); //each char has the size of one byte
These are C tools, for C++, however, you can/should use std::string, with std::cin instead of scanf.
std::string s;
std::cin >> s;
If you must use C tools, scanf("%s", s); is not the most safe method, if you don't pass the size of the char array container, changing specifier %s to %100s or changing it altogether to a safer function like fgets(s, sizeof(s), stdin); is a better option.
char *s;
You created a pointer, though it does not point to anything (it is uninitialized).
scanf("%s",s);
You try to read data into the string pointed-to by s, but no such thing exists.
💥!
Allocate some memory and have s point to it… or, better yet, use std::string and std::cin.
char *s;
printf("enter a word \n");
scanf("%s",s);
scanf with %s does not allocate memory, instead it reads into the buffer you provide it (e.g. s = malloc(100);. How big does that buffer need to be to avoid a buffer overflow? Unfortunately it can be however long until a whitespace character, so is inherently unsafe.
You can specify a max up front (not including null terminator!), but to handle variable size you then need to dynamically build the format string which gets complicated. As does what to do if the user enters a string too long.
char s[100];
scanf("%99s", s);
Since you tagged C++, you can use std::string and IO streams (e.g. std::cin for console input) which will handle all the memory allocation for you.
std::string s;
std::cout << "enter a word" << std::endl;
std::cin >> s;
In the case of C, you might use fgets(str, num, stream), this lets you specify the max length and avoid overflow in a simple manner.
char s[128];
fgetsf(s, 100, stdin);
Or with the POSIX 2008 scanf it can allocate the memory, but I don't believe this is universally supported, e.g. by Microsoft Visual Studio.
char *s = 0;
scanf("%ms", &s); // pass a pointer to a pointer!
free(s); // needs to be freed later!
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.
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';
Is there anyway , if I enter any string , then I want to scan ASCII value of each character inside that string , if I enter "john" then I should get 4 variables getting ASCII value of each character, in C or C++
Given a string in C:
char s[] = "john";
or in C++:
std::string s = "john";
s[0] gives the numeric value of the first character, s[1] the second an so on.
If your computer uses an ASCII representation of characters (which it does, unless it's something very unusual), then these values are the ASCII codes. You can display these values numerically:
printf("%d", s[0]); // in C
std::cout << static_cast<int>(s[0]); // in C++
Being an integer type (char), you can also assign these values to variables and perform arithmetic on them, if that's what you want.
I'm not quite sure what you mean by "scan". If you're asking how to iterate over the string to process each character in turn, then in C it's:
for (char const * p = s; *p; ++p) {
// Do something with the character value *p
}
and in (modern) C++:
for (char c : s) {
// Do something with the character value c
}
If you're asking how to read the string as a line of input from the terminal, then in C it's
char s[SOME_SIZE_YOU_HOPE_IS_LARGE_ENOUGH];
fgets(s, sizeof s, stdin);
and in C++ it's
std::string s;
std::cin >> s; // if you want a single word
std::getline(std::cin, s); // if you want a whole line
If you mean something else by "scan", then please clarify.
You can simply get the ascii value of a char by casting it to type int:
char c = 'b';
int i = c; //i contains ascii value of char 'b'
Thus, in your example the code to get the ascii values of a string would look something like this:
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
int main()
{
string text = "John";
for (int i = 0; i < text.size(); i++)
{
cout << (int)text[i] << endl; //prints corresponding ascii values (one per line)
}
}
To get the corresponding char from an integer representing an entry in the ascii table, you just have to cast the int back to char again:
char c = (char)74 // c contains 'J'
The code given above was written in C++ but it basically works the same way in C (and many other languages as well I guess)
There is no way to turn a string of length 'x' into x variables. In C or C++ you can only declare a fixed number of variables. But probably you don't need to do what you are saying. Perhaps you just need an array, or most likely you just need a better way to solve whatever problem you are trying to solve. If you explain what the problem is in the first place, then I'm sure a better way can be explained.
Ya,I think there are some more better solutions are also available but this one also be helpful.
In C
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main(){
char s[]="abc";
int cnt=0;
while(1){
if(s[cnt++]==NULL)break;
}
int *a=(int *)malloc(sizeof(int)*cnt);
for(int i=0;i<cnt;i++)a[i]=s[i];
for(int i=0;i<cnt-1;i++)printf("%d\n",a[i]);
return 0;
}
In C++
#include <iostream>
#include <string>
using namespace std;
int main(){
string s="abc";
//int *a=new int[s.length()];
//for(int i=0;i<s.length();i++)a[i]=s[i];
for(int i=0;i<s.length();i++)
cout<<(int)s[i]<<endl;
return 0;
}
I hope this one will be helpful..
yeah it's very easy ..just a demo
int main()
{
char *s="hello";
while(*s!='\0')
{
printf("%c --> %d\n",*s,*s);
s++;
}
return 0;
}
But make sure your machine is supporting the ASCII value format.
In C every char has one integral value associted with it called ASCII.
Using %d format specifier you can directly print the ASCII of any char as above.
NOTE: It's better to get good book and practice this kind of program yourself.
char* a="HELLO WORLD";
IF ADDRESS of 'H' is 0x01 then the printf with %s prints to D but if the same code is written with manual printing routine
while(*a!=NULL) {printf("%c",n[a]);n++;}
this prints a few more characters..
but
printf("%s",a);
prints it perfectly.
while(*a++) printf("%c", *(a-1)); or
for(;*a++;)printf("%c", *(a-1));
although work but i dont want solutions but the process mechanisms..
so the question coming to my mind is
whether printf gets the length of the string from some register(or any memory unit)
or it performs character check.. then prints...
The way you're indexing into the character string is odd. It works for the string, but won't stop because you never change the value of *a. What your program does is try to get the a offset of n, so for the first 11 positions they are the same, but the loop doesn't terminate because *a will always be 'H'. What you'd want the terminating condition to be is n < strlen(a).
However, the more succinct way to write that program would be:
int main(int argc, char **argv) {
char *a = "HELLO WORLD";
while(*a) printf("%c", *a++);
return 0;
}
This works because a is an array of characters and as we're printing out each character (de-referencing the value stored at the position) we also increment to the next position. The string should terminate with a NULL reference, which will cause the loop to terminate sine *a == 0 at the NULL terminator.
did you mean or you have error:
int main() {
int n = 0;
char* a="HELLO WORLD";
while(a[n] != NULL) {printf("%c",a[n]);n++;}
}
explanation about what is wrong:
while(*a!=NULL) printf("%c",n[a]);n++;
a is not modified anywhere, so *a will not change it's value.
Although n[a] is perfectly valid construct in C I strongly recommend not to use it, because it is semantically incorrect. You access array by index, not index by array.
You increment index (n++) but check the pointer to array. You could possibly increment a inself like this: while(*a!=NULL) {printf("%c",*a);a++;}
The corect way to do this is:
#include <iostream>
using namespace std;
int main() {
char *a="HELLO WORLD";
int n = 0;
while(a[n]!=NULL){
cout<<a[n];
n++;
}
cout<<'\n';
return 0;
}
As far as I remember, by default when you created char* a it will be something as {HELLO WORLD\0} in memory ('\0' is how %s know the end of the your string is)..
Not sure if '\0' == null will yield true.. but I doubt it