As a learning technique, i'm suppose to make my own copy of the following string function in
char * mystrcpy(char *a, char *b);
// string copy. destroys a but not b.
// identical to strcpy in <string.h>
// running time O(mystrlen(b))
I've come with this
char * mystrcpy(char *a, char *b){
a = b;
return a;
}
since string a is a random chuck in memory I'm thinking to assign just to string b ... is my interpretation correct ?
accessing a specific char [in index i] in string is done using a[i], just like an array. [remember that in C, a string is actually an array of chars].
You should iterate the strings until you "see" a '\0' char - which indicate the end of string.
Yes, comparing to chars with operator< is comparing them by their ascii value - which is probably what you need.
Related
I am creating a program and part of it needs to take a word, and jumble the letters.
I know that there is officially no string data type within C, so technically the characters in the word are already in array? They just need sorting. (That is my understanding anyway).
I also know that C isn't very good for actual random numbers, I normally use the time as the seed, not sure if this would affect shuffling the letters.
For instance:
The word Hello
Split into Characters H/E/L/L/O
Shuffled E/L/O/H/L
New word Elohl
technically the characters in the word are already in array?
You can treat them like a null-terminated array of characters. Apply your favorite shuffle algorithm to the portion of the string between 0, inclusive, and strlen(str), exclusive to produce a shuffled string.
The only catch here is that not all strings can be shuffled in place. Specifically, strings representing string literals are not writable. Trying to change them would lead to undefined behavior.
For example, if you do
char *word = "hello";
shuffle(word);
and try to modify word's characters inside shuffle, you would get undefined behavior. You need to copy the content into a writable array before you can shuffle the content - for example, like this:
char word[] = "hello";
shuffle(word);
int compare(const void *a, const void *b){
return *(const char *)a - *(const char *)b;
}
char arr[] = "dbaurjvgeofx";
printf("Unsorted: %s\n", arr);
qsort(arr, strlen(arr), 1, compare);
printf("Sorted: %s\n", arr);
I am trying to swap two strings by using only pointer notation, (no arrays), with
a function that looks like this
void str_switch(char *a, char *b)
the swapping should work irrespective of the sizes of b and a, and it is not known.
my idea is this:
void str_switch(char *a, char *b) {
const char *temp = a;
strcpy(b, temp);
}
however, after this, I am not sure how to copy b to a, because b changes, I tried declaring other constant pointers, but once I change b, I can never get the old version.
This strays from your question, heading in particular as strcpy is not used, and follow your comment to Martin James:
void str_switch(char **a, char **b) {
char *tmp = *a;
*a = *b;
*b = tmp;
}
If you really want to use strcpy you'll have to know size of C-strings.
if your strings are stored in allocated memories using functions like malloc(); thus this code works perfectly for that case, especially as it treats strings with different size and length
#include <stdio.h> // list of libraries that need to be included
#include <stdlib.h>
#include <string.h>
void str_switch(char **a, char **b) {
if (strlen(*a)>strlen(*b)) // check the strings with lowest size to reallocate
{ // in order to fit the big one
char *temp=malloc((strlen(*a)+1)*sizeof(char)); // temp variable to preserve the lowest
// the variable with lowest length
strcpy(temp,*a); // store the longest string in its new location
strcpy(*a,*b);
free(*b); // free the allocated memory as we no longer need it
*b=temp; // assign the new address location for the lowest string
}
else if (strlen(*b)>strlen(*a)) // the same as above but invert a to b and b to a
{
char *temp=malloc((strlen(*b)+1)*sizeof(char));
strcpy(temp,*b);
strcpy(*b,*a);
free(*a);
*a=temp;
}
else // if the lengths are equal ==> #Morpfh solution
{
char *tmp = *a;
*a = *b;
*b = tmp;
}
}
This is a test for function above (main code)
int main(int argc, char *argv[])
{
char *a=malloc(sizeof(char)*6);
strcpy(a,"hello");
char *b=malloc(sizeof(char)*4);
strcpy(b,"bye");
printf("a=%s\nb=%s\n",a,b);
str_switch(&a,&b);
printf("----------------------\n");
printf("a=%s\nb=%s\n",a,b);
return 0;
}
and we get
a=hello
b=bye
----------------------
a=bye
b=hello
If you don't want to allocate extra storage, you would need to switch the strings by swapping one character at a time.
If you are OK allocating extra storage, strdup a, strcpy b into a, strcpy the copy of a into b, then free the copy.
I am a beginner in C. I wanted to make strcat function using pointers. I made it but don't know what is wrong with it. I used gcc compiler and it gave segmentation fault output.
#include<stdio.h>
#include<string.h>
char scat(char *,char *);
void main()
{
char *s="james";
char *t="bond";
char *q=scat(s,t);
while(*q!='\0') printf("the concatenated string is %c",*q);
}
char *scat(char *s,char *t)
{
char *p=s;
while(*p!='\0'){
p++;
}
while(*t!='\0'){
*p=*t;
p++;
t++;
}
return p-s-t;
}
This one works:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *scat(char *,char *); /* 1: your prototype was wrong */
void main()
{
char *s="james";
char *t="bond";
char *q=scat(s,t);
printf("cat: %s\n", q); /* 2: you can use %s to print a string */
free(q);
}
char *scat(char *s,char *t)
{
char *p=malloc(strlen(s)+strlen(t)+1); /* 3: you will have to reserve memory to hold the copy. */
int ptr =0, temp = 0; /* 4 initialise some helpers */
while(s[temp]!='\0'){ /* 5. use the temp to "walk" over string 1 */
p[ptr++] = s[temp++];
}
temp=0;
while(t[temp]!='\0'){ /* and string two */
p[ptr++]=t[temp++];
}
return p;
}
You have to allocate new space to copy at the end of s. Otherwise, your while loo[ will go in memory you don't have access to.
You shoul learn about malloc() here.
It is undefined behaviour to modify a string literal and s, and eventually p, is pointing to a string literal:
char* s = "james";
s is passed as first argument to scat() to which the local char* p is assigned and then:
*p=*t;
which on first invocation is attempting to overwite the null character an the end of the string literal "james".
A possible solution would be to use malloc() to allocate a buffer large enough to contain the concatentation of the two input strings:
char* result = malloc(strlen(s) + strlen(p) + 1); /* + 1 for null terminator. */
and copy them into it. The caller must remember to free() the returned char*.
You may find the list of frequently asked pointer questions useful.
Because p goes till the end of the string and then it starts advancing to illegal memory.
That is why you get segmentation fault.
It's because s points to "james\0", string literal & you cannot modify constant.
Change char *s="james"; to char s[50]="james";.
You need to understand the basics of pointers.
a char * is not a string or array of characters, it's the address of the beginning of the data.
you can't do a char * - char* !!
This is a good tutorial to start with
you will have to use malloc
You get a segmentation fault because you move the pointer to the end of s and then just start writing the data of p to the memory directly following s. What makes you believe there is writable memory available after s? Any attempt to write data to non-writable memory results in a segmentation fault and it looks like the memory following s is not writable (which is to expect, since "string constants" are usually stored in read-only memory).
Several things look out of order.
First keep in mind that when you want to return a pointer to something created within a function it needs to have been malloc'ed somewhere. Much easier if you pass the destination as an argument to the function. If you follow the former approach, don't forget to free() it when you're done with it.
Also, the function scat has to return a pointer in the declaration i.e. char *scat, not char scat.
Finally you don't need that loop to print the string, printf("%s", string); will take care of printing the string for you (provided it's terminated).
At first, your code will be in infinte loop because of the below line. you were supposed to use curely braces by including "p++; t++ " statements.
while(*t!='\0')
*p=*t;
though you do like this, you are trying to alter the content of the string literal. which will result in undefined behavior like segmentation fault.
A sequence of characters enclosed with in double quotes are called as string literal. it is also called as "string". String is fixed in size. once you created, you can't extend its size and alter the contents. Doing so will lead to undefined behavior.
To solve this problem , you need to allocate a new character array whose size is sum of the length of two strings passed. then append the two strings into the new array. finally return the address of the new array.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* scat(char *,char *);
void append(char *t , char *s);
int main(void)
{
char *s="james";
char *t="bond";
char *n = scat(s,t);
printf("the concatenated string is %s",n);
return 0;
}
char* scat(char *s,char *t)
{
int len = strlen(s) + strlen(t);
char *tmp = (char *)malloc(sizeof(char)* len);
append(tmp,s);
append(tmp,t);
return tmp;
}
void append(char *t , char *s)
{
//move pointer t to end of the string it points.
while(*t != '\0'){
t++;
}
while( *s != '\0' ){
*t = *s;
t++;
s++;
}
}
This is to convert from char pointer into char.
I followed the codes from another topic but it seems like it's not working to me.
I am using Open VMS Ansi C compiler for this. I don't know what's the difference with
another Platform.
main(){
char * field = "value1";
char c[100] = (char )field;
printf("c value is %s",&c);
}
the output of this is
c value is
which is unexpected for me I am expecting
c value is value1
hope you can help me.
strcpy(c, field);
You must be sure c has room for all the characters in field, including the NUL-terminator. It does in this case, but in general, you will need an if check.
EDIT: In C, you can not return an array from a function. If you need to allocate storage, but don't know the length, use malloc. E.g.:
size_t size = strlen(field) + 1; // If you don't know the source size.
char *c = malloc(size);
Then, use the same strcpy call as before.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char * field = "value";
char c[100]="";
strncpy(c,field,100);
printf("c value is %s",c);
return 0;
}
In C, the char type holds a single character, not a string. char c[100]; doesn't allocate a char of length 100, it allocates an array of 100 consecutive chars, each one byte long, and that array can hold a string.
So what you seem to want to do is to fill an array of chars with the same char values that are at the location pointed at by a char *. To do that, you can use strncpy() or any of several other functions:
strncpy(c,field,100); /* copy up to 100 chars from field to c */
c[99] = '\0'; /* ..and make sure the last char in c is '\0' */
..or use strcpy() since you know the string will fit in c (better in this case):
strcpy(c,field);
..or:
snprintf(c,100,"%s",field);
I tried to code a function which replace all string s1 to s2, in a given string s.
however, i don't know why my program stop at the line *p=0 in that replace function without any error reported? ##
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void replace(char * s, char * s1, char * s2) {
char * p; int l=strlen(s2);
while ((p=strstr(s,s1))) {
*p=0;
p+=l;
strcat(s,s2);
strcat(s,p);
}
}
int main(void) {
char *s=(char *)"cmd=ls+-la&abc=xyz";
replace (s, "+", " ");
printf("%s", s);
return EXIT_SUCCESS;
}
There are some problems with the replace function but, first of all, there is a big difference between a pointer to a constant char array vs a character array:
char *str = "some string";
Assigns str the address of the immutable character array (read-only), it does not copy the string, only pointers are involved. Any attempt to modify that string will result in undefined behavior.
char str[] = "some string";
In this case str is an array (of size big enough to hold the string + \0) that is initialized to that string, allowing the modification of individual characters within the array.
Back to your replace function.
I will start with the first thing that I saw which is your use of strstr and strcat inside the loop is highly inefficient. Every time you call strstr it starts from the beginning of the string and searches for the first occurrence of the second string all over, the same problem can be seen with strcat which needs to find the null-terminator every time.
Another issue I see is if the replacement string (s2) is longer than the original string (s1) you must shift the entire string to accommodate for the additional characters of the new string. The same issue will occur if the replacement string is shorter.
a basic method to replace a simple char might look like this:
while (*s)
{
if (*s == c1)
*s = c2;
++s;
}
a little more complex method to replace a string would be:
/* PRECONDITION: strlen(s1) == strlen(s2) */
int l = strlen(s2);
while (*s)
{
if (!strncmp(s, s1, l))
{
memcpy(s, s2, l);
s += l;
}
else
++s;
}
Your compiler is allowed to place string literals into read-only memory, which is probably what it did with s.
Try:
char s[] = "cmd=ls+-la&abc=xyz";
This changes s from a pointer to a string literal into an array initialized with your string.