Append ' before and after char[] in C - c

I am trying to append single quotes before and after a char array. Following is the code I am trying:
static const char str[] = "select * from name";
STATICF boolean test(){
char[] key = "1234";
strcat(str,(const char *)"\'");
strcat(str,key);
strcat(str,(const char *)"\'");
}
It does not work as I get segmentation fault. How can I fix this?

The array str is initialized to be exactly as big as the string that initializes it. This means that attempting to append anything to that string will write past the end of the array. Doing so invokes undefined behavior which in this case causes your program to crash.
You need to make the destination string big enough to hold the resulting string, and you need to not qualify it as const.
Also, manually constructing a SQL string is a bad idea as it can lead to a SQL injection attack. You should instead use prepared statements which can inject parameters into a command safely.
static const char str[] = "select * from name";
STATICF boolean test(){
char[] key = "1234";
int len = strlen(str) + 1 + strlen(key) + 1 + 1;
char dest[len];
strcpy(dest,str);
strcat(dest,"'");
strcat(dest,key);
strcat(dest,"'");
}

strcat(str,(const char *)"\'");
strcat(str,key);
strcat(str,(const char *)"\'");
str needs to be big enough to hold the whole concatenated result string, plus \0 to terminate the string. This isn´t the case at your example with the declaration of str as:
static const char str[] = "select * from name";
with str to hold only the size of the old string plus \0. Thus, trying to append more characters causes the segmentation fault.
Try to declare str with a fixed size, large enough to hold the result string (the old string of select * from name + \' + 1234 + \' + the terminating \0 which shall be 25 characters in total if I´d counted right).
str needs to be non-constant to change the value of str by the way, so omit static const.
Also omit the cast of (const char *); and replace "\'" with "'".
The result is like the following:
char str[25];
strcpy(str,"select * from name");
STATICF boolean test(){
char key[] = "1234";
strcat(str,"'");
strcat(str,key);
strcat(str,"'");
}

Related

Create a file of a specific dimension filled with zeroes

I'm trying to create a method which, given multiple strings, merges them together. Now, this is what I came up with. The main is purely for test so in the end I'll have only one part string at the time, the location on which that part belongs in the full string, and the final string where I need to put these parts.
int mergeParts(char* text, char* part, int position){
int printSpot = position * CONTENTSIZE;
strcat(text[printSpot], part);
printf("%s\n", text);
return 0;
}
Now, the problem with this code is a segmentation error, I tried multiple things but the only one that seems to work is using strcat(text, part); without using the "location" on which the part of the string must be copy.
#define CONTENTSIZE 10
int main(){
int i;
char* part1 = "This is a ";
char* part2 = "test with ";
char* part3 = "something ";
char* part4 = "that i wro";
char* part5 = "te in it";
int totParts = 5;
char* parts[totParts] = {part1,part2,part3,part4,part5};
int stringSize = totParts * CONTENTSIZE;
char* finalString = malloc(stringSize);
for(i = 0; i<totParts; i++){
mergeParts(finalString, parts[i], i);
}
return 0;
}
How can I do this specifying to the string the location where to copy the parts.
A good example that I can give you to explain better what I'm looking for is:
I have a empty string "------------------------------"
I have to write inside "This "; "is an"; " exam"; "ple o"; "f the"; " text";
If I receive " exam";, the result in my string has to be "---------- exam---------------".
Then I receive " text"; and so the result will be "---------- exam---------- text"
And so on until I have "This is an example of the text";
It seems that strcat(text[printSpot], part); is the point. I think you should use strcat(&(text[printSpot]), part); instead. text[printSpot] will have the actual char data like 'e', not the address of the string which is required for strcat.
Or you can use strcat(text+printSpot,part) simply.
The main issue causing the segfault is that you're not passing the correct argument to strcat:
strcat(text[printSpot], part);
Both arguments are expected to be of type char *, but for the first argument you're passing in a single char. Passing a non-pointer where a pointer is expected invokes undefined behavior. In this case, the character being passed in is being interpreted as an address (which is invalid), and that invalid address is dereferenced, causing a crash.
You should be passing in the address of that array element:
strcat(&text[printSpot], part);
You also haven't initialized the bytes in finalString. The strcat function expects its first argument to point to a null terminated string, but because none of the allocated bytes have been initialized, you potentially read past the end of allocated memory, which again invokes undefined behavior.
Putting an empty string in finalString will take care of this:
strcpy(finalString, "");
Or equivalently:
finalString[0] = '\x0';
This allows the test program to work properly, where you're appending to an empty string in order, but it doesn't satisfy the requirement of updating parts of an existing string, possibly in the middle. Using strcat will null-terminate the destination string after the second argument is appended, resulting in anything that might have come after it to be lost.
Assuming finalString is initially set with an "empty" string as in your example of the proper length, you should instead use memcpy. This will copy over only the characters in the string and not add a null terminating byte:
memcpy(&text[printSpot], part, strlen(part));
You'll also want to populate finalString with '-' characters to start:
char* finalString = malloc(stringSize + 1);
memset(finalString, '-', stringSize);
finalString[stringSize]=0;
Output:
This is a ----------------------------------------
This is a test with ------------------------------
This is a test with something --------------------
This is a test with something that i wro----------
This is a test with something that i wrote in it--

Memmove in same pointer for deleting multiple whitespaces C

while this Code works:
char * k = "asd";
char * j = malloc(sizeof(char) * 3);
memmove(j,k,3);
printf("%s",j);
while code gives error:
char * k = "asd";
char * j = malloc(sizeof(char) * 3);
memmove(k,k+1,3);
printf("%s",k); // output should be "sd"
I am thinking wrong? Why it gives an erorr? I'm planning to use it for deleting the multiple whitespaces ("aaa.......bbb"(dots are spaces) -> "aaa bbb")
Thank you.
A declaration like
char *k = "asd";
causes the string literal to be stored in the read-only data segment. (C compilers tend to not warn for this case even though declaring the pointer as const char *k = "asd" would be safer, for historical reasons.)
If you want the string contents to be modifiable, you will need to use an array instead, like
char k[] = "asd";
When you do char *k = "asd", the string "asd" is placed in the read only parts of memory and the pointer k is made to point there. You cannot write to this location using memmove().
You should instead use char k[] = "asd".
The statement
memmove(k,k+1,3);
tries to shift the elements of string literal asd by 1. String literals are non modifiable. Any attempt to modify it will invoke undefined behavior.

char* and char[] are not same type? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I get a segmentation fault when writing to a string?
I'm experiencing a strange issue with my C code. I'm trying to split string using strtok function, but I get access violation exception. Here's my code:
char *token;
char *line = "LINE TO BE SEPARATED";
char *search = " ";
token = strtok(line, search); <-- this code causes crash
However, if I change char *line to char line[], everything works as expected and I don't get any error.
Anyone can explain why I get that (strange for me) behavior with strtok? I thought char* and char[] was the same and exact type.
UPDATE
I'm using MSVC 2012 compiler.
strtok() modifies the string that it parses. If you use:
char* line = "...";
then a string literal is being modified, which is undefined behaviour. When you use:
char[] line = "...";
then a copy of the string literal is being modified.
When assigning "LINE TO BE SEPARATED" to char *line, you make line point to an constant string written in the program executable. You are not allowed to modify it. You should declare those kind of variable as const char *.
When declared as char[], your string is declared on the stack of your function. Thus, you are able to modify it.
char *s = "any string"
is a definition of pointer which point to string or array of char(s). in the above example s is pointing to a constant string
char s[] = "any string"
is a definition of array of char(s). in the above example s is an array of char(s) which contains the charcters {'a','n','y',' ','s','t','r,'i','n','g','\0'}
strtock changes the content of your input string. it replaces the delimators in your string by the '\0' (null).
So, you can not use strtok with constant strings like this:
char *s="any string"
you can use strtok with dynamic memory or static memory like:
char *s = malloc(20 * sizeof(char)); //dynamic allocation for string
strcpy(s,"any string");
char s[20] = "any string"; //static allocation for string
char s[] = "any string"; //static allocation for string
To answer your question: char* and char[] are not same type?
This:
char *line = "LINE TO BE SEPARATED";
Is a string literal defined in read only memory. You can't change this string.
This, however:
char line[] = "LINE TO BE SEPARATED";
Is now a character array (the quoted text was copied into the array) placed on the stack. You are allowed to modify the characters in this array.
So they are both character arrays, but placed in different parts of memory.

Initialize a string in C to empty string

I want to initialize string in C to empty string.
I tried:
string[0] = "";
but it wrote
"warning: assignment makes integer from pointer without a cast"
How should I do it then?
In addition to Will Dean's version, the following are common for whole buffer initialization:
char s[10] = {'\0'};
or
char s[10];
memset(s, '\0', sizeof(s));
or
char s[10];
strncpy(s, "", sizeof(s));
You want to set the first character of the string to zero, like this:
char myString[10];
myString[0] = '\0';
(Or myString[0] = 0;)
Or, actually, on initialisation, you can do:
char myString[10] = "";
But that's not a general way to set a string to zero length once it's been defined.
Assuming your array called 'string' already exists, try
string[0] = '\0';
\0 is the explicit NUL terminator, required to mark the end of string.
Assigning string literals to char array is allowed only during declaration:
char string[] = "";
This declares string as a char array of size 1 and initializes it with \0.
Try this too:
char str1[] = "";
char str2[5] = "";
printf("%d, %d\n", sizeof(str1), sizeof(str2)); //prints 1, 5
calloc allocates the requested memory and returns a pointer to it. It also sets allocated memory to zero.
In case you are planning to use your string as empty string all the time:
char *string = NULL;
string = (char*)calloc(1, sizeof(char));
In case you are planning to store some value in your string later:
char *string = NULL;
int numberOfChars = 50; // you can use as many as you need
string = (char*)calloc(numberOfChars + 1, sizeof(char));
To achieve this you can use:
strcpy(string, "");
string[0] = "";
"warning: assignment makes integer from pointer without a cast
Ok, let's dive into the expression ...
0 an int: represents the number of chars (assuming string is (or decayed into) a char*) to advance from the beginning of the object string
string[0]: the char object located at the beginning of the object string
"": string literal: an object of type char[1]
=: assignment operator: tries to assign a value of type char[1] to an object of type char. char[1] (decayed to char*) and char are not assignment compatible, but the compiler trusts you (the programmer) and goes ahead with the assignment anyway by casting the type char* (what char[1] decayed to) to an int --- and you get the warning as a bonus. You have a really nice compiler :-)
I think Amarghosh answered correctly. If you want to Initialize an empty string(without knowing the size) the best way is:
//this will create an empty string without no memory allocation.
char str[]="";// it is look like {0}
But if you want initialize a string with a fixed memory allocation you can do:
// this is better if you know your string size.
char str[5]=""; // it is look like {0, 0, 0, 0, 0}
It's a bit late but I think your issue may be that you've created a zero-length array, rather than an array of length 1.
A string is a series of characters followed by a string terminator ('\0'). An empty string ("") consists of no characters followed by a single string terminator character - i.e. one character in total.
So I would try the following:
string[1] = ""
Note that this behaviour is not the emulated by strlen, which does not count the terminator as part of the string length.

Why does *(str+i) = *(str +j) not work here?

void reverse(char *str){
int i,j;
char temp;
for(i=0,j=strlen(str)-1; i<j; i++, j--){
temp = *(str + i);
*(str + i) = *(str + j);
*(str + j) = temp;
printf("%c",*(str + j));
}
}
int main (int argc, char const *argv[])
{
char *str = "Shiv";
reverse(str);
printf("%s",str);
return 0;
}
When I use char *str = "Shiv" the lines in the swapping part of my reverse function i.e str[i]=str[j] dont seem to work, however if I declare str as char str[] = "Shiv", the swapping part works? What is the reason for this. I was a bit puzzled by the behavior, I kept getting the message "Bus error" when I tried to run the program.
When you use char *str = "Shiv";, you don't own the memory pointed to, and you're not allowed to write to it. The actual bytes for the string could be a constant inside the program's code.
When you use char str[] = "Shiv";, the 4(+1) char bytes and the array itself are on your stack, and you're allowed to write to them as much as you please.
The char *str = "Shiv" gets a pointer to a string constant, which may be loaded into a protected area of memory (e.g. part of the executable code) that is read only.
char *str = "Shiv";
This should be :
const char *str = "Shiv";
And now you'll have an error ;)
Try
int main (int argc, char const *argv[])
{
char *str = malloc(5*sizeof(char)); //4 chars + '\0'
strcpy(str,"Shiv");
reverse(str);
printf("%s",str);
free(str); //Not needed for such a small example, but to illustrate
return 0;
}
instead. That will get you read/write memory when using pointers. Using [] notation allocates space in the stack directly, but using const pointers doesn't.
String literals are non-modifiable objects in both C and C++. An attempt to modify a string literal always results in undefined behavior. This is exactly what you observe when you get your "Bus error" with
char *str = "Shiv";
variant. In this case your 'reverse' function will make an attempt to modify a string literal. Thus, the behavior is undefined.
The
char str[] = "Shiv";
variant will create a copy of the string literal in a modifiable array 'str', and then 'reverse' will operate on that copy. This will work fine.
P.S. Don't create non-const-qualified pointers to string literals. You first variant should have been
const char *str = "Shiv";
(note the extra 'const').
String literals (your "Shiv") are not modifiable.
You assign to a pointer the address of such a string literal, then you try to change the contents of the string literal by dereferencing the pointer value. That's a big NO-NO.
Declare str as an array instead:
char str[] = "Shiv";
This creates str as an array of 5 characters and copies the characters 'S', 'h', 'i', 'v' and '\0' to str[0], str[1], ..., str[4]. The values in each element of str are modifiable.
When I want to use a pointer to a string literal, I usually declare it const. That way, the compiler can help me by issuing a message when my code wants to change the contents of a string literal
const char *str = "Shiv";
Imagine you could do the same with integers.
/* Just having fun, this is not C! */
int *ptr = &5; /* address of 5 */
*ptr = 42; /* change 5 to 42 */
printf("5 + 1 is %d\n", *(&5) + 1); /* 6? or 43? :) */
Quote from the Standard:
6.4.5 String literals
...
6 ... If the program attempts to modify such an array [a string literal], the behavior is undefined.
char *str is a pointer / reference to a block of characters (the string). But its sitting somewhere in a block of memory so you cannot just assign it like that.
Interesting that I've never noticed this. I was able to replicate this condition in VS2008 C++.
Typically, it is a bad idea to do in-place modification of constants.
In any case, this post explains this situation pretty clearly.
The first (char[]) is local data you can edit
(since the array is local data).
The second (char *) is a local pointer to
global, static (constant) data. You
are not allowed to modify constant
data.
If you have GNU C, you can compile
with -fwritable-strings to keep the
global string from being made
constant, but this is not recommended.

Resources