I am fairly new to C programming and still trying to understand all the nooks and crannies of C. I am writing a program to concatenate two strings. But I am getting an error which I don't understand. Here is the output.
Asfakul
The Length of the String name is 7
The Length of the String fullname is 7
L
Segmentation fault (core dumped)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char const *argv[])
{
char *name="Asfakul";
char *surname="Laskar";
char *fullname;
int i=0;
//Allocate Memory of 100 char
fullname=(char*)malloc(100*sizeof(char));
fullname=name;
while(*name !='\0')
{
i++;
name++;
}
// Allocate Memory for FullName
//fullname=(char*)malloc(100*sizeof(char));
//Coppied the spurce String
// fullname=name; // Here this assignement will not work as Pointer name now point to NULL character of String Name.
puts(fullname);
printf("The Length of the String name is %d\n",i );
printf("The Length of the String fullname is %d\n",strlen(fullname) );
while(*surname !='\0')
{
printf("%c\n",*(fullname+i+1));
*(fullname+i+2)=*(surname);
printf("%c\n",*(surname));
i++;
surname++;
}
puts(fullname);
return 0;
}
Please help me understand what I am doing wrong.
fullname = name; assigns the pointer name to fullname. You subsequently modify the data at name. That's not allowed since name points to a read-only string literal.
You're also discarding the malloc pointer, leaving you no way to free the allocated memory! This will not end well.
You should take a deep copy of name instead: consider using a strncpy.
If you were to use const char* for the string literals then compilation should fail, so protecting yourself from these kind of things.
*(fullname+i+2)=*(surname);
Here you are trying to cat the surname at the end of the name:
char *name="Asfakul";
This is read-only space.
You should alloc enough space for both strings and copy them inside the allocated space.
You can past char by char
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char const *argv[])
{
char *name="Asfakul";
char *surname="Laskar";
char *fullname;
int i=0;
//Allocate Memory of 100 char
fullname=malloc(100*sizeof(char));
while(*name !='\0')
{
fullname[i++] = *name++;
}
fullname[i] = '\0';
puts(fullname);
printf("The Length of the String name is %d\n",i );
printf("The Length of the String fullname is %zd\n",strlen(fullname) );
fullname[i++] = ' ';
while(*surname !='\0')
{
fullname[i++]= *surname++;
}
fullname[i] = '\0';
puts(fullname);
free(fullname);
return 0;
}
Related
I'm working on a project where I have to replace some char in a string.
I do not understand one of the errors I see.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void replaceLetters(char *text, char original, char new_char);
{
for (int counter = 0; text[counter] != '\0'; counter++)
{
if (text[counter] == original)//Error occurs here
{
text[counter] = new_char;
}
printf("%c", chr[counter]);
}
return 0;
}
int main()
{
char *text = "HallO";
char original = 'O';
char new_char = 'N';
replaceLetters(text, original, new_char);
return 0;
}
At the if statement the following error occurs: thread 1 exc_bad_access (code=1 address=0x0).
What does this mean, and how can I address it?
In c, string literals like "HallO" are stored in global read-only memory. If you want to modify the string, you will need to keep it in a buffer on the stack.
char text[6] = "HallO";
"What does this mean, and how can I address it?"
It is an access violation. The string you have defined
char *text = "HallO";
is referred to in C as a string literal, and is created in an area of read-only memory, resulting in an access violation.
This can be easily addressed by creating the original variable such that it is editable. eg:
char text[6] = "HallO"; //okay
char text[] = "HallO"; //better, let the compiler do the computation
char text[100] = "HallO"; //useful if you know changes to string will require more room
I'm trying to copy one string to another in c using memcpy with the following code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct fullName
{
char* firstName;
char* lastName;
} NAME;
int main()
{
NAME myName, hisName;
myName.firstName = "aaaaaaa";
hisName.firstName = "bbbbbb";
memcpy(myName.firstName, hisName.firstName, sizeof(hisName.firstName));
printf("myName.firstName = %s\n", myName.firstName);
printf("hisName.firstName = %s\n", hisName.firstName);
}
and it gives Segmentation fault (core dumped) Error after running the program
I tried to declare firstName and lastName as pointer to an array of chars rather than pointer to char but the error persists . what am I missing ?! plz help...
FYI .. I'm working on Ubuntu 14 and I'm using gcc (Ubuntu 4.8.2-19ubuntu1)...
In these statements
myName.firstName = "aaaaaaa";
hisName.firstName = "bbbbbb";
you initialized pointers with addresses of string literals.
In next statement
memcpy(myName.firstName, hisName.firstName, sizeof(hisName.firstName));
you try to modify one of the string literals.
According to the C Standard (6.4.5 String literals)
7 It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined.
Also this expression
sizeof(hisName.firstName)
returns size of the pointer itself. It is not the same as the size of the corresponding string literal.
The valid program could look the following way
#include <stdio.h>
#include <string.h>
typedef struct fullName
{
char firstName[8];
char lastName[8];
} NAME;
int main()
{
NAME myName = { "aaaaaaa" };
NAME hisName = { "bbbbbb" };
memcpy( myName.firstName, hisName.firstName, sizeof( hisName.firstName ) );
printf( "myName.firstName = %s\n", myName.firstName );
printf( "hisName.firstName = %s\n", hisName.firstName );
}
You are assigning myName.firstName and hisName.firstName with pointers to string literals. String literals cannot be modified, which is what's causing your error.
To achieve what you want, you can either declare firstName as a char array, or allocate memory to it (as a char pointer).
Array method:
typedef struct fullName
{
char firstName[256]; // a sufficiently large number
char lastName[256];
} NAME;
int main()
{
NAME myName, hisName;
strcpy(myName.firstName, "aaaaaaa"); // You can't assign a string directly
strcpy(hisName.firstName, "bbbbbb");
memcpy(myName.firstName, hisName.firstName, sizeof(hisName.firstName));
printf("myName.firstName = %s\n", myName.firstName);
printf("hisName.firstName = %s\n", hisName.firstName);
}
Allocation method:
typedef struct fullName
{
char* firstName;
char* lastName;
} NAME;
int main()
{
NAME myName, hisName;
size_t buffersize = 256; // a sufficiently large number
myName.firstName = malloc(buffersize);
hisName.firstName = malloc(buffersize); // same for lastName
strcpy(myName.firstName, "aaaaaaa");
strcpy(hisName.firstName, "bbbbbb");
memcpy(myName.firstName, hisName.firstName, buffersize); // You can't use sizeof() as this will give the size of a pointer
printf("myName.firstName = %s\n", myName.firstName);
printf("hisName.firstName = %s\n", hisName.firstName);
}
This did not crash in MSVC, it produced the output:
myName.firstName = bbbbaaa
hisName.firstName = bbbbbb
Notice that only 4 chars from hisName have been copied to myName. That is because
sizeof(hisName.firstName)
is 4 on your platform, the size of the pointer. But manipulating such strings is Undefined Behaviour anyway.
I have a problem with assigning specific pointer to another char sequence(string);
#include<stdio.h>
void setInformations(char *informations[], char *contests_name[]);
int main(void) {
char *informations[]={"","","",""};
char *contests_name[]={"cycle_race","swim","running race"};
int totalTime=0;
setInformations(informations,contests_name);
getch();
return 0;
}
void setInformations(char *informations[], char *contests_name[]) {
printf("Competitor's name: ");
scanf("%s",*informations[0]);
printf("%s",informations[0]);
}
I know that the problem is assigning string to pointer of type char. How can I replace this (strcpy?)
Take the * out of the scanf:
scanf ("%s", informations[0]);
...and allocate space for the informations array
char* informations[NUMBER_OF_INFORMATIONS][MAX_NAME_LENGTH] = {{'\0'}};
so scanf will have room to put in the info.
here : scanf("%s",*informations[0]);, you are trying to write in a read-only memory.
So you have to allocate the memory in the main :
int stringSize = 30; // example of length
char* informations[3];
informations[0] = malloc(stringSize);
informations[1] = malloc(stringSize);
informations[2] = malloc(stringSize);
//initialyse the strings to "" :
informations[0][0] = '\0';
informations[1][0] ='\0';
informations[2][0] ='\0';
in setInformations(, you have to delete the * to give scanf the adress of the memory where to write). correct syntax : scanf("%s",informations[0]);
So i'm trying to create a simple String struct which will contain the text of the string and the size of it, at least for now. However I'm having issues allocating my struct. Right now i'm simply trying to get a size of 1 character to work, but its simply crashing at this point and i don't know what i'm doing wrong with the allocation, please help.
#include <stdio.h>
#include <stdlib.h>
typedef struct{
char* text;
int size;
}String;
String* getString();
int main(int argc, char** argv){
String* str1 = getString();
printf("%s",str1->text);
free(str1);
return 0;
}
String* getString(){
String* str = (String*)malloc(sizeof(String));
scanf("%s",str->text);
str->size++;
return str;
}
You need to allocate memory for the structure but also for text string.
scanf("%s",str->text);
str->text is an uninitialized pointer.
You don't allocate any memory for str->text. You leave it uninitialized, so your program invokes undefined behavior.
You need to allocate memory for it using str->text = malloc(MAX_SIZE); where MAX_SIZE is the maximal size for the string. Alternatively, if your strings will be short, you may use a regular, fixed-szie array instead.
Furthermore, you probably do not want to use scanf() for scanning strings. One particular reason is that %s makes scanf() stop at the first whitespace character. Another reason is that it's not trivial to prevent scanf() from writing past the buffer if it's too small.. How about using fgets() instead?
fgets(str->text, MAX_SIZE, stdin);
is a better and safer approach.
int main(int argc, char** argv){
String* str1 = getString();
printf("%s",str1->text);
free(str1->text);
free(str1);
return 0;
}
String* getString(){
String* str = (String*)malloc(sizeof(String));//for struct
str->size = 16;//initialize
str->text = (char*)malloc(sizeof(char)*str->size);//for input text
int ch, len;
while(EOF!=(ch=fgetc(stdin)) && ch != '\n'){
str->text[len++]=ch;
if(str->size==len){
str->text = realloc(str->text, sizeof(char)*(len+=16));
}
}
str->text[len++]='\0';
str->text = realloc(str->text, sizeof(char)*(str->size=len));
return str;
}
#include <stdio.h>
#include <string.h>
char Jones(char, char);
int main() {
char name[]="Andrew";
char surname[]="Jones";
char result[80];
result=Jones(name, surname);
puts(result);
return 0;
}
char Jones(char name, char surname)
{
char result[80];
int length;
length = strlen(surname);
for (int i=0; i<50; i++)
{
result[length+i] = name[i];
}
return result;
}
The program does not compile and i dont know why. It is supposed to read two strings and swap their places. It should display eg. "Jones Andrew".
Here's one problem:
char name[]="Andrew";
char surname[]="Jones";
char result[80];
wynik=Jones(name, surname);
This calls Jones() with character arrays (which will decay to character pointers), but the function is declared to accept single characters only.
You should change the function to take char *name, char *surname, since it really does seem to expect strings.
Further, you can't return a character array like you're doing in Jones(), you need to read up quite a bit on how to work with strings in C.
Also, wynik looks undeclared, that'll also make it fail to build.
There's a few errors:
char Jones(char, char);
This takes just a single char, not a char * which you need for a string.
result=Jones(name, surname);
Here result is an array. In C, you cannot assign to an array.
char Jones(char name, char surname)
{ char result[80];
...
return result;
}
Here you return result which is a local variable. But to return a string, you'd need to return a char*. But that char* would point to a local variable within the Jones function, which is no longer valid when the function ends. One solution is to pass in a buffer where you write the result that the caller owns.
Your algorithm for combining the surename and name is also wrong, you never do anything with the surename.
You'll need to do this:
char *Jones(char*, char* , char *);
int main() {
char name[]="Andrew";
char surname[]="Jones";
char result[80];
char *p;
p = Jones(name, surname, result);
puts(p);
return 0;
}
char *Jones(char *name, char *surname, char *result)
{
int length;
int i,k;
length = strlen(surname);
for (i=0; i<length ; i++)
{
result[i] = surname[i];
}
result[i++] = ' '; //add a space
length = strlen(name);
for (k=0; k<length ; k++, i++)
{
result[i] = name[k];
}
result[i] = 0; //add nul terminator to end the string
return result;
}
The conatenation could be simplified in many ways, e.g. to
strcpy(result, surename);
strcat(result, " ");
strcat(result, name);
or the Jones function could just do:
sprintf(result, "%s %s", surename, name);
In all cases, the function is rather fragile, as it's easy to overflow the result buffer if you pass in something else that does not fit within the result buffer.
1) The name and surname are char array and not single char so you have to change the input parameters types of your function Jones() the input parameters types should be char name[] (char array) or char *name (pointer to array of char)
2) You can not return an array defined locally and statically in the function. and if you want to return a string from the function, the string should be constant or it should be a buffer allocated dynamically (with malloc, calloc, realloc) into the function And for both cases the function type should be char *Jonas() and not char Jonas()
Or you can pass the result array via input parametr. and in this case you can fill it into the function.
void Jones(char *name, char *surname, char *result)
and in the main:
char result[80];
Jones(names, surname, result);
3) The following for loop is missing some thing
for (int i=0; i<50; i++)
{
result[length+i] = name[i];
}
The result elements from element 0 to element length are containing garbage because the result array is not initiated. so when you printf the result array you will get garbages printed. You have to initiate elements between 0 to length in the result array
#include <stdio.h>
#include <string.h>
char* Jones(char*, char*);
int main() {
char name[]="Andrew";
char surname[]="Jones";
puts(Jones(name,surname));
return 0;
}
char* Jones(char *name, char *surname)
{
strcat(surname," ");
strcat(surname,name);
return surname;
}