Avatar billede axcx Nybegynder
03. maj 2006 - 11:00 Der er 29 kommentarer og
1 løsning

Slet specifik linie i en txtfil

Hej Alle

Jeg har et lille problem jeg ikke kan finde ud af og håber da i kan hjælpe mig herinde.

Jeg har denne textfil www.jajo.midtfyn.net/AFLAES.txt som indholder en masse info jeg bruger. Mit problem er at jeg skal have mulighed for at regigere de sidste 2 tal i hver linie til noget nyt, eks. skal linie 3 regigeres fra 87 til 88.

Lige pt laver jeg bare en linie der ligner den man redigere i på en prik dog med nye tal til sidst. Ville så bagefter slette den gamle linie men det kan jeg ikke helt finde ud af, så ender op med 2 linier der næsten ligner hinanden.

Håber om en af jer kan hjælpe med det, eller om der er en helt anden smartere måde at regigere en linie på.

Hvis i har brug for mere info skriver i bare.
Programmerer til en PDA hvis det skulle have noget sige.
Avatar billede mikkel_sommer Nybegynder
03. maj 2006 - 11:15 #1
Kan du ikke indlæse filen ind i en string og så køre en replace på din string for derefter at skrive filen ud igen....
Avatar billede axcx Nybegynder
03. maj 2006 - 11:28 #2
Har tænkt på at gå ind og søge efter "87" og så replace det med eks. "88", men hvis der nu står "87" flere steder bliver det vel rettet alle stederne eller?

Men på den anden side burde det være muligt da de første tegn i hver linie er unik (er de dog ikke i filen der er linket til, da det er en test fil)
Hvordan ville man gøre det nemmest, altså søge efter det unikke i hver linie (de første tegn i starten) når dette er fundet replace det sidste tal med det nye skriv filen med ændringer og beholde alt det gamle?
Avatar billede mikkel_sommer Nybegynder
03. maj 2006 - 11:50 #3
tror jeg ville finde den linie hvor i der skal replaces og så lave en replace på hele linien
Avatar billede thesurfer Nybegynder
03. maj 2006 - 12:03 #4
1) Hvor anderledes er det at programmere til PDA, hvis man sammenligner det med en Windows applikation?

Du har disse data:

48260;10875714;01;01;01;2006-00-03 12:00;2006-27-03 10:27;89
LUKIA;BAJ11;01;01;01;2006-00-03 12:00;2006-43-03 10:43;90
48260;10875714;01;01;01;2006-00-03 12:00;2006-44-03 10:44;87
LUKIA;BAJ11;01;01;01;2006-00-03 12:00;2006-44-03 10:44;78
62069;10985043;01;01;01;2006-00-03 12:00;2006-44-03 10:44;90

2) Hvilke data kender du, når det er at du skal erstatte? Er det kun tallene "87", "88" osv?

/theSurfer
Avatar billede axcx Nybegynder
03. maj 2006 - 12:14 #5
theSurfer:

1. Det er ikke meget anderledes, det var bare lige for info'ens skyld.

2. Jeg kender alle data fra filen, men det er kun det i starten (48260, LUKIA osv) der må benyttes da der er unikt. Man vælger det unikke fra en comboBox som herefter lister alle data fra linien hvor den unikke værdi er. Man skal herefter indtaste en ny værdi som sal erstattes med den gamle, værdien er placeret som der sidste i filen.
http://www.jajo.midtfyn.net/pda.jpg billede fra programmet håber det giver lidt mere menning og håber jeg besvarede dit spørgesmål theSurfer eller må du bare råbe lidt af mig :P
Avatar billede thesurfer Nybegynder
03. maj 2006 - 12:33 #6
Billedet er en glimrende forklaring :-)

Her er et forslag:
- Læs hele filen ind i en variabel
- opret en string array ("string[]") og opdel indeholdet af variablen ved "\n" ("nylinie")
- loop fra 0 or til antallet af linier i string arrayen
-- hvis fra start af linien, og til ";", er lig det ønskede
--- erstat gammel værdi med ny værdi
-- slut hvis
-- hop ud af loop
- dan ny (almindelig) streng igen via en loop, og gem hele strengen

Det betyder at hele filens indhold, bliver erstattet af den nye indhold, med den rettede værdi.

/theSurfer
Avatar billede thesurfer Nybegynder
03. maj 2006 - 12:35 #7
Hvordan ser din kode ud, der læser og gemme filen?
Det kan være at jeg kan lave et eksempel til dig.

/theSurfer
Avatar billede thesurfer Nybegynder
03. maj 2006 - 12:36 #8
Der var nogle småfejl i 03/05-2006 12:33:49.. :-)
Men det kan nemt rettes..

/theSurfer
Avatar billede axcx Nybegynder
03. maj 2006 - 12:36 #9
Yes det lyder fornuftigt, prøver det lige af og vender tilbage :)
Jeg er ikke haj til det her endnu så der kan gå alt fra 30 min til 10 timer til jeg er færdig :P
Avatar billede thesurfer Nybegynder
03. maj 2006 - 12:42 #10
Helt iorden..

Du kan evt bruge noget i stil med denne kode, så skulle du gerne få fat på "48260, LUKIA, 48260, LUKIA, 62069" osv..

unik = strarr[i];
unik = unik.substring(0, unik.indexOf(";")); // indholder jo f.eks. "LUKIA"
if (unik == ønskedeværdi)
{
strarr[i] = strarr[i].Replace(gammelværdi, nyværdi)
break; // hop ud af loopen
}



/theSurfer
Avatar billede thesurfer Nybegynder
03. maj 2006 - 12:42 #11
"nu", og ikke "jo": indholder jo f.eks. "LUKIA"

:-)

/theSurfer
Avatar billede thesurfer Nybegynder
03. maj 2006 - 13:02 #12
Hvis "LUKIA" optræder flere steder i filen, men BAJ11 (eller flere værdier) er unikke, kan du splitte linie op ved ";":

string linie = "LUKIA;BAJ11;01;01;01;2006-00-03 12:00;2006-43-03 10:43;90";
string[] data  = linie.split(";".toCharArray());

Sådan er data-string-arrayen nu:
(formattet er: plads: værdi)
0: LUKIA
1: BAJ11
2: 01
3: 01

osv..

Så kan du spørge:
if (data[0] == "LUKIA" && data[1] == "BAJ11")
{
// noget her
}

Så kan du have flere betingelser..

/theSurfer
Avatar billede axcx Nybegynder
03. maj 2006 - 13:06 #13
Den her køre når formen loades, den finder de unikke værdier i hver linie og udksriver dem i en comboboks.

private void RetInfo_Load(object sender, System.EventArgs e)
{
  int i = 0;
  FileInfo t = new FileInfo("\\my documents\\Personal\\AFLAES.txt");
  if(t.Exists)
    {
    StreamReader readAll = new StreamReader("\\my documents\\Personal\\AFLAES.txt  ", System.Text.Encoding.Default);
           
    while ((linjerFraFil[i] = readAll.ReadLine()) != null)
        {
                  //comboBoxforbrugernr indholder det unikke.
            comboBoxforbrugernr.Items.Add(linjerFraFil[i].Split(splitter)[0]);
            i++;
        }
    readAll.Close();
    }
    else
    En messageboks med en fejl, da AFLAES.txt ikke findes.
-----------------------------------------------------------------------------------
Sådan her ser koden ud hvor jeg henter data og indsætter det i mine testbokse/labels udfra hvad der er valgt i comboboksen.

private void comboBoxforbrugernr_SelectedIndexChanged(object sender, System. EventArgs e)
{
StreamReader findPoster = new StreamReader("\\my documents\\Personal\\AFLAES.txt", System.Text.Encoding.Default);

label3.Text = "";
int i = 0;
string[] delt = new string[9];

while(!linjerFraFil[i].StartsWith(comboBoxforbrugernr.Text.ToString()))
    {
    i++;
    }

delt = linjerFraFil[i].Split(splitter); //splitter er ';"
labelMaalernr.Text = delt[1];
labelForbrugtype.Text = delt[2];
labelRegisternr.Text = delt[3];
labelRegistertype.Text = delt[4];
NyValue.Text = delt[7]; // den textbox hvor den nye værdi skal indtastes.
findPoster.Close();
}

sorry, det ser nok total åndsvagt og er slam kode men det virker :P

theSurfer: Da det kun er en testfil der er linket til står der LUKIA flere steder med vilje, i den rigtige vil LUKIA kun stå 1 gang og alt vil være unikt i starten.
Avatar billede thesurfer Nybegynder
03. maj 2006 - 13:08 #14
Jeg er blevet ringet op af arbejdet, og skal på arbejde kl 15-23..
Hvis der ikke er løst inden da, laver jeg noget kode til dig.

/theSurfer
Avatar billede thesurfer Nybegynder
03. maj 2006 - 13:15 #15
Hvis det kun står 1 gang, kan du bruge noget i stil med:

string linie = "LUKIA;BAJ11;01;01;01;2006-00-03 12:00;2006-43-03 10:43;90";
string[] data  = linie.split(";".toCharArray());
string tmp = "";
bool fundet = false;

if (data[0] == "LUKIA")
{
  tmp = data[data.length]; // indeholder nu "90"
  tmp = tmp.replace(gammel_værdi, ny_værdi);
  data[data.length] = tmp;
  fundet = true;
}

if (fundet == true)
{
  tmp = "";
  for (i = 0; i < data.length; i++)
  {
    tmp += data[i] + ";"
  }
  tmp = tmp.substring(0, tmp.length - 1) // fjerner det sidste ";"
}

"tmp" indeholder nu hele linien med den rettede værdi.

/theSurfer
Avatar billede thesurfer Nybegynder
03. maj 2006 - 13:15 #16
Det skal lige sige, at koden er skrevet direkte her på Eksperten, og er derfor ikke test.. :-)
Der kan være fejl..

/theSurfer
Avatar billede thesurfer Nybegynder
03. maj 2006 - 13:34 #17
Jeg har fået lavet følgende eksempel (jeg har bare brugt faste værdier):

            int i = 0;
            string linie = "LUKIA;BAJ11;01;01;01;2006-00-03 12:00;2006-43-03 10:43;90";
            MessageBox.Show("linie: " + linie);
            string[] data = linie.Split(";".ToCharArray());
            string tmp = "";
            bool fundet = false;
            string gammel_vaerdi = "90";
            string ny_vaerdi = "10";

            if (data[0] == "LUKIA")
            {
                tmp = data[data.Length - 1]; // indeholder nu "90"
                tmp = tmp.Replace(gammel_vaerdi, ny_vaerdi);
                data[data.Length - 1] = tmp;
                fundet = true;
            }

            if (fundet == true)
            {
                tmp = "";
                for (i = 0; i < data.Length; i++)
                {
                    tmp += data[i] + ";";
                }
                tmp = tmp.Substring(0, tmp.Length - 1); // fjerner det sidste ";"
                linie = tmp;
            }
            MessageBox.Show("linie: " + linie);


Jeg smutter på arbejde nu, og er først tilbage omkring 23.. eller midnat..

/theSurfer
Avatar billede axcx Nybegynder
03. maj 2006 - 18:05 #18
Hej theSurfer og jer andre der kigger med.

Din kode virker fint, jeg får byttet værdien ud med den nye værdi og den ligger så i "linie". Problemet er dog ikke helst løst endnu.
Jeg har modificeret din kode lidt så den tager og ændre ud fra hvilken linie der er valgt i comboboksen (se billedet). Det virker fint.

Problemet er nu at få skrevet den nye linie ind i tekstfilen istedet for den gamle der er ændret i.

Så hvis filen ser sådan herud:

00004;10875714;01;01;01;2006-00-03 12:00;2006-27-03 10:27;89
00003;BAJ11;01;01;01;2006-00-03 12:00;2006-43-03 10:43;90
00001;10875714;01;01;01;2006-00-03 12:00;2006-44-03 10:44;87 //gamle værdi
00002;BAJ11;01;01;01;2006-00-03 12:00;2006-44-03 10:44;78

og jeg ændre linie 3 med en ny værdi, her bruger jeg din kode, nu ligger strengen som skal skrives til filen nu i "linie" og ser sådan her ud:

00001;10875714;01;01;01;2006-00-03 12:00;2006-44-03 10:44;100 //ny værdi her

skal filen opdateres til:

00004;10875714;01;01;01;2006-00-03 12:00;2006-27-03 10:27;89
00003;BAJ11;01;01;01;2006-00-03 12:00;2006-43-03 10:43;90
00001;10875714;01;01;01;2006-00-03 12:00;2006-44-03 10:44;100 //ny værdi her
00002;BAJ11;01;01;01;2006-00-03 12:00;2006-44-03 10:44;78

Jeg har leget lidt med StreamWriter men den ender altid med at der bare bliver add'et en ny linie og den gamle forbliver i filen.
Jeg håber du eller andre lige kan regne den ud :)
Avatar billede arne_v Ekspert
04. maj 2006 - 02:43 #19
hvis den nye linie har samme længde som den gamle linie, så kan man fuske
det med noget direct access (Seek & Write)

hvis den nye linie har en anden længde en den gamle længde så skal du formentlig
genskrive hele filen (du kan også nøjes med at genskrive fra der hvor ændringen sker -
igen med lidt fusk)
Avatar billede thesurfer Nybegynder
04. maj 2006 - 03:11 #20
Det blev lidt sent.. :-)

jeg har lavet noget kode, som jeg har testet.. og det virker.. :-)

Controls:
Combobox, navn: cbxId
Textbox, navn: tbxVaerdi
Button, navn: btnOpdaterData

Hele koden (fra "Form1.cs") med kommentar:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace q706949
{
    public partial class RetInfo : Form
    {
        // hvis du bruger "@", behøver du ikke at escape backslash (dvs, dobbelt backslash)
        string fil = Application.StartupPath + @"\AFLAES.txt"; // filen "AFLAES.txt" ligger sammen med EXE-filen
        string indhold = ""; // kommer til at indeholde indholdet af filen
        int i, j = 0; // interatorer
        string unikid = ""; // kommer til at indeholde det unikke id
        string[] data = null; // kommer til at indeholde dataene fra linier fra filen
        bool fundet = false; // checkpoint så man kan se, om det unikke id blev fundet

        public RetInfo()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                fundet = false; // nulstil checkpoint
                indhold = LaesFilenOgReturnerIndholdet(); // indlæs fil.. e metoden "LaesFilenOgReturnerIndholdet()"

                string[] linier = indhold.Split("\n".ToCharArray()); // split indholdet op i linier
                for (i = 0; i < linier.Length; i++) // løb alle linierne igennem
                {
                    data = linier[i].Split(";".ToCharArray()); // split den nuværende linie
                    unikid = data[0]; // dette unikke id er på plads 0 (første) på linien
                    if (unikid == cbxId.Text) // sammen lign det unikke id med det valgte (combobox)
                    {
                        data[data.Length - 1] = tbxVaerdi.Text; // sætte sidste plads i data-array til text-værdien
                        linier[i] = ""; // nulsil linien, så vi kan samle den igen, med den nye værdi
                        for (j = 0; j < data.Length; j++) // løb igennem alle data-værdierne
                        {
                            linier[i] += data[j] + ";"; // tilføj den nuværende værdi til den nuværende linie
                        }
                        linier[i] = linier[i].Substring(0, linier[i].Length - 1); // fjerne det sidste ";"
                        fundet = true; // sæt checkpoint, så man kan se, at der er set en rettelse = save file
                        break; // hop ud af loopen
                    }
                }

                if (fundet == true) // check om der er blevet fundet/rettet noget
                {
                    indhold = ""; // nulstil indholdet
                    for (i = 0; i < linier.Length; i++) // løb igennem alle linierne
                    {
                        indhold += linier[i] + "\r\n"; // tilføj linien til indholdet og lav linieskift
                    }
                    indhold = indhold.Substring(0, indhold.Length - 2); // fjern det sidste linieskift

                    try
                    {
                        StreamWriter SW; // opret instans af StreamWrite så vi kan skrive til filen
                        SW = File.CreateText(fil); // opret forbindelse til filen
                        SW.Write(indhold); // skriv indholdet (alle linier + den nye værdi)
                        SW.Close(); // afslut instansen
                        OpdaterCombobox(); // opdater combobox'en, så man kan se at der er "sket" noget
                    }
                    catch (Exception ex)
                    {
                        // hvis der opstår fejl (f.eks. ved skrivning), fanges den her:
                        if (ex.Message != "") MessageBox.Show("FEJL!\n" + ex.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                // hvis der opstår general fejl, fanges den her:
                if (ex.Message != "") MessageBox.Show("Error: " + ex.Message);
            }
        }

        private void OpdaterCombobox()
        {
            try
            {
                indhold = LaesFilenOgReturnerIndholdet(); // indlæs fil.. e metoden "LaesFilenOgReturnerIndholdet()"

                string[] linier = indhold.Split("\n".ToCharArray()); // ***
                cbxId.Items.Clear(); // tøm/nulstil combobox'en
                for (i = 0; i < linier.Length; i++) // løb igennem alle linierne
                {
                    // filføj den unikke id til combobox'en:
                    cbxId.Items.Add(linier[i].Split(";".ToCharArray())[0]);
                }
                cbxId.Focus(); // set fokus på combobox'en
            }
            catch (Exception ex)
            {
                // hvis der opstår general fejl, fanges den her:
                if (ex.Message != "") MessageBox.Show("Error: " + ex.Message);
            }


        }

        private string LaesFilenOgReturnerIndholdet()
        {
            string filens_indhold = ""; // nulstil variablen der kommer til at indeholde indholdet
            try
            {
                StreamReader SR; // opret instans af StreamWrite så vi kan skrive til filen
                SR = File.OpenText(fil); // opret forbindelse til filen
                filens_indhold = SR.ReadToEnd(); // put indholdet af filen i variablen "filens_indhold"
                SR.Close(); // afslut instansen
            }
            catch (Exception ex)
            {
                // hvis der opstår fejl (f.eks ved åben/læs fil), fanges den her:
                if (ex.Message != "") filens_indhold = "FEJL!\n\n" + ex.Message;
            }
            return filens_indhold.Replace("\r\n", "\n"); // erstat carrige return (?) og send indholdet retur
        }

        private void RetInfo_Load(object sender, EventArgs e)
        {
            OpdaterCombobox(); // opdater/popuplate combobox'en
        }

        private string HentDenSpecifikkeLinieMedDenMedsendteUnikkeId(string unikid)
        {
            string[] linier = indhold.Split("\n".ToCharArray()); // split
            string linie = ""; // nulstil variablen linie
            for (i = 0; i < linier.Length; i++) // løb alle linierne igennem
            {
                data = linier[i].Split(";".ToCharArray()); // opdel linien og put dataene i string-arrayen data
                string tmpid = data[0]; // den unikke id smides over i variablen "tmpid"
                if (tmpid == unikid) // sammenlign "tmpid" med den medsendte unikke id
                {
                    // de er ens
                    linie = linier[i]; // læg den nuværende linie over i variablen "linie"
                    fundet = true; // sæt checkpoint, så man kan se, at linien blev fundet
                    break; // hop ud af loopen
                }
            }
            if (fundet == true) // check om linien blev fundet
            {
                return linie; // linien blev fundet.. returner den
            } else {
                // linien blev IKKE fundet.. return en fejlmeddelelse:
                return "FEJL!\nDet unikke ID blev ikke fundet!";
            }
        }

        private void cbxId_SelectedIndexChanged(object sender, EventArgs e)
        {
            indhold = LaesFilenOgReturnerIndholdet(); // indlæs indholdet af filen
            string tmp = HentDenSpecifikkeLinieMedDenMedsendteUnikkeId(cbxId.Text); // hent linien
            if (tmp.Substring(0, 4) == "FEJL") // check for fejl = linien blev ikke fundet
            {
                MessageBox.Show(tmp); // linien blev ikke fundet.. vis en fejlmeddelelse
            }
            else
            {
                // linien blev fundet.. forsæt med at arbejde med den:
                data = tmp.Split(";".ToCharArray()); // opdel linien så vi kan få fat på dataene
                tmp = data[data.Length - 1]; // smid den sidste plads fra "data" over i "tmp"
                tbxVaerdi.Text = tmp; // vis værdien, så man kan se/redigere den
            }
        }
    }
}

/theSurfer
Avatar billede thesurfer Nybegynder
04. maj 2006 - 03:19 #21
- Fordelen ved at læse fra filen, hver gang et unikt id vælges, er at man altid har de nyeste data.

- Ulempen er at man bruger ressourcer hver gang. Man kunne have indlæst alle data i variabler (eller objekter), når programmet starter op, og så ikke igen..

/theSurfer
Avatar billede axcx Nybegynder
04. maj 2006 - 08:47 #22
Wow!

Kigger på det ASAP, skal lige være færdig i skolen.
Avatar billede axcx Nybegynder
04. maj 2006 - 10:33 #23
theSurfer du er gud!! :)

Smid et svar, det virker for fedt!
Avatar billede thesurfer Nybegynder
04. maj 2006 - 10:40 #24
Tror nu ikke lige at jeg er en gud.. :-)
Alt (eller næsten alt) kan laves.. :-)
- Svar

/theSurfer
Avatar billede thesurfer Nybegynder
04. maj 2006 - 10:41 #25
Doh! :-)

/theSurfer
Avatar billede thesurfer Nybegynder
04. maj 2006 - 20:11 #26
Hmm.. hvor meget/lidt forskel er der på C# i Windows applikationer og PDA?

Jeg er igang med et projekt, og skal muligvis programmere en lille klient-ting, til en PDA..

Projektet er "top secret", så jeg kan ikke komme med detaljer.. :-)

/theSurfer
Avatar billede axcx Nybegynder
04. maj 2006 - 20:48 #27
Ikke det store faktisk TROR jeg :) Er dog selv nybegynder men har da fundet ud at eks. cryptography kan ikke bruges på PDA'er.
Desuden havde jeg problemer med Application.StartupPath fra din kode, det kunne den ikke finde ud af :S Ved ikke om det bare er mig der gør et eller andet galt :P
Ændrede det dog bare til  string fil = "<sti>"; det virkede også kanon :)
Avatar billede arne_v Ekspert
04. maj 2006 - 20:51 #28
man kan laese i docs om en klasse er supporteret i CF
Avatar billede thesurfer Nybegynder
04. maj 2006 - 21:25 #29
axcx> Jeg ved at "Application.StartupPath" ikke virker fra klasser, da det skal bruges fra "Application"/formen..
Ellers skal man tilføje "using System.Window.Forms" (eller noget i den stil) i toppen..

Men du kører koden fra formen (RetInfo_Load).. ik?


arne_v> Hvad mener du med "CF"?

/theSurfer
Avatar billede arne_v Ekspert
04. maj 2006 - 21:35 #30
CF = Compact Framework
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
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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