Avatar billede coltau Juniormester
21. november 2008 - 18:11 Der er 19 kommentarer og
1 løsning

Arbejde med string og string[]

Jeg er lige startet med C# og har problemer med syntaxen i nedenstående kode.

Koden skal være en funktion der modtager 2 parametre.
En string med (resten) af en linie fra en kommasep. fil og selve seperatoren.

Funktionen skal fjerne og returnere næste felt i linien.

Koden er spækket med syntax fejl men det jeg i første omgang ønsker svar på er problemer omkring (S[P] == chr(34)) og en forklaring på hvordan selve funktionen skal se ud for at returnere en string.


public static string EatNextField(string S, char Sep);
{
    bool QFlag;
    int P;
    bool EOField;
    bool Result;

  Result = "";
  P = 0;
  if (S.Length > 0) {
    QFlag = (S[P] == chr(34));
    if QFlag = true {
      P++;
    } 
    EOField = false;
    while !EOField do {
      if not QFlag {
        EOField = (S[P] == Sep);
        if not EOField then
          Result = Result + S[P];
      } else {
        if (S[P] == chr(34)) {
          if (P < Length(S)) and (S[P + 1] = chr(34)) {
            Result = Result + S[P];
            P++;
          } else {
            if (P >= Length(S)) or (S[P + 1] == Sep) {
              EOField = true;
              P++;
            } else
              Result = Result + S[P];
        } else {
          Result = Result + S[P];
          }
      } // end else   
      P++;
      if !EOField {
        if !QFlag {
          EOField = (P > S.Length) // ?
        } else {
          EOField = (P >= S.Length);
        } 
        if EOField {
          P++;
        } 
      }
    } // while
    S.Delete(1, P - 1);
  }
return Result;   
}
Avatar billede arne_v Ekspert
21. november 2008 - 18:17 #1
Er den kode oversat fra C/C++ ?

:-)
Avatar billede arne_v Ekspert
21. november 2008 - 18:18 #2
chr(34) kan laves som '"'

string er immutable og default i C# er pass by value saa S.Delete(1, P - 1) goer ikke hvad du tror
Avatar billede arne_v Ekspert
21. november 2008 - 18:19 #3
En funktion kan returnere en string ligesom alt muligt andet. Hvis du vil have en
bool returvaerdi kan du lave det som en out parameter.
Avatar billede arne_v Ekspert
21. november 2008 - 18:22 #4
Nej - ved naemere eftertanke ligner det mere Pascal.

:-)
Avatar billede arne_v Ekspert
21. november 2008 - 18:23 #5
Jeg ville droppe hele ideen med at laese et felt og slette det.

Det maa vaere meget nemmer at lave en metode som returnerer et string[] eller List<string>, saa skal du kun parse en gang.
Avatar billede coltau Juniormester
21. november 2008 - 18:25 #6
Jeg har arbejdet med Delphi i 10 år - så det er tidligere Delphikode.

Ok - jeg får fejl på denne.

    QFlag = (S[P] == chr(34));

Expected class, delegate, enum ...

Umiddelbart synes jeg linien ser korrekt ud.

Selvfølgelig skal jeg bruge "out" i stedet for "ref".
Avatar billede arne_v Ekspert
21. november 2008 - 18:32 #7
hvad med:

QFlag = (S[P] == '"');

?
Avatar billede coltau Juniormester
21. november 2008 - 18:39 #8
Kompileren kommer med samme fejl på denne

    QFlag = (S[P] == '"');

og sætter en rød (stavefejls) streg under ==

funktionen er del af en kode der anvendes til at indlæses en linie fra en kommasep. fil og overføre den til en Collection, som gør det nemmere at arbejde med de enkelte felter i linien. Funktionen anvendes til at "æde" et felt af gangen fra den læste linie.

Der findes sikkert nemmere metoder i C# men i første omgang er det blot for at få en forståelse af syntaxen.
Avatar billede arne_v Ekspert
21. november 2008 - 18:49 #9
Det boer compile fint hvis S er string, P er int og QFlag er bool.

Der er ikke fejl laengere oppe som har faaet compileren "af sporet" ?
Avatar billede coltau Juniormester
21. november 2008 - 19:15 #10
Du har sikkert ret i at det stammer fra et eller andet længere oppe i koden.

Starten ser ud som nedenstående. (Jeg anvender C# 2008 Express)
Til venstre for koden kan jeg se nogle lodrette streger.
Stregerne der starter ved namespace stopper lidt for tidligt i koden. Jeg har noteret det i koden.
Som om namespace ikke dækker mere.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication1
{
namespace myfilesio
{

public static string EatNextField(ref string S, char Sep);
{
    bool QFlag;
    int P;
    bool EOField;
    bool Result;

  Result = "";
  P = 0;
  if (S.Length > 0) {
    QFlag = (S[P] == '"');
    if QFlag = true {
      P++;
    } 
    EOField = false;
    while !EOField do {
      if not QFlag {
        EOField = (S[P] == Sep);
        if not EOField then
          Result = Result + S[P];
      } else { // Her går namespace myfilesio til
        if (S[P] == chr(34)) {
          if (P < Length(S)) and (S[P + 1] = chr(34)) {
            Result = Result + S[P];
            P++;
          } else { // Her går namespace WindowsFormsApplication1 til
Avatar billede arne_v Ekspert
22. november 2008 - 01:20 #11
public static string EatNextField(ref string S, char Sep); <---- start med at slette dette semikolon
Avatar billede arne_v Ekspert
22. november 2008 - 01:20 #12
og

namespace myfilesio

skal nok være

class myfilesio
Avatar billede arne_v Ekspert
22. november 2008 - 01:27 #13
Og ellers hjllper det gevaldigt på overblokket med korrekt indrykning.

Jeg satte lidt parenteser, ændrede and og or til && og || og nåede så til:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication1
{
    public class myfilesio
    {
        public static string EatNextField(ref string S, char Sep)
        {
            bool QFlag;
            int P;
            bool EOField;
            bool Result;
            Result = "";
            P = 0;
            if (S.Length > 0)
            {
                QFlag = (S[P] == '"');
                if (QFlag)
                {
                    P++;
                }
                EOField = false;
                while (!EOField) do
                {
                    if (!QFlag)
                    {
                        EOField = (S[P] == Sep);
                        if (!EOField)
                            Result = Result + S[P];
                    }
                    else
                    {
                        if (S[P] == '"')
                        {
                            if ((P < Length(S)) && (S[P + 1] = '"'))
                            {
                                Result = Result + S[P];
                                P++;
                            }
                            else
                            {
                                if ((P >= Length(S)) || (S[P + 1] == Sep)) {
                                    EOField = true;
                                    P++;
                                }
                                else
                                    Result = Result + S[P];
                            } else { <----- problem
Avatar billede d0t Nybegynder
24. november 2008 - 11:46 #14
En mere korrekt sammenligning af chars, ville være at bruge equals funktionen..

QFlag = (S[P] == '"');

Bliver til:

QFlag = S[P].Equals("");


Du spørger hvordan funktionen skal se ud, hvis den skal returnere en streng:

Du angiver selv i "oprettelsen" af funktionen, at den skal returnere en string.
I slutning (eller hvor du nu end vil have retuneringen, skriver du blot return Result, antaget at Result er hvad du vil returnere!
Avatar billede coltau Juniormester
24. november 2008 - 13:15 #15
Takker for svarene - kom selv videre da jeg fandt ud af at et namespace skal indledes med en "class ???" uden public/static foran. Som du skrev arne - > Måske er fejlen længere oppe i koden end hvor man tror. (Smid et svar)
Her efter kunne jeg følge kompilerens fejlmeddelelser og komme videre.

Som sagt er det første gang jeg har siddet med C# kode - men det lykkes mig da at lave et par (string)funktioner, oprette dynamiske komponenter og hente data fra en mySQL database via nettet.
Avatar billede arne_v Ekspert
24. november 2008 - 15:07 #16
d0t>

Der er ikke noget galt med at bruge ==.

Result er endnu en Delphisme.
Avatar billede arne_v Ekspert
24. november 2008 - 15:07 #17
svar
Avatar billede arne_v Ekspert
24. november 2008 - 15:11 #18
Som jeg ville lave det i C#:

using System;
using System.Collections.Generic;
using System.Text;

namespace E
{
    public class Program
    {
        public static List<string> Parse(String s, char delim, char quote)
        {
            List<string> res = new List<string>();
            StringBuilder sb = new StringBuilder();
            bool inquote = false;
            int ix = 0;
            while(ix < s.Length)
            {
                if(s[ix] == delim)
                {
                    if(inquote)
                    {
                        sb.Append(s[ix]);
                    }
                    else
                    {
                        res.Add(sb.ToString());
                        sb = new StringBuilder();
                    }
                }
                else if(s[ix] == quote)
                {
                    if(ix + 1 < s.Length && s[ix+1] == quote)
                    {
                        sb.Append(s[ix]);
                        ix++;
                    }
                    else
                    {
                        inquote = !inquote;
                    }
                }
                else
                {
                    sb.Append(s[ix]);
                }
                ix++;
            }
            res.Add(sb.ToString());
            return res;
        }
        public static void Main(string[] args)
        {
            List<string> lst = Parse("123,#ABC#,#DE,FG#,#HI##JK#", ',', '#');
            foreach(string s in lst)
            {
                Console.WriteLine(s);
            }
            Console.ReadKey();
        }
    }
}
Avatar billede d0t Nybegynder
24. november 2008 - 22:25 #19
Må være et lævn fra mine java dage, hvor man ikke måtte bruge == til sammenligning af strings eller chars..

Vidste ikke at C# har fixet dette :)
Avatar billede arne_v Ekspert
25. november 2008 - 04:31 #20
I Java skal man bruge .equals for String, men == virker fint for char.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester