/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
CSV og ny CSV!
Fra : Preben


Dato : 14-06-04 12:24

Hej alle,

jeg har brug for at fremstille et program, der tager en komma-separeret
fil som argument og ændrer rækkefølgen af kolonner og indsætter nogle
"tomme"/default.

Jeg er jo ikke den store C-programmør, men jeg håber I kan hjælpe med et
lille eksempel, til hvordan jeg skal håndtere dette problem!


Mvh / Preben Holm

 
 
Jesper Louis Anderse~ (14-06-2004)
Kommentar
Fra : Jesper Louis Anderse~


Dato : 14-06-04 13:17

Preben <64bitNOnoNOSPAM@mailme.dk> wrote:

> jeg har brug for at fremstille et program, der tager en komma-separeret
> fil som argument og ?ndrer r?kkef?lgen af kolonner og inds?tter nogle
> "tomme"/default.
>
> Jeg er jo ikke den store C-programm?r, men jeg h?ber I kan hj?lpe med et
> lille eksempel, til hvordan jeg skal h?ndtere dette problem!

Overkill! UNIX og awk(1):

annah$ cat test
1, 2
3, 4
5, 6
annah$ awk 'BEGIN {FS=", "} {print $2 ",", $1}' <test
2, 1
4, 3
6, 5

Og mon ikke du kan finde noget source til en awk(1) klon at oversaette?

Hvis du _vil_ kode i C, saa er det nemmeste nok at arbejde
linieorienteret og lave noget grimt med fscanf()/fprintf(). Det er ikke
generelt, men mon ikke det loeser dit problem.

--
j.

Preben (14-06-2004)
Kommentar
Fra : Preben


Dato : 14-06-04 14:49

>>jeg har brug for at fremstille et program, der tager en komma-separeret
>>fil som argument og ?ndrer r?kkef?lgen af kolonner og inds?tter nogle
>>"tomme"/default.
>>
>>Jeg er jo ikke den store C-programm?r, men jeg h?ber I kan hj?lpe med et
>>lille eksempel, til hvordan jeg skal h?ndtere dette problem!
>
>
> Overkill! UNIX og awk(1):
>
> annah$ cat test
> 1, 2
> 3, 4
> 5, 6
> annah$ awk 'BEGIN {FS=", "} {print $2 ",", $1}' <test
> 2, 1
> 4, 3
> 6, 5
>
> Og mon ikke du kan finde noget source til en awk(1) klon at oversaette?
>
> Hvis du _vil_ kode i C, saa er det nemmeste nok at arbejde
> linieorienteret og lave noget grimt med fscanf()/fprintf(). Det er ikke
> generelt, men mon ikke det loeser dit problem.
>

Problemet er at det skal kunne køre på en Windows også! Derfor skal jeg
ikke bare have et smart perl-script eller noget andet, men faktisk noget
der virker "nemt" (nemmere i hvert fald) for brugeren!

Mvh / Preben

Bertel Brander (14-06-2004)
Kommentar
Fra : Bertel Brander


Dato : 14-06-04 19:09

Preben wrote:
> Hej alle,
>
> jeg har brug for at fremstille et program, der tager en komma-separeret
> fil som argument og ændrer rækkefølgen af kolonner og indsætter nogle
> "tomme"/default.
>
> Jeg er jo ikke den store C-programmør, men jeg håber I kan hjælpe med et
> lille eksempel, til hvordan jeg skal håndtere dette problem!
>
>

Man kunne starte med noget i stil med:

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

int main(int argc, char *argv[])
{
FILE *f;
char line[1024];

if(argc != 2)
{
fprintf(stderr, "Du skal angive et filnavn\n");
return EXIT_FAILURE;
}

if((f = fopen(argv[1], "rt")) == NULL)
{
fprintf(stderr, "Failed to open: %s\n", argv[1]);
return EXIT_FAILURE;
}
while(fgets(line, sizeof(line), f))
{
/* Read as first,middle,last, any could be missing */
char *p1 = line, *p2, *p3;
int i;

if((p2 = strrchr(line, '\n')) != NULL)
*p2 = 0;

p2 = strchr(line, ',');
p3 = strrchr(line, ',');
if(!p2 || !p3 || p2 == p3)
{
fprintf(stderr, "Input error!\n");
fclose(f);
return EXIT_FAILURE;
}
p2++;
p3++;
/* Write as first,last,middle, missing fields will be replaced by
FIRST/MIDDLE/LAST */
for(i = 0; *p1 != ','; i++, p1++)
putc(*p1, stdout);
if(!i)
fprintf(stdout, "FIRST");
putc(',', stdout);

for(i = 0; *p3 != ',' && *p3 != 0; i++, p3++)
putc(*p3, stdout);
if(!i)
fprintf(stdout, "MIDDLE");

putc(',', stdout);
for(i = 0; *p2 != ','; i++, p2++)
putc(*p2, stdout);

if(!i)
fprintf(stdout, "LAST");

putc('\n', stdout);
}

fclose(f);
return EXIT_SUCCESS;
}

Det får noget der ser sådan ud:
1,2,3
4,5,6
a,,c
,e,f
g,h,
,,lk

Til at se sådan ud:
1,3,2
4,6,5
a,c,LAST
FIRST,f,e
g,MIDDLE,h
FIRST,lk,LAST

/b

Preben (15-06-2004)
Kommentar
Fra : Preben


Dato : 15-06-04 15:14

Preben wrote:
> Hej alle,
>
> jeg har brug for at fremstille et program, der tager en komma-separeret
> fil som argument og ændrer rækkefølgen af kolonner og indsætter nogle
> "tomme"/default.
>
> Jeg er jo ikke den store C-programmør, men jeg håber I kan hjælpe med et
> lille eksempel, til hvordan jeg skal håndtere dette problem!
>
>
> Mvh / Preben Holm


Nogen der kan se fejlen heri:



while (fgets(string, LINE_LENGTH, f)) {
start = 0;
token = 0;
local = 0;
input = 1;

if (string[0] == '"')
input = 0;


for (i = 0; i < LINE_LENGTH && string[i] != 0; i++) {
if (i > 0 && string[i-1] == '"') {
   if (local == 1) {
    input = 0;
    local = 0;
   } else {
    input = 1;
    local = 1;
   }

   start = i;
}


if (input && string[i] != '"')
   input_str[i-start] = string[i];

if (i > 1 && string[i] == ',' && local != 1) {
   if (token == 0)
    strcpy(dato, input_str);
   else if (token == 1)
    strcpy(bilag, input_str);
   else if (token == 2)
    strcpy(type, input_str);
   else if (token == 3)
    strcpy(kontonr, input_str);
   else if (token == 4)
    strcpy(moms, input_str);
   else if (token == 5)
    strcpy(belob, input_str);
   else if (token == 6)
    strcpy(tekst, input_str);

   initString(input_str, FIELD_LENGTH);
   token++;
   input = 1;
}
}

strncpy(tekst, input_str, 25);

printf("\"%s\",\"%s\",\"%s\",\"%s\",\"0\",\"%s\",\"%s\",\"0\"\n",
dato, bilag, type, kontonr, tekst, belob);
initString(input_str, FIELD_LENGTH);
}


det er meningen at "-tegn skal fjernes fra output, men desværre er der
også felter hvor "-tegn ikke er tilstede.
Det var meningen at local skulle betegne når der var "-tegn og input når
der var input.

Jeg kan ikke se hvorfor at belob f.eks. ikke medtages når der ikke er
"-tegn udenomkring dette input.

her er et eksempelinput:


"30-01-2004","","D","11731","",4053,"En laaaaaaaaaaang tekst"
"30-01-2004","","D","11731","",-4133,"En endnu lææææææææængere tekst"



Håber nogen kan hjælpe og gennemskue hvad der skal laves anderledes


Mvh / Preben Holm

Preben (15-06-2004)
Kommentar
Fra : Preben


Dato : 15-06-04 16:27

Hej igen

et svar til mit eget spørgsmål

> while (fgets(string, LINE_LENGTH, f)) {
> start = 0;
> token = 0;
> local = 0;
> input = 1;
>
> if (string[0] == '"')
> input = 0;
>
>
> for (i = 0; i < LINE_LENGTH && string[i] != 0; i++) {
> if (i > 0 && string[i-1] == '"') {
> if (local == 1) {
> input = 0;
> local = 0;
> } else {
> input = 1;
> local = 1;
> }
>
> start = i;
> }
>
>
> if (input && string[i] != '"')
> input_str[i-start] = string[i];
>
> if (i > 1 && string[i] == ',' && local != 1) {
> if (token == 0)
> strcpy(dato, input_str);
> else if (token == 1)
> strcpy(bilag, input_str);
> else if (token == 2)
> strcpy(type, input_str);
> else if (token == 3)
> strcpy(kontonr, input_str);
> else if (token == 4)
> strcpy(moms, input_str);
> else if (token == 5)
> strcpy(belob, input_str);
> else if (token == 6)
> strcpy(tekst, input_str);
>
> initString(input_str, FIELD_LENGTH);
> token++;
> input = 1;

her skulle lige indsættes:
start = i+1;

(ellers startes med null-string)

> }
> }
>
> strncpy(tekst, input_str, 25);
>
> printf("\"%s\",\"%s\",\"%s\",\"%s\",\"0\",\"%s\",\"%s\",\"0\"\n",
> dato, bilag, type, kontonr, tekst, belob);
> initString(input_str, FIELD_LENGTH);
> }

Preben (15-06-2004)
Kommentar
Fra : Preben


Dato : 15-06-04 16:55

Opfølgning:


For lige at gøre en kort historie lang (eller omvendt) så har jeg nu
fremstillet et program som kan nuppe en komma-separeret fil og tygge den
ud i mindre dele (en del slamkode, men what ever - det skulle jo bare
virke).

Som sagen ligger er løsningen ikke perfekt, for nogle programmer vil jo
gerne have mulighed for at anvende "-tegn i strenge. Det løses
imidlertid ved at angive "" eller \".
Dette betyder, at hvis man vil have dette supporteret også, vil der
blive endnu flere if-sætninger hvilket også bliver for komplekst, da
strengen
..test","","test2","","test3"
jo sagtens vil kunne forekomme. dette giver jo ekstra tjek igen igen,
men hvad skal man gøre for at komme uden om det problem, hvis man gerne
vil lave en "pæn" løsning.

Bruger man regexp i C eller er det kun perl der kender sådan noget (ikke
fordi jeg fatter meget af dem, men de er rimelig nyttige)?


Mvh / Preben Holm

Bertel Lund Hansen (15-06-2004)
Kommentar
Fra : Bertel Lund Hansen


Dato : 15-06-04 18:12

Preben skrev:

>For lige at gøre en kort historie lang (eller omvendt) så har jeg nu
>fremstillet et program som kan nuppe en komma-separeret fil og tygge den
>ud i mindre dele (en del slamkode, men what ever - det skulle jo bare
>virke).

Gør dig selv den tjeneste at bruge en switch:

> if (i > 1 && string[i] == ',' && local != 1) {
>   if (token == 0)
>    strcpy(dato, input_str);
>   else if (token == 1)
>    strcpy(bilag, input_str);


if (i > 1 && string[i] == ',' && local != 1) {
   switch (token) {
    case 0: strcpy(dato, input_str); break;
    case 1: strcpy(bilag, input_str); break;
    osv.
}

Husk break;.

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

Bertel Brander (15-06-2004)
Kommentar
Fra : Bertel Brander


Dato : 15-06-04 18:52

Preben wrote:
> Opfølgning:
>
>
> For lige at gøre en kort historie lang (eller omvendt) så har jeg nu
> fremstillet et program som kan nuppe en komma-separeret fil og tygge den
> ud i mindre dele (en del slamkode, men what ever - det skulle jo bare
> virke).
>
> Som sagen ligger er løsningen ikke perfekt, for nogle programmer vil jo
> gerne have mulighed for at anvende "-tegn i strenge. Det løses
> imidlertid ved at angive "" eller \".
> Dette betyder, at hvis man vil have dette supporteret også, vil der
> blive endnu flere if-sætninger hvilket også bliver for komplekst, da
> strengen
> ..test","","test2","","test3"
> jo sagtens vil kunne forekomme. dette giver jo ekstra tjek igen igen,
> men hvad skal man gøre for at komme uden om det problem, hvis man gerne
> vil lave en "pæn" løsning.

Hvis der altid er text mellem , kan du med fordel bruge strtok:
http://www.rt.com/man/strtok.3.html

>
> Bruger man regexp i C eller er det kun perl der kender sådan noget (ikke
> fordi jeg fatter meget af dem, men de er rimelig nyttige)?
>

Man kan godt bruge regexp i C/C++, det er dog ikke en del af standarden,
så du skal ud finde en.
Jeg har modificeret en og pakket den ind i en C++ class:
http://home20.inet.tele.dk/midgaard/wgrep_2.zip

/b

Mogens Hansen (15-06-2004)
Kommentar
Fra : Mogens Hansen


Dato : 15-06-04 19:01


"Preben" <64bitNOnoNOSPAM@mailme.dk> wrote:

[8<8<8<]
> Bruger man regexp i C eller er det kun perl der kender sådan noget (ikke
> fordi jeg fatter meget af dem, men de er rimelig nyttige)?

Prøv at kigge på
Boost.Regex (http://www.boost.org/libs/regex/doc/index.html)
Boost.Tokenizer (http://www.boost.org/libs/tokenizer/index.html)
Boost.Spirit (http://www.boost.org/libs/spirit/index.html)

Venlig hilsen

Mogens Hansen



Igor V. Rafienko (15-06-2004)
Kommentar
Fra : Igor V. Rafienko


Dato : 15-06-04 19:20

[ 64bitNOnoNOSPAM@mailme.dk ]

[ ... ]

> men hvad skal man gøre for at komme uden om det problem, hvis man
> gerne vil lave en "pæn" løsning.


Først setter man seg ned og spesifiserer inputen fullt ut. Dvs. du
skriver ned (helst formelt) all den inputen som du ønsker skal være
gyldig.

Så tegner man et tilstandsdiagram som er i stand til å håndtere den
inputen eller tar i bruk lex (eller en passende variant av den).

I tilfellet man valgte å lage tilstandsdiagrammet og implementere alt
selv, gjenstår det bare å oversette diagrammet til C koden (det er
trivielt).

Dersom oppgaven din går imidlertid på noe annet enn en øvelse i
inputhåndtering, ville jeg foreslå å finne en parser som støtter den
csvdialekten du bruker.


> Bruger man regexp i C eller er det kun perl der kender sådan noget
> (ikke fordi jeg fatter meget af dem, men de er rimelig nyttige)?


Eh, nei, ikke i dette tilfellet. Regulære uttrykk (eller deres litt
mer kraftige brødre som PCRE) skaper ofte flere problemer enn de
løser. *Spesielt* i slike tilfeller er regulære uttrykk feil vei å gå,
da det er fryktelig vanskelig å bevise (selv relativt uformelt) at et
gitt regulært uttrykk vil kjenne igjen nettopp det språket man har
lyst det skal kjenne igjen: i slike situasjoner har "spesialtilfeller"
en lei tendens til å dukke opp, og for hver neste iterasjon blir
regexpen styggere og styggere.





ivr
--
<html><form><input type crash></form></html>

Søg
Reklame
Statistik
Spørgsmål : 177580
Tips : 31968
Nyheder : 719565
Indlæg : 6409076
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste