I need an entire string to be one char of another string.
const char *const_string = "FOOBAR";
char *character_string = malloc(1024);
// character_string = const_string[3];
How can I make the last (commented) line work?
It seems you mean the following
void do_something(char *str, int idx)
{
str[0] = glob_str[idx];
str[1] = '\0';
}
You can add a check to the function that the index is not outside the string literal pointed to by glob_str.
Given
char *glob_str = "test test"; // glob_str is literal string and cannot be modified
then
glob_str[0] = val; // modification won't work
You need to change to
char glob_str[] = "test test";
See this question
Related
Since a string literal can be initialized like
char myString [] = "somestring";
it seems logical to be able to use a function like
int stringLength ( char * str )
{
char * c2 = str;
while (*c2++);
return (c2-str);
}
and call it like
printf("%d",stringLength("somestring"));
However, I get an error when I do that.
Is there some way I can "cast" "something" into something proper to input into the function, or do I always have use an extra line like
char str [] = "somestring";
printf("%d",stringLength(str));
or is there something else I should be doing altogether?
char myString [] = "somestring";
creates an array of characters that are modifiable.
When you use
printf("%d",stringLength("somestring"));
it is analogous to:
char const* temp = "somestring";
printf("%d",stringLength(temp));
That's why the compiler does not like it.
You can change the function to use a char const* as argument to be able to use that.
int stringLength ( char const* str )
{
char const* c2 = str;
while (*c2++);
return (c2-str);
}
You know that your function "stringLength" will never mutate/change the contents of the string right so make that function so
int somefunc(const char* ptr)
{
const char* base=ptr;
while(*(ptr++));
return (ptr-base);
}
int main()
{
printf("%d",somefunc("HELLO"));
return 0;
}
I have coded the following function that will reverse a String in C:
void reverse(char *str) {
int length = strlen(str) - 1;
for (int i=0; i < length/2; i++) {
char tmp = str[i];
str[i] = str[length - i];
str[length - i] = tmp;
}
}
This works if I do this:
char a[]="Hello";
reverse(a);
But if I call it passing a string literal, such as:
char *a = "Hello";
It won't work.
So, how would I modify my function so that it can accept string literals and reverse them?
You can not do that, string literals are constants in C
Perhaps, you need to copy the string, much like you do it in your first example, where you initialize a char array using a string literal.
You better of copying string to some other temp string.
Use another char* to copy original string. Allocate sufficient memory.
Copy sources string to this one. Don't forget to null terminate it.
reverse..
Dont forget to free this memory after use.
char *a1 = "Hello";
char* copy_a1 = malloc(sizeof(char)*(strlen(a1)+1));
strncpy(copy_a1, a1, strlen(a1));
copy_a1[strlen(a1)] = '\0';
reverse(copy_a1);
//free memory used.
The problem is C history.
char *a = "Hello"; should be const char *a = "Hello";. But const came in after C was successful so char *a = "Hello"; was allowed to remain OK syntax.
Had code been const char *a = "Hello";, reverse(a); would generate a warning (or error).
To modify create something like:
char *reverse(char *dest, const char *src);
How would I append a char to string that has no initial value in the following method I've started:
void append(char a) {
const char *str;
char *ret = malloc (strlen(str)+2);
strncpy(str,strlen(str),ret);
ret[strlen(str)-2] = a;
ret[strlen(str)-1] = 0;
printf("%s", str);
}
I've tried a few different answers to other questions but none have worked, please help.
Since the pointer str is not initialized, you can't add characters to what it points at. What makes sense depends on what you're going to do next. Since you don't return a value from the function, you can't access the string to which a is appended unless append calls some other function.
char *str; is not a string. It is a mnemonic that says that *str will give you a value which is supposedly a character.
str is a pointer that points at random. Make it point to an allocated bunch of memory first.
Do something like- str = malloc(100); and then do a *(str+1) = a and then a *(str+2) = '\0' to NULL terminate the string.
how about something like:
char * append(char a, const char * str)
{
char *ret = malloc (strlen(str)+2);
strncpy(str,strlen(str),ret);
ret[strlen(str)-2] = a;
ret[strlen(str)-1] = 0;
return ret;
}
Assume that you have a link like http://1.1.1.1/test.mpg. Then you want to change it to http://1.1.1.1/test.mkv. How can you change "mpg" to "mkv" programmatically in C? I tried to use strtok and strcpy but I am not good in C so I couldn't do it.
The following is the solution, but there is one thing left to you for experimenting!
The malloc'ed memory is not free'd in the below code. Try it on your own!
One other drawback is, it does replace only the first occurrence of the string.. So you cna improve this code to replace all the occurrence of the string!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * strrep(char *str, char *o_s, char *n_s)
{
char *newstr = NULL;
char *c = NULL;
/* no substring found */
if ((c = strstr(str, o_s)) == NULL) {
return str;
}
if ((newstr = (char *) malloc((int) sizeof(str) -
(int) sizeof(o_s) +
(int) sizeof(n_s) + 1)) == NULL) {
printf("ERROR: unable to allocate memory\n");
return NULL;
}
strncpy(newstr, str, c-str);
sprintf(newstr+(c-str), "%s%s", n_s, c+strlen(o_s));
return newstr;
}
int main(void)
{
char str[] = "http://1.1.1.1/test.mpg";
char old_s[] = "mpg";
char new_s[] = "mkv";
char *str_new = strrep(str, old_s, new_s);
if (str_new != NULL) {
printf("Original : %s\n", str);
printf("Replaced : %s\n", str_new);
}
return 0;
}
$ gcc strrep.c
$ ./a.out
Original : http://1.1.1.1/test.mpg
Replaced : http://1.1.1.1/test.mkv
$
You shouldn't change a const char*. Changing it will lead to undefined behavior. Usually, a const is there for a reason.
That aside, you should create a new char*, copy the contents inside it, and modify that.
Changing a character from a const char * should not be allowed by the compiler, and if done via an explicit cast to char * will lead to undefined behaviour.
If you declare the string as an array that is stored either globally or on the stack:
char str[] = "http://1.1.1.1/test.mpg";
Then you are not dealing with const char * and altering characters is OK. Otherwise,
char *str = "http://1.1.1.1/test.mpg";
the string literal will possibly be stored in a read-only protected area of the process and an attempt to write there will most probably generate a protection fault.
A const char * pointer cannot and must not be changed. This is indicated by the const, that obviously tells that this pointer points to constant characters.
If you need to change something in this variable programatically your only choice is to first copy it to another variable of sufficient size and change that. For this you can just change the last few bytes by using array indexing. Something like this will work:
const char * url = "http://1.1.1.1/test.mpg";
char * url2;
url2 = malloc( strlen( url ) + 1 );
strcpy( url2, url ); // no need to use strncpy
url2[ strlen( url2 ) - 3 ] = 'm';
url2[ strlen( url2 ) - 2 ] = 'k';
url2[ strlen( url2 ) - 1 ] = 'v';
Note that in this case this only works so smoothely, because the length of "mkv" and "mpg" is the same. If it is not you need some more complicated techiques.
I'm trying very hard to figure out a way to parse a string and "highlight" the search term in the result by making it uppercase.
I've tried using strstr and moving a pointer along and "toupper"ing the characters, to no avail.
char * highlight( char *str, char *searchstr ) {
char *pnt=str;
int i;
pnt=strstr(str,searchstr);
while(pnt){
printf("ststr retured: %s\n", pnt);
for(i=0;i<strlen(searchstr);i++) {
printf("%c",toupper(pnt[i]));
}
printf("\n");
pnt=pnt+strlen(searchstr);
pnt=strstr(pnt,searchstr);
}
return str;
}
Any advice is greatly appreciated.
Since Schot mentioned every occurrence:
#include <string.h>
char *highlight(char *str, char *searchstr) {
char *pnt = str;
while (pnt = strstr(pnt, searchstr)) {
char *tmp = searchstr;
while(*(tmp++)) { *pnt = toupper(*pnt); pnt++; }
}
return str;
}
int main() {
char s[] = "hello world follow llollo";
char search[] = "llo";
puts(highlight(s, search));
return 0;
}
output is:
$ ./a.out
heLLO world foLLOw LLOLLO
You appreciate that the function takes the string as an argument and then returns that same string, while having -not- modified that string? all the function does is print to stdout the capital characters.
At some point, you would need to change the string itself, e.g.;
pnt[i] = toupper( pnt[i] );
Like Blank Xavier said, you probably want to modify the actual string. toupper does not change the value of the character you supply, but returns a new character that is its uppercase version. You have to explicitly assign it back to the original string.
Some additional tips:
Never do multiple strlen calls on a string that doesn't change, do it once and store the result.
You can express the promise of not changing searchstr by declaring it as const char *.
Below is an example with a (in my opinion) easy method of looping through all strstr matches:
#include <string.h>
#include <ctype.h>
char *highlight(char *s, const char *t)
{
char *p;
size_t i, len = strlen(t);
for (p = s; (p = strstr(p, t)); p += len)
for (i = 0; i < len; i++)
p[i] = toupper(p[i]);
return s;
}