PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.c > replace substring
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
replace substring

Réponse
 
LinkBack Outils de la discussion
Vieux 26/05/2008, 08h06   #1
magix
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut replace substring

Hi,

I have
char* str1 = "d:\temp\data\test.txt"

I want to replace all the "\" to be "\\", so that

the string will have "d:\\temp\\data\\test.txt"

Can you ?

Regards,
Magix

  Réponse avec citation
Vieux 26/05/2008, 08h29   #2
James Dow Allen
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

On May 26, 2:06pm, magix <mag...@gmail.com> wrote:
> I want to replace all the "\" to be "\\", so that


Try
sed ss\\\\s\\\\\\\\sg

YMMV

James Dow Allen
  Réponse avec citation
Vieux 26/05/2008, 09h33   #3
Richard Heathfield
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

magix said:

> Hi,
>
> I have
> char* str1 = "d:\temp\data\test.txt"


If you have that, you're in trouble, because \d isn't a valid escape
sequence. \t is, but I don't think you really wanted embedded tabs in that
string, did you?

> I want to replace all the "\" to be "\\", so that
>
> the string will have "d:\\temp\\data\\test.txt"
>
> Can you ?


char *str1 = "d:\\temp\\data\\test.txt";

If that doesn't fix your problem, you need to clarify what your problem is.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
  Réponse avec citation
Vieux 26/05/2008, 09h45   #4
Martin Ambuhl
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

magix wrote:
> Hi,
>
> I have
> char* str1 = "d:\temp\data\test.txt"
>
> I want to replace all the "\" to be "\\", so that
>
> the string will have "d:\\temp\\data\\test.txt"
>
> Can you ?


The string to which str1 points is a string literal, and you should not
attempt to modify it. String literals are usually not modifiable and in
any case your new string takes more space than the string literal does,
so even if you could modify it, you would overrun the end of it.

You need to allocate an array of sufficient space for the new string
(including the terminating zero-byte) and then something like

/* warning: neither tested nor written to be bulletproof
(or even dart-resistant) */
void replaceslash(char *source, char *target)
{
for (;*source; source++)
{
if (*source = '\\') *target++ = *source;
*target++ = *source;
}
}

Now, the code above simply produces two '\\' when it sees one.
But on almost any system, it makes more sense to replace '\\' with '/'
(even windows and dos have no problem with this), when the above
then becomes
void replaceslash(char *source, char *target)
{
for (;*source; source++)
{
if (*source = '\\') *target++ = '/';
else *target++ = *source; /* notice the else! */
}
}
  Réponse avec citation
Vieux 26/05/2008, 10h20   #5
Jens Thoms Toerring
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

magix <magix8@gmail.com> wrote:
> I have
> char* str1 = "d:\temp\data\test.txt"


> I want to replace all the "\" to be "\\", so that


> the string will have "d:\\temp\\data\\test.txt"


You can't change the above string at all. What you have
there is a pointer that points to memory that you are
not allowed to change - it could be read-only memory.

Now, if you change the definitionof 'str1' to

char str1[ ] = "d:\temp\data\test.txt";

things already look a bit better since now 'str1' isn't
just a pointer but a real array, initialized with
the string. And that's now something you can change.
But you couldn't double just one character in that
array since it simply isn't large enough to hold
one more character. To add something to the string
you would first have to get hold of memory where
the resulting string would fit in.

But there is another problems. There's not a single
backslash in that string! E.g. "\t" isn't a backslash
followed by the character 't' but it's the escape
sequence for the tab character. And '\d' is not even
a valid escape sequence, so the compiler will try to
warn you and drop the backslash. If you try to print
that string anyway you will get something like

d: empdata est.txt

(the details depending on the tab settings on your
machine). So there actually isn't a single backslash
character in your 'str1' since the single backslash
characters you wrote in there are always taken to
"escape" the following character. Whenever you
see a backslash in a string in C (or a character
constant like '\t') remember that this is just a
kind of "operator", changing the meaning of the
following character in the string. And to get a
real baclslash character you have to write '\\'
since the backslash "escapes" itself.

Thus if you want backslashes in the string you have to
double them already when you write the string in order
to end up with single backslashes within it at all.
Putting in two backslashes in a row results in a
single backslash character in the string. If you do
that like this

char str1[ ] = "d:\\temp\\data\\test.txt";

then 'str1' contains three (not six) backslashes. And
I guess you're not really interested in doubling those
anymore.
Regards, Jens

PS. If I am not completely misinformed you can also
use a normal slash '/' as a path separator under
Windows (what I guess you're using from the 'd:'
at the start of the string) in a C program. So if
this is supposed to be a path you could use

char str1[ ] = "d:/temp/data/test.txt";

and pass that to e.g. fopen() and it should still
work as intended.
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
  Réponse avec citation
Vieux 26/05/2008, 21h00   #6
Bartc
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring


"magix" <magix8@gmail.com> wrote in message
news:debb18bd-c54b-4446-b60f-fc675d2e1aa2@p25g2000pri.googlegroups.com...
> Hi,
>
> I have
> char* str1 = "d:\temp\data\test.txt"
>
> I want to replace all the "\" to be "\\", so that
>
> the string will have "d:\\temp\\data\\test.txt"
>
> Can you ?


If str1 really contains those slashes, then it already represents a valid
Windows filename, if that was the idea.

Doubling up the slashes I think still yields a valid filename, but is
unnecessary.

But if that is initialisation code from a C program, the slashes will be
converted or ignored.

Assuming however you do have such a string and want to double up the
slashes, I tried this somewhat fiddly code. You may want to put str1=str2 at
the end, but is anyway just to give an idea. Note the double \\ characters
here are really single.


/* Duplicate \ characters in a string */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
char* str1 = "d:\\temp\\data\\test.txt"; /* old string (in const memory)
*/
char* str2 = NULL; /* new string (to be in heap memory) */
char *p,*q;
char c;
int i,len,slashes;

slashes=0;
len=strlen(str1);

for (i=0; i<len; ++i) /* Calculate size of new string */
if (str1[i]=='\\')++slashes;

str2=malloc(len+slashes+1);

if (str2!=NULL) {
p=str1;
q=str2;
while (c=*p++) {
*q++ = c;
if (c=='\\') *q++ = '\\';
};
*q++ = 0;
printf("STR1 = %s\n",str1);
printf("STR2 = %s\n",str2);

// free(str2);
}
else
puts("No memory");

}



  Réponse avec citation
Vieux 26/05/2008, 21h31   #7
Keith Thompson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

magix <magix8@gmail.com> writes:
> I have
> char* str1 = "d:\temp\data\test.txt"
>
> I want to replace all the "\" to be "\\", so that
>
> the string will have "d:\\temp\\data\\test.txt"
>
> Can you ?


You're going to need to be clearer about what you have and what you
want.

Do you mean that you have a declaration:

const char* str1 = "d:\temp\data\test.txt";

(note: I added the "const" and the semicolon) *in a C source file*,
and you want to modify the C source file so the declaration is

const char* str1 = "d:\\temp\\data\\test.txt";

? If so, I'd say the best tool for the job is a text editor; just add
the extra backslashes and save the file. But that's so trivial that I
suspect it's not really what you were asking.

If you want to modify a large number of such incorrect declarations,
it's going to be difficult. For one thing, backslashes can appear
legitimately in string literals; you wouldn't want to change
"hello, world\n"
to
"hello, world\\n"
.. I can imagine ways to detect which string literals should be
translated and which should be left alone, but it can't be done 100%
reliably, and I wouldn't even make the attempt without a lot more
information.

If you mean that you want to leave the declaration alone and change
the value of the string at run time, you're pretty much out of luck
(and fixing the declaration is a much better idea anyway).

Tell us what you're really trying to do, and we can probably .

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
  Réponse avec citation
Vieux 29/05/2008, 19h47   #8
Antoninus Twink
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

On 26 May 2008 at 7:32, CBFalconer wrote:
> The copy part will look something like:
>
> while (*p1) {
> if ('\' == (*p2++ = *p1++)) *p2++ = '\';
> }


It won't look like that if you want it to pass a code review in any
professional environment. Blech.

  Réponse avec citation
Vieux 30/05/2008, 15h48   #9
Richard
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

CBFalconer <cbfalconer@yahoo.com> writes:

> magix wrote:
>>
>> I have
>> char* str1 = "d:\temp\data\test.txt"
>>
>> I want to replace all the "\" to be "\\", so that
>> the string will have "d:\\temp\\data\\test.txt"
>>
>> Can you ?

>
> No. str1 is a non-writable string. You can create str2 and copy
> str1, with modifications, into it. The copy part will look
> something like:
>
> while (*p1) {
> if ('\' == (*p2++ = *p1++)) *p2++ = '\';
> }


Note to magix : never, ever lay your code out like this or it will be
laughed out of any code review. Multiple statements on line might save a
little bit vertical real estate but are a pain in the behind to debug
and read. Others might disagree. Only you can decide.

Something like (not compiled or tested but you get the meaning I hope)

char c;
while (c = *d++ = *s++) { /* s==source, d==destination */
if (c=='\')
*d++ = '\';
}

  Réponse avec citation
Vieux 30/05/2008, 16h31   #10
Ben Bacarisse
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

Richard<rgrdev@gmail.com> writes:

> CBFalconer <cbfalconer@yahoo.com> writes:
>
>> magix wrote:

<a question about doubling \s>
>>> Can you ?

<snip>
>> while (*p1) {
>> if ('\' == (*p2++ = *p1++)) *p2++ = '\';
>> }

>
> Note to magix : never, ever lay your code out like this or it will be
> laughed out of any code review. Multiple statements on line might save a
> little bit vertical real estate but are a pain in the behind to debug
> and read. Others might disagree. Only you can decide.
>
> Something like (not compiled or tested but you get the meaning I hope)
>
> char c;
> while (c = *d++ = *s++) { /* s==source, d==destination */
> if (c=='\')
> *d++ = '\';
> }


The layout is up to you, of course, but you've altered the semantics.

--
Ben.
  Réponse avec citation
Vieux 30/05/2008, 17h26   #11
Richard Harter
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

On Fri, 30 May 2008 16:48:42 +0200, Richard<rgrdev@gmail.com>
wrote:

>CBFalconer <cbfalconer@yahoo.com> writes:
>
>> magix wrote:
>>>
>>> I have
>>> char* str1 = "d:\temp\data\test.txt"
>>>
>>> I want to replace all the "\" to be "\\", so that
>>> the string will have "d:\\temp\\data\\test.txt"
>>>
>>> Can you ?

>>
>> No. str1 is a non-writable string. You can create str2 and copy
>> str1, with modifications, into it. The copy part will look
>> something like:
>>
>> while (*p1) {
>> if ('\' == (*p2++ = *p1++)) *p2++ = '\';
>> }

>
>Note to magix : never, ever lay your code out like this or it will be
>laughed out of any code review. Multiple statements on line might save a
>little bit vertical real estate but are a pain in the behind to debug
>and read. Others might disagree. Only you can decide.
>
>Something like (not compiled or tested but you get the meaning I hope)
>
> char c;
> while (c = *d++ = *s++) { /* s==source, d==destination */
> if (c=='\')
> *d++ = '\';
> }
>


Obscene noises and horselaughs. I doubt that I would
intentionally hire anyone who objected to CFB's code, which uses
standard C idioms. More strongly, in my opinion anyone who has
difficulty reading it or debugging probably has made a bad career
choice.

Note that CFB's code does not have multiple statements on one
line.

Also I do not like your suggested alternative. Let me count the
ways. YMMV of course.

Introducing c is problematic. In C89 it will need to be at the
beginning of the block in which the loop is contained breaking
the connection between the declaration and the code that uses it.
More importantly it is a bit of obfuscation.

I don't like the multiple assignment trick (c = *d++ = *s++).
Count that as a personal prejudice.

The lines
> if (c=='\')
> *d++ = '\';


are a definite style error. Either write

if (c=='\') *d++ = '\';

making it clear that the if controls a single statement, or

if (c=='\') {
*d++ = '\';
}

The trouble with the format that you used is that it is fragile;
it is easy to erroneously add another statement to what appears
to be a block. If you do, the code compiles and the error can be
surprisingly hard to find.









Richard Harter, cri@tiac.net
http://home.tiac.net/~cri, http://www.varinoma.com
Save the Earth now!!
It's the only planet with chocolate.
  Réponse avec citation
Vieux 30/05/2008, 17h42   #12
Keith Thompson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

CBFalconer <cbfalconer@yahoo.com> writes:
> magix wrote:
>>
>> I have
>> char* str1 = "d:\temp\data\test.txt"
>>
>> I want to replace all the "\" to be "\\", so that
>> the string will have "d:\\temp\\data\\test.txt"
>>
>> Can you ?

>
> No. str1 is a non-writable string. You can create str2 and copy
> str1, with modifications, into it. The copy part will look
> something like:
>
> while (*p1) {
> if ('\' == (*p2++ = *p1++)) *p2++ = '\';
> }


Note that '\' is a syntax error. It should be '\\'.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
  Réponse avec citation
Vieux 30/05/2008, 17h48   #13
Keith Thompson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

cri@tiac.net (Richard Harter) writes:
> On Fri, 30 May 2008 16:48:42 +0200, Richard<rgrdev@gmail.com>
> wrote:
>
>>CBFalconer <cbfalconer@yahoo.com> writes:

[...]
>>> while (*p1) {
>>> if ('\' == (*p2++ = *p1++)) *p2++ = '\';
>>> }

>>
>>Note to magix : never, ever lay your code out like this or it will be
>>laughed out of any code review. Multiple statements on line might save a
>>little bit vertical real estate but are a pain in the behind to debug
>>and read. Others might disagree. Only you can decide.

[...]
> Note that CFB's code does not have multiple statements on one
> line.


Yes, it does. It just happens that one of the statements is part of
the other statement.

(Assuming, of course, that '\' is changed to '\\'.)

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
  Réponse avec citation
Vieux 31/05/2008, 06h51   #14
rio
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring


"CBFalconer" <cbfalconer@yahoo.com> ha scritto nel messaggio
news:483A677F.950DC227@yahoo.com...
> magix wrote:
>>
>> I have
>> char* str1 = "d:\temp\data\test.txt"
>>
>> I want to replace all the "\" to be "\\", so that
>> the string will have "d:\\temp\\data\\test.txt"
>>
>> Can you ?

>
> No. str1 is a non-writable string. You can create str2 and copy
> str1, with modifications, into it. The copy part will look
> something like:


> while (*p1) {
> if ('\' == (*p2++ = *p1++)) *p2++ = '\';
> }


here there should be
*p2=0;

so "if ('\' == (*p2++ = *p1++)) *p2++ = '\';"
should be
c=*p2 = *p1; ++p1; ++p2;
if(c=='\') *p2++ = '\';




  Réponse avec citation
Vieux 31/05/2008, 13h56   #15
Joe Wright
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

rio wrote:
> "CBFalconer" <cbfalconer@yahoo.com> ha scritto nel messaggio
> news:483A677F.950DC227@yahoo.com...
>> magix wrote:
>>> I have
>>> char* str1 = "d:\temp\data\test.txt"
>>>
>>> I want to replace all the "\" to be "\\", so that
>>> the string will have "d:\\temp\\data\\test.txt"
>>>
>>> Can you ?

>> No. str1 is a non-writable string. You can create str2 and copy
>> str1, with modifications, into it. The copy part will look
>> something like:

>
>> while (*p1) {
>> if ('\' == (*p2++ = *p1++)) *p2++ = '\';
>> }

>
> here there should be
> *p2=0;
>
> so "if ('\' == (*p2++ = *p1++)) *p2++ = '\';"
> should be
> c=*p2 = *p1; ++p1; ++p2;
> if(c=='\') *p2++ = '\';
>


I think you'll all find there isn't even one '\' in the string. Does
anyone test code anymore?

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
  Réponse avec citation
Vieux 05/06/2008, 07h31   #16
Richard Harter
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

On Fri, 30 May 2008 09:48:55 -0700, Keith Thompson
<kst-u@mib.org> wrote:

>cri@tiac.net (Richard Harter) writes:
>> On Fri, 30 May 2008 16:48:42 +0200, Richard<rgrdev@gmail.com>
>> wrote:
>>
>>>CBFalconer <cbfalconer@yahoo.com> writes:

>[...]
>>>> while (*p1) {
>>>> if ('\' == (*p2++ = *p1++)) *p2++ = '\';
>>>> }
>>>
>>>Note to magix : never, ever lay your code out like this or it will be
>>>laughed out of any code review. Multiple statements on line might save a
>>>little bit vertical real estate but are a pain in the behind to debug
>>>and read. Others might disagree. Only you can decide.

>[...]
>> Note that CFB's code does not have multiple statements on one
>> line.

>
>Yes, it does. It just happens that one of the statements is part of
>the other statement.


My bad. You're right. In some languages the whole line is one
statement but not C.


>(Assuming, of course, that '\' is changed to '\\'.)


Oops, I missed that. Blush.


Richard Harter, cri@tiac.net
http://home.tiac.net/~cri, http://www.varinoma.com
Save the Earth now!!
It's the only planet with chocolate.
  Réponse avec citation
Vieux 05/06/2008, 17h01   #17
Keith Thompson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

cri@tiac.net (Richard Harter) writes:
> On Fri, 30 May 2008 09:48:55 -0700, Keith Thompson
> <kst-u@mib.org> wrote:
>>cri@tiac.net (Richard Harter) writes:
>>> On Fri, 30 May 2008 16:48:42 +0200, Richard<rgrdev@gmail.com>
>>> wrote:
>>>
>>>>CBFalconer <cbfalconer@yahoo.com> writes:

>>[...]
>>>>> while (*p1) {
>>>>> if ('\' == (*p2++ = *p1++)) *p2++ = '\';
>>>>> }
>>>>
>>>>Note to magix : never, ever lay your code out like this or it will be
>>>>laughed out of any code review. Multiple statements on line might save a
>>>>little bit vertical real estate but are a pain in the behind to debug
>>>>and read. Others might disagree. Only you can decide.

>>[...]
>>> Note that CFB's code does not have multiple statements on one
>>> line.

>>
>>Yes, it does. It just happens that one of the statements is part of
>>the other statement.

>
> My bad. You're right. In some languages the whole line is one
> statement but not C.


<NITPICK>
Well, it's one statement in C as well, it just happens to contain
another statement within it. In fact, that's the way it is in most
languages: the equivalent of "if (condition) statement" is a compound
statement that contains another statement. C isn't unusual in this
regard.
</NITPICK>

[...]

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
  Réponse avec citation
Vieux 05/06/2008, 18h08   #18
Tomás Ó hÉilidhe
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

On May 26, 8:06am, magix <mag...@gmail.com> wrote:

> char* str1 = "d:\temp\data\test.txt"
>
> I want to replace all the "\" to be "\\", so that
>
> the string will have "d:\\temp\\data\\test.txt"



Do you want to do it "in place"? If so then you'll need to be sure
that the buffer is big enough. Something like

void DoubleBackSlashes(char *src)
{
char register *dst = src;

while ((*dst++ = *src++))
{
if ('\\' == *dst)
{
*dst++ = '\\';
}
}
}
  Réponse avec citation
Vieux 05/06/2008, 23h59   #19
Barry Schwarz
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

On Thu, 5 Jun 2008 10:08:56 -0700 (PDT), Tomás Ó hÉilidhe
<toe@lavabit.com> wrote:

>On May 26, 8:06am, magix <mag...@gmail.com> wrote:
>
>> char* str1 = "d:\temp\data\test.txt"
>>
>> I want to replace all the "\" to be "\\", so that
>>
>> the string will have "d:\\temp\\data\\test.txt"

>
>
>Do you want to do it "in place"? If so then you'll need to be sure
>that the buffer is big enough. Something like
>
>void DoubleBackSlashes(char *src)
>{
> char register *dst = src;
>
> while ((*dst++ = *src++))


This doesn't work when src points to a string literal.

> {
> if ('\\' == *dst)
> {
> *dst++ = '\\';


This doesn't work at all. It destroys every character following the
first / before that character is processed.

> }
> }
>}



Remove del for email
  Réponse avec citation
Vieux 06/06/2008, 01h17   #20
CBFalconer
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

Barry Schwarz wrote:
> Tomás Ó hÉilidhe <toe@lavabit.com> wrote:
>

.... snip ...
>
>> void DoubleBackSlashes(char *src) {
>> char register *dst = src;
>>
>> while ((*dst++ = *src++)) {

>
> This doesn't work when src points to a string literal.


It works fine to copy the string except that dst cannot be equal to
src. It doesn't work for the rest.
>
>> if ('\\' == *dst) {
>> *dst++ = '\\';

>
> This doesn't work at all. It destroys every character following
> the first / before that character is processed.


Of coarse not. It is no longer testing the original src.
>
>> }
>> }


Which is why I wrote, about a week ago:

while (*p1) {
if ('\' == (*p2++ = *p1++)) *p2++ = '\';
}

with the fairly minor error that '\' should be '\\'. Note that p2
points to an independant output array. *p1 is dereferenced, but
not altered. A final *p2 = '\0' is required. A suitable variant
is:

while (ch = (*p1++ = *p2++))
if ('\\' == ch) *p2++ = '\\');

which doesn't require the final '\0' added.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.


** Posted from http://www.teranews.com **
  Réponse avec citation
Vieux 06/06/2008, 02h12   #21
Tomás Ó hÉilidhe
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

On Jun 5, 11:59pm, Barry Schwarz <schwa...@dqel.com> wrote:
> On Thu, 5 Jun 2008 10:08:56 -0700 (PDT), Tomás Ó hÉilidhe
>
>
>
>
>
> <t...@lavabit.com> wrote:
> >On May 26, 8:06am, magix <mag...@gmail.com> wrote:

>
> >> char* str1 = "d:\temp\data\test.txt"

>
> >> I want to replace all the "\" to be "\\", so that

>
> >> the string will have "d:\\temp\\data\\test.txt"

>
> >Do you want to do it "in place"? If so then you'll need to be sure
> >that the buffer is big enough. Something like

>
> >void DoubleBackSlashes(char *src)
> >{
> > char register *dst = src;

>
> > while ((*dst++ = *src++))

>
> This doesn't work when src points to a string literal.
>
> > {
> > if ('\\' == *dst)
> > {
> > *dst++ = '\\';

>
> This doesn't work at all. It destroys every character following the
> first / before that character is processed.



Oh Christ what was I thinking :-O

There's a few different ways of writing this algorithm depending upon:
* whether the original buffer is big enough
* whether memory is so scarce that you shouldn't create another
buffer
  Réponse avec citation
Vieux 06/06/2008, 02h41   #22
Joe Wright
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

Tomás Ó hÉilidhe wrote:
> On Jun 5, 11:59 pm, Barry Schwarz <schwa...@dqel.com> wrote:
>> On Thu, 5 Jun 2008 10:08:56 -0700 (PDT), Tomás Ó hÉilidhe
>>
>>
>>
>>
>>
>> <t...@lavabit.com> wrote:
>>> On May 26, 8:06 am, magix <mag...@gmail.com> wrote:
>>>> char* str1 = "d:\temp\data\test.txt"
>>>> I want to replace all the "\" to be "\\", so that
>>>> the string will have "d:\\temp\\data\\test.txt"
>>> Do you want to do it "in place"? If so then you'll need to be sure
>>> that the buffer is big enough. Something like
>>> void DoubleBackSlashes(char *src)
>>> {
>>> char register *dst = src;
>>> while ((*dst++ = *src++))

>> This doesn't work when src points to a string literal.
>>
>>> {
>>> if ('\\' == *dst)
>>> {
>>> *dst++ = '\\';

>> This doesn't work at all. It destroys every character following the
>> first / before that character is processed.

>
>
> Oh Christ what was I thinking :-O
>
> There's a few different ways of writing this algorithm depending upon:
> * whether the original buffer is big enough
> * whether memory is so scarce that you shouldn't create another
> buffer


I noted up-thread that given..

char* str1 = "d:\temp\data\test.txt";

...that str1 doesn't contain even one '\' character.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
  Réponse avec citation
Vieux 06/06/2008, 02h59   #23
Paul Hsieh
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

On May 26, 12:06 am, magix <mag...@gmail.com> wrote:
> I have
> char* str1 = "d:\temp\data\test.txt"
>
> I want to replace all the "\" to be "\\", so that
>
> the string will have "d:\\temp\\data\\test.txt"
>
> Can you ?


All the solutions posted so far are incomplete or utter nonsense. Not
too surprising, as the C language is just such garbage for dealing
with strings. Your source data is likely wrong as well, as within
strings \ is always escaped by \\ (though you might mean \t, \d, \t
characters in there, but it doesn't look like it). You want to write
to a char * string, but you have done nothing to make sure its
writable or finding storage for it. Let's try this:

char * str1 = "d:\\temp\\data\\test.txt";
char * str2 = (char *) malloc (sizeof(char) * (1 + 2 * strlen
(str1)));
if (!str2) {
char * d = str2, *s = str1;
while ('\0' != (*d = *s)) {
d++;
if ('\\' == *s) {
*d = *s;
d++;
}
s++;
}
}

return str2; /* or str1 = str2; or however else you want to do this */

Its hacky code and its very difficult to write code like the above in
a sustainable way (and I haven't reviewed it -- it might contain
bugs). A much easier solution is just to use "The Better String
Library":

bstring b = bfromcstr ("d:\\temp\\data\\test.txt");
static struct tagbstring from = bsStatic ("\\");
static struct tagbstring replace = bsStatic ("\\\\");

if (BSTR_OK != bfindreplace (b, from, replace, 0)) {
bdestroy (b);
b = NULL;
}
/* If you have the memory b will contain the post modified string.
*/

Life is too short not to have solutions like this on hand.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/ <-- URL for The Better String Library.
  Réponse avec citation
Vieux 06/06/2008, 14h54   #24
Ben Bacarisse
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

CBFalconer <cbfalconer@yahoo.com> writes:

> Barry Schwarz wrote:
>> Tomás Ó hÉilidhe <toe@lavabit.com> wrote:
>>

> ... snip ...
>>
>>> void DoubleBackSlashes(char *src) {
>>> char register *dst = src;
>>>
>>> while ((*dst++ = *src++)) {

>>
>> This doesn't work when src points to a string literal.

>
> It works fine to copy the string except that dst cannot be equal to
> src. It doesn't work for the rest.
>>
>>> if ('\\' == *dst) {
>>> *dst++ = '\\';

>>
>> This doesn't work at all. It destroys every character following
>> the first / before that character is processed.

>
> Of coarse not. It is no longer testing the original src.


I know I'll regret this but... check again. Barry Schwarz is correct
(except for the typo: writing / instead of \).

if ('\\' == *dst) *dst++ = '\\';

looks harmless (even pointless) putting, as it does, a \ where one
already exists, but because src also points there, the increment means
that the loop condition will copy the \ over whatever follows. This
causes both the loop condition and that of the nested 'if' to be
forever true. UB is guaranteed if the string contains \.

>>> }
>>> }


--
Ben.
  Réponse avec citation
Vieux 06/06/2008, 20h22   #25
Flash Gordon
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: replace substring

Paul Hsieh wrote, On 06/06/08 02:59:
> On May 26, 12:06 am, magix <mag...@gmail.com> wrote:
>> I have
>> char* str1 = "d:\temp\data\test.txt"
>>
>> I want to replace all the "\" to be "\\", so that
>>
>> the string will have "d:\\temp\\data\\test.txt"
>>
>> Can you ?

>
> All the solutions posted so far are incomplete or utter nonsense. Not


Yours is buggy.

> too surprising, as the C language is just such garbage for dealing
> with strings. Your source data is likely wrong as well, as within
> strings \ is always escaped by \\ (though you might mean \t, \d, \t
> characters in there, but it doesn't look like it). You want to write
> to a char * string, but you have done nothing to make sure its
> writable or finding storage for it. Let's try this:
>
> char * str1 = "d:\\temp\\data\\test.txt";
> char * str2 = (char *) malloc (sizeof(char) * (1 + 2 * strlen
> (str1)));


Why the sizeof(char)? You know that is is 1 by definition so putting it
is is pointless and makes the code harder to read. The cast is also
pointless and may stop the compiler from producing a warning if he
forgets to include stdlib.h

Not bugs, but not ful in my opinion.

> if (!str2) {


Urm, don't you mean "if (str2)" ? I'm sure you did not want to do the
processing if and only if the malloc call failed! This is a bug.

> char * d = str2, *s = str1;
> while ('\0' != (*d = *s)) {
> d++;
> if ('\\' == *s) {
> *d = *s;
> d++;
> }
> s++;
> }
> }


I would not seperate out all of those increments.
while ((*d++ = *s) != '\0) {
if (*s++ = '\\')
*d++ = '\\'

> return str2; /* or str1 = str2; or however else you want to do this */
>
> Its hacky code and its very difficult to write code like the above in
> a sustainable way (and I haven't reviewed it -- it might contain
> bugs). A much easier solution is just to use "The Better String
> Library":
>
> bstring b = bfromcstr ("d:\\temp\\data\\test.txt");
> static struct tagbstring from = bsStatic ("\\");
> static struct tagbstring replace = bsStatic ("\\\\");
>
> if (BSTR_OK != bfindreplace (b, from, replace, 0)) {
> bdestroy (b);
> b = NULL;
> }
> /* If you have the memory b will contain the post modified string.
> */
>
> Life is