Perl kód átírása C-be

 ( csortu | 2010. április 3., szombat - 4:08 )

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

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Ü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.

Köszi, megpróbálom kihámozni.
Csaba

Nos, jelenlg itt tartok:

#include 
#include 
#include 
#include 

/* 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....

Csaba

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.

c++ nem jó?

#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);
}

Nagyon szépen köszönöm.
Csaba

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.

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.

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

É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.

kjelző
--
unix -- több, mint kód. filozófia.
Life is feudal

GLib hasznalata engedelyezett?
g_strsplit() es kesz is vagyunk. ;-)