Sziasztok!
Van egy perl scriptem:
#!/usr/bin/perl -w
use strict;
use Getopt::Std;
our $opt_i='';
my @infiles;
getopts('i:');
if ($opt_i){
@infiles=split(/,/,$opt_i)
}
my $i=0;
for(my $i=0;$i < scalar @infiles;$i++){
print "$i. file: $infiles[$i]\n";
}
exit;
Kérlek, segítsetek átírni C-be. Alapvetően a split-es részt és a filenevek arrayben tárolását nem tudom, hogy kell megoldanom C-ben.
Köszönök minden tanácsot előre is.
Csaba
- 1771 megtekintés
Hozzászólások
Üdv az éjszakában! Csab írta még tavaly. Ebből a split részét ki is hámozhatod. Értelemszerűen a ';' helyett neked ',' kell.
- A hozzászóláshoz be kell jelentkezni
Köszi, megpróbálom kihámozni.
Csaba
- A hozzászóláshoz be kell jelentkezni
Nos, jelenlg itt tartok:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* megszámlálja a ',' elemeket */
int get_size( char * buffer ){
int c = 0, i = 0;
if( buffer[ 0 ] == 0 )
return 0;
while( buffer[ i ] != 0 )
{
if( buffer[ i ] == ',' )
c++;
i++;
}
/* egyet hozzáadok, mert a "hello" is értéknek számít, hiába nincs benne ',' */
return c + 1;
}
/* visszatér egy pointer tömbbel, ami az elemekre mutat, a tömböt 0 pointerrel zárja */
char ** get_pointers( char * buffer )
{
int size = get_size( buffer );
/* helyfoglalás a pointer tömbnek */
char ** res = (char **)malloc( sizeof( char * ) * ( size + 1 ) );
int i=0;
int p=0;
while( buffer [ i ] != 0 ) {
/* a sor elejét eltárolom */
res[ p++ ] = buffer + i;
/* a sor végét megkeresem */
do {
i++;
} while( buffer[ i ] != 0 && buffer[ i ] != ',' );
/* felülírjuk a ','-t 0-val */
if( buffer[ i ] != 0 ) {
buffer[ i ] = 0;
i++;
}
}
/* null pointerrel zárjuk */
res[ p ] = 0;
return res;
}
int main(int argc, char *argv[ ]) {
int c;
char delims[] = ",";
char *infiles;
char ** infile_array=get_pointers(infiles);
char *outfiles;
while ((c = getopt(argc, argv, ":i:o:h")) != -1) {
switch(c){
case 'h':
printf ("Usage: ....\n");
break;
case 'i':
infiles=optarg;
printf("infiles %s\n", infiles);
int p = 0;
while( infile_array[ p ] != 0 )
{
printf( "%i. file:%s\n", p,infile_array[ p ] );
p++;
}
break;
case 'o':
break;
}
}
}
Ez legalább lefordul, de nem igazán azt csinálja, amit szeretnék. Szerintem valahogy a pointerek körül kavarok el valamit. Help! Köszi....
- A hozzászóláshoz be kell jelentkezni
Ebben ke't elvi hiba van, igy elsore:
- a get_pointers() fv-t akkor hivod meg, amikor az argumentuma me'g nem inicializa'lt: ezt at ko"ll tenned az optarg-feldolgozo switch{}-be, es nem rogton a main() 3. sora'ban.
- a get_pointers() fv modositja az argumentumaban megadott sztringet (lasd sajat kommented: ./* felülírjuk a ','-t 0-val */). ezert az infiles/optarg mint olyan modositva lesz. ez viszont egy readonly pointer (pontosabban: a pointer egy readonly teruletre mutat; lasd argv[] tomb valahanyadik eleme), igy ez segfault-hoz fog vezetni. tehat:
infiles=strdup(optarg)
, majd ha _sem_ az infile_array[]-ra, _sem_ az infiles sztringre nem lesz szukseged, akkor free()-vel mindkettot fel lehet szepen szabaditani.
- A hozzászóláshoz be kell jelentkezni
c++ nem jó?
- A hozzászóláshoz be kell jelentkezni
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **tokenize_char_dyn(char *buff,int tchar)
{
int n;
char **tokens;
if ( buff==NULL )
return(NULL);
else if ( (tokens=(char **)malloc(sizeof(char *)))==NULL )
return(NULL);
else if ( *buff==0 )
{ *tokens=NULL;
return(tokens);
}
n=0;tokens[n]=buff,n++;
while ( *buff )
{ if ( *buff != tchar ) buff++;
else
{ *buff=0,buff++;
tokens=(char **)realloc(tokens,sizeof(char *)*(n+2));
tokens[n]=buff,n++;
}
};
tokens[n]=NULL;
return(tokens);
}
int main(int argc,char *argv[])
{
int i;
char *inlist,**inarr;
inlist=NULL;
for ( i=1 ; i<argc ; i++ )
{ if ( strcmp(argv[i],"-i")==0 && i<argc-1 )
{ i++;inlist=strdup(argv[i]); }
else
{ fprintf(stderr,"unknown option: %s\n",argv[i]); }
}
inarr=tokenize_char_dyn(inlist,',');
for ( i=0 ; inarr != NULL && inarr[i] != NULL ; i++ )
{ fprintf(stdout,"%d. file: %s\n",i,inarr[i]); }
if ( inarr != NULL ) free(inarr);
if ( inlist != NULL ) free(inlist);
return(0);
}
- A hozzászóláshoz be kell jelentkezni
Nagyon szépen köszönöm.
Csaba
- A hozzászóláshoz be kell jelentkezni
A tokenizalashoz az strtok miert nem jo, mint konyvtari fgv?
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Csak az strtok() kicsit keves ehhez: itt dinamikus tombot kell eloallitani, hogy utana egyszeruen lehessen hasznlalni. Amihez vagy tenzort allokalsz (de az relative bonyolult, meg felszabaditani se lehet free()-vel olyan egyszeruen), vagy mint ahogy itt is, ugy hogy modositod az eredeti sztringet. Egyebkent persze, lehet keverni az implementaciokat, hogy a dinamikus tomb kezelesnel nem kezzel keresed a hatarolokaraktereket, hanem strtok()-kal, de nem ez a szuk keresztmetszet (sem cpu-idoben, sem a skalazas miatt, sem technikailag). A fenti fv meg jo alapja annak, hogy egy fokkal intelligensebb tokenizalast csinalj mas esetekben (pl. whitespace-alapokon, kiegeszitve pl eszkepelessel vagy shell-szeru featurakkal, mint pl az "..."-ben levo szoveg az egy token, stbstb), legalabbis en igy csinaltam anno.
- A hozzászóláshoz be kell jelentkezni
Jelen feladathoz tökéletesen elegendő az strtok.
Értem én, hogy dinamikus lista, de pl ettől a ciklusban hívott realloc-tól engem kiráz a hideg...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Értem én, hogy dinamikus lista, de pl ettől a ciklusban hívott realloc-tól engem kiráz a hideg...
persze, lehet intelligensebben/szebben is csinalni. a celnak (altalanos szovegfileok parzolasa) ez itt megfelel, mivel ez alt. olyan eljarasokba epul be ahol ezt a malloc/realloc-ot nem koveti ujabb allokacio valamint ezen felul a szoveg feldolgozasa utan ezt a dinamikusan allokalt tombot eldobod a fenebe.
- A hozzászóláshoz be kell jelentkezni
kjelző
--
unix -- több, mint kód. filozófia.
Life is feudal
- A hozzászóláshoz be kell jelentkezni
GLib hasznalata engedelyezett?
g_strsplit() es kesz is vagyunk. ;-)
- A hozzászóláshoz be kell jelentkezni