[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 844
  • Last Modified:

Simple C Question - Splitting a string

Hey What is the best way to
take a string and make a new string from its first two characters ?
Thanks Foggy
0
paddyOBrien
Asked:
paddyOBrien
  • 9
  • 5
  • 3
  • +2
1 Solution
 
Sjef BosmanGroupware ConsultantCommented:
The fastest:

char *s= "abcdef";
char news[3];

news[0]= *s++;
news[1]= *s;
news[2]= '\0';

What's your code, 'coz this isn't probably what you want...
0
 
Sjef BosmanGroupware ConsultantCommented:
There's also strncpy, where you can set how long a string is to be. See your manual
0
 
MercantilumCommented:
Yes, sjef, you were the fastest :)
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
PerryDKCommented:
Since your in the C group I will assume you don't have access to std::string which is availble in C++ and you have to be using char* as your strings.

char* oldStr = "hello";

#define MAX_SUB_STRING_LENGTH 10
char subStr[10];

void getSubString(char* source, char* dest, int index, int count)
{
  memcpy(dest, &source[index], count);
  dest[count] = '\0';
}


now to get your first two characters just do this

getSubString(oldStr, subStr, 0, 2);

subStr will now contain a string with just the first two characters of oldStr
0
 
MercantilumCommented:
Well, in this case, you could do this which creates dynamically a string

#include <stdlib.h>
#include <string.h>

// return pointer to an allocated string of length chars (length+1 for trailing 0)

char *make_new_string (char *source, int length)
{
    char *alloc;

    alloc = malloc (length+1);
    strncpy (alloc, source, 2);
    alloc[2] = 0;
    return (alloc);
}

// main

int main ()
{
   char *firststring = "cool bool";
   char *second;

    second = make_new_string (firststring, 50);

     printf ("%s  %s\n", firststring, second);
}

Somebody gets an idea for a recursive func ??
0
 
PerryDKCommented:
Mercantilum,

In gerneral I would steer clear of returning allocated memory from a function.  Its best to have the user allocate his own memory and pass it into the function.  The problem with having a function returning allocated memory is that the user then becomes responsible for knowing the implementation details of the function and know that for this function they are explicitly responsible for deallocting the memory that was returned from the function.

If you force the user to allocate his own memory and then pass it into the function...the user is aware that he allocated the memory and is thus already aware that he is responsible for deallocating it.

Case In point...your main function has a memory leak :)
You did not deallocate the memory that the variable second is pointing too.
0
 
MercantilumCommented:
In this case the user creates the function and uses it himself :)
0
 
PerryDKCommented:
Even if you are the end user I would still stay clear of returning allocated memory in a function.  You the user created the function so you know of the implemention details.  Even with that knowledge you still forgot to deallocate before your main function ended.  Once your program gets big enough it will be impossible to keep every little detail in your head.  Even if you are the end user of the function, returning allocated memory from a function still creates a little detail that you have to be aware of.  Its just good programming practice to minimise the number of things that you have to keep track of all the time.
0
 
MercantilumCommented:
He Perry all here agree that it is better not to let the caller free the mem alloc by the func :)
we are trying to find a way to answer the question - this is one of them... come on...
0
 
PerryDKCommented:
Sorry wasn't trying to offend you was just trying to point out the potential for errors with that particular solution.

The author already has 3 viable solutions...he must have forgot about his question :)
0
 
MercantilumCommented:
Ok, by the way

1.  I don't think it is good practice to teach a program to a beginner without indicating the include, like #include <string.h> for memcpy.
Can be dangerous if the compiler doesn't warn.

2.  To copy a substring better to use strncpy - name fits better than memcpy. Especially in your case where you copy n bytes, even if the source could be much less than n bytes :)

3.  These copy functions are usually (dest, source) and not the opposite - not a good practice to do the opposite of the libs

4.  The char *oldStr should have been declared as static.

5.  I don't think it is the best practice to use global vars.

no offense :)
0
 
PerryDKCommented:
you have valid points and I agree with all of them.  
0
 
MercantilumCommented:
I know it is usually not considered as a good practice to use recursive funcs  :)

#include <stdio.h>

// copyn copies n chars, 1 char at a time and set the trailing (char)0 :)

static void copyn (char *dest, const char *source, int n)
{
  if (n <= 0) *dest = (char)0;
  else
  {
    *dest = *source;
    copyn (dest+1, source+1, n-1);
  }
}

// example of main ()

int main ()
{
  const char *from = "what about that";
  char to[10];

  copyn (to, from, 2);

  printf ("'%s' '%s'\n", from, to);

  return (0);
}
0
 
MercantilumCommented:
AND there is no control of size limit, e.g. if 'dest' is not big enough, copy will go beyond its limits (length of 9 in this case :)
(ouf!)
0
 
skypalaeCommented:
Hi guys,
fine discussion here. I don't understand the words "best way"? Is it "fastest" or "shortest" or "most compatible"?

the fastest (and shortest i think) would be:
    char s1[] = "abcd" ; // directly on the stack
    char *s2 = s1 ; // indirect

    char d1[3] ; // directly on the stack
    char *d2 = d1 ; // indirect

    // if you need allways and only the 2byte string, you can keep the 3rd byte allways '\0'
    // so if you're getting the 2byte string in a loop you can ceep the following outside the loop
    d1[3] = '\0' ;

    // typing the arrays to word size compiles the assignment into 2-4 assembler instructions (depending on strings declaration)
    ((short*)d1)[0] = ((short*)s1)[0] ;
    // mov         dx,word ptr [ebp-8]
    // mov         word ptr [ebp-10h],dx
    ((short*)d1)[0] = ((short*)s2)[0] ;
    // mov         eax,dword ptr [ebp-0Ch]
    // mov         cx,word ptr [eax]
    // mov         word ptr [ebp-10h],cx
    ((short*)d2)[0] = ((short*)s1)[0] ;
    // mov         edx,dword ptr [ebp-14h]
    // mov         ax,word ptr [ebp-8]
    // mov         word ptr [edx],ax
    ((short*)d2)[0] = ((short*)s2)[0] ;
    // mov         ecx,dword ptr [ebp-14h]
    // mov         edx,dword ptr [ebp-0Ch]
    // mov         ax,word ptr [edx]
    // mov         word ptr [ecx],ax

but creating the 2char string from bigger string is fast enough that you needn't to count the assembler instructions (especially on machines like PPro 2GHz :))

the most compatible would be (as you pointed) use strncpy() function

Cheers! S.
0
 
paddyOBrienAuthor Commented:
Hi I actually have access to std:string as it is in C++. How would that make it easier ?
0
 
MercantilumCommented:
string first = "abracadabra";
string second = first.substr (0, 2);
0
 
MercantilumCommented:
If you want to try at home :)

#include <iostream>
#include <string>

using namespace std;

// copy 2 first chars of first into second
// then print the 2 values

int main()
{
    string first = "abracadabra";
    string second = first.substr (0, 2);
    cout << first     << endl;
    cout << second << endl;
}
0
 
paddyOBrienAuthor Commented:
Thanks for all the help people
Much appreciated
Points to Mercantilum
Thank you :-)
0
 
Sjef BosmanGroupware ConsultantCommented:
So it was a simple C++ question! Wrong TA...

Sjef :(
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 9
  • 5
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now