[C#] Vaag probleem met String.Indexof()

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Wilde
  • Registratie: December 2000
  • Niet online
Ik zit met een wazig probleempje in c# wat ongetwijfeld aan mij ligt, maar ik kom er niet uit..

Stel we hebben een string A:
code:
1
string a = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}}\r\n\\viewkind4\\uc1\\pard\\fs20 132{\\pict\\wmetafile8\\picw450\\pich450\\picwgoal255\\pichgoal255 \r\n0000000000000000000000000000000000000000"


In deze string wil ik zoeken naar de substring "pict". Als we met de hand kijken staat 't op plek 126 in de string.

code:
1
int index = a.IndexOf("pict")


index is nu niet 126 zoals je zou verwachten, maar 110 ! Het lijkt erop als elke dubbele backslash ervoor zorgt dat de te vinden positie 1 kleiner wordt. Oftewel de dubbele backslash wordt als 1 positie gerekend. Ik heb geprobeerd letterlijk te zoeken dmv @ voor de string(s), maar het lukt niet..

Iemand die dit eens wil verhelderen voor me ?

Specs: 9800X3D, RTX 5090, 64GB, VR: Pimax Crystal-Light


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Een backslash dient in c# gewoon ge-escaped te worden en omdat je hier dubbele backslashes hebt zou je die moeten vervangen door \\\\. Wat handiger is, is gewoon een apenstaart voor de string mikken (verbatim string).

C#:
1
2
3
4
5
string mystring = "dit\is\een\test";            // Fout
string mystring = "dit\\is\\een\\test";         // Geeft: Dit\is\een\test

string mystring = "dit\\\\is\\\\een\\\\test";   // Geeft: Dit\\is\\een\\test
string mystring = @"dit\is\een\test";           // Geeft: Dit\is\een\test

[ Voor 45% gewijzigd door RobIII op 06-11-2008 14:07 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Je kunt ook een apestaartje (@) voor je string zetten. De inhoud van de string is dan letterlijk.

C#:
1
string a = @"c:\windows\notepad.exe";


Heeft wel als nadeel dat de 'escape', de backslash, niet meer werkt waardoor \n dan geen regeleinde meer geeft.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • Wilde
  • Registratie: December 2000
  • Niet online
RobIII schreef op donderdag 06 november 2008 @ 14:03:
Een backslash dient in c# gewoon ge-escaped te worden en omdat je hier dubbele backslashes hebt zou je die moeten vervangen door \\\\. Wat handiger is, is gewoon een apenstaart voor de string mikken.

C#:
1
2
3
4
5
string mystring = "dit\is\een\test";            // Fout
string mystring = "dit\\is\\een\\test";         // Geeft: Dit\is\een\test

string mystring = "dit\\\\is\\\\een\\\\test";   // Geeft: Dit\\is\\een\\test
string mystring = @"dit\is\een\test";           // Geeft: Dit\is\een\test
Hier heb je natuurlijk gelijk in, maar hier zit de kern van mijn probleem volgens mij niet in. Het zal er overigens wel enigsins mee te maken hebben..

probleem is in mijn geval dat als je *iets* zoekt in een string met dubbele (en enkele) backslashes erin, de indexof functie een verkeerde index teruggeeft

Specs: 9800X3D, RTX 5090, 64GB, VR: Pimax Crystal-Light


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Wilde schreef op donderdag 06 november 2008 @ 14:07:
Hier heb je natuurlijk gelijk in, maar hier zit de kern van mijn probleem volgens mij niet in. Het zal er overigens wel enigsins mee te maken hebben..
Nee, het is wel de kern van je probleem. Zet een apenstaart voor je string en je bent er.
Wilde schreef op donderdag 06 november 2008 @ 14:07:
probleem is in mijn geval dat als je *iets* zoekt in een string met dubbele (en enkele) backslashes erin, de indexof functie een verkeerde index teruggeeft
IndexOf geeft wel degelijk de juiste index terug; maar jij escaped je strings niet goed ;)

Gooi de mystring's uit mijn voorbeeld maar eens in een messagebox ;)

C#:
1
2
3
4
MessageBox.Show("Eentje:  Test\\Test");
MessageBox.Show("Twee:    Test\\\\Test");
MessageBox.Show(@"Eentje: Test\Test");
MessageBox.Show(@"Twee:   Test\\Test");


Zie ook C# Language Specification 2.4.4.5 String literals en C# Language Reference Escape Sequences

[ Voor 24% gewijzigd door RobIII op 06-11-2008 14:17 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • .Gertjan.
  • Registratie: September 2006
  • Laatst online: 17-02 21:20

.Gertjan.

Owl!

Niemand_Anders schreef op donderdag 06 november 2008 @ 14:06:
Je kunt ook een apestaartje (@) voor je string zetten. De inhoud van de string is dan letterlijk.

C#:
1
string a = @"c:\windows\notepad.exe";


Heeft wel als nadeel dat de 'escape', de backslash, niet meer werkt waardoor \n dan geen regeleinde meer geeft.
Maar wanneer je een @ gebruikt kun je gewoon een enter tussen de "" gebruiken.

code:
1
2
 string x = @"dit is lijn 1
dit is lijn2";

The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.


Acties:
  • 0 Henk 'm!

  • Wilde
  • Registratie: December 2000
  • Niet online
RobIII schreef op donderdag 06 november 2008 @ 14:09:
[...]

Nee, het is wel de kern van je probleem. Zet een apenstaart voor je string en je bent er.


[...]

IndexOf geeft wel degelijk de juiste index terug; maar jij escaped je strings niet goed ;)

Gooi de mystring's uit mijn voorbeeld maar eens in een messagebox ;)

C#:
1
2
3
4
MessageBox.Show("Eentje:  Test\\Test");
MessageBox.Show("Twee:    Test\\\\Test");
MessageBox.Show(@"Eentje: Test\Test");
MessageBox.Show(@"Twee:   Test\\Test");
Klopt, je hebt alweer gelijk :) Dat gaat lekker zo, haha.. Als ik mijn code verander in:
code:
1
2
string a = @"{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}}\r\n\\viewkind4\\uc1\\pard\\fs20 132{\\pict\\wmetafile8\\picw450\\pich450\\picwgoal255\\pichgoal255 \r\n0000000000000000000000000000000000000000";
int index = a.IndexOf("pict");


Dan werkt het goed, de juiste positie wordt gevonden.. Het zit hem ook in de intepretatie van escape chars, dat weet ik..

Maar in mijn geval heb ik niet een string a, maar gebruik ik richttextbox.rtf:
code:
1
2
a = @rtb_input.Rtf;
int index = a.IndexOf("pict");


Waarbij rtb_input.rtf dezelfde inhoud heeft als de string a... Nu gaat het dus niet meer..

Specs: 9800X3D, RTX 5090, 64GB, VR: Pimax Crystal-Light


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Wilde schreef op donderdag 06 november 2008 @ 14:17:
Waarbij rtb_input.rtf dezelfde inhoud heeft als de string a... Nu gaat het dus niet meer..
Je kunt een @ sign (verbatim string) natuurlijk niet voor een non-literal plaatsen (en dat is dus alleen als je "blah" doet). In jouw geval lees je gewoon een property (.rtf) en zit de tekst dus écht wel goed al in je variabele en indexof geeft dan ook écht wel de juiste waarde terug.

Waar jij falikant de mist in gaat is het feit dat de dubbele backslashes die je ziet al escape sequences zijn. Als je dus \\rtf\\ansi\\ ziet, dan is dat 'in werkelijkheid' gewoon \rtf\ansi. Je wilt dus feitelijk geen dubbele backslashes maar enkele en dus was je initiele code correct maar de positie die jij verwacht (126) is in werkelijkheid gewoon 110 en dus heeft indexof het bij het rechte eind en is je verwachting gewoon fout.

Ik kom hier nu pas mee omdat ik even dacht dat rtf inderdaad dubbele backslashes bevatte, maar dat was mijn foute aanname; je probleem is dus nog steeds hetzelfde, maar nu gewoon andersom ;)

Resumerend: "{\\rtf1\\ansi\\ansicpg1252...." is de reeds escapete versie van de daadwerkelijke inhoud "{\rtf1\ansi\ansicpg1252....".

[ Voor 45% gewijzigd door RobIII op 06-11-2008 14:27 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Wilde
  • Registratie: December 2000
  • Niet online
RobIII schreef op donderdag 06 november 2008 @ 14:22:
[...]

Je kunt een @ sign (verbatim string) natuurlijk niet voor een non-literal plaatsen (en dat is dus alleen als je "blah" doet). In jouw geval lees je gewoon een property (.rtf) en zit de tekst dus écht wel goed al in je variabele en indexof geeft dan ook écht wel de juiste waarde terug.

Waar jij falikant de mist in gaat is het feit dat de dubbele backslashes die je ziet al escape sequences zijn. Als je dus \\rtf\\ansi\\ ziet, dan is dat 'in werkelijkheid' gewoon \rtf\ansi. Je wilt dus feitelijk geen dubbele backslashes maar enkele en dus was je initiele code correct maar de positie die jij verwacht (126) is in werkelijkheid gewoon 110 en dus heeft indexof het bij het rechte eind en is je verwachting gewoon fout.

Ik kom hier nu pas mee omdat ik even dacht dat rtf inderdaad dubbele backslashes bevatte, maar dat was mijn foute aanname; je probleem is dus nog steeds hetzelfde, maar nu gewoon andersom ;)

Resumerend: "{\\rtf1\\ansi\\ansicpg1252...." is de reeds escapete versie van de daadwerkelijke inhoud "{\rtf1\ansi\ansicpg1252....".
Ja ik zie het... Zit ik alsnog met een probleem maar daar zal ik jouw/jullie verder niet mee lastig vallen. Bedankt voor je uitleg :+

Specs: 9800X3D, RTX 5090, 64GB, VR: Pimax Crystal-Light

Pagina: 1