Newsgroup: it.comp.lang.c
Titolo: Malefiche stringhe

Il problemino che ho è questo:
passo come argomenti di un exe il nome di un file con dati di input, un
intero (numero iterazioni) ed una opzione.
Quello che vorrei fare è che a partire dal nome del file di input venga
creato in nome del file di output con alcune modifiche:
nome file di input: pippo.txt
nome file di output: out_pippo_niter100.txt
Non riesco a farlo. Ecco cosa ho scritto:
int main(int argc, char **argv)  {
  FILE *InFile, *OutFile;
  char *InFileName, *OutFileName;
   // qui sono dichiarazioni varie
  /*  Controlla della correttezza dei parametri da riga di comando
*/
  if (argc < 4) {
    fprintf(stderr, "Sintassi corretta: %s inputfile outputfile maxiter
printOptionm\n",
            argv[0]);
    fprintf(stderr, "  inputfile  : file di testo contenente i dati di
input\n");
    fprintf(stderr, "  maxiter    : numero massimo di iterazioni;\n");
    fprintf(stderr, "  printOption: opzioni di stampa (0..2);\n");
    exit(1);
  }
  /* Assegnazione dei nomi di file per la successiva apertura */
  InFileName  = argv[1];
  OutFileName = argv[2];
  niter  = atoi(argv[3]);
  prttyp = atoi(argv[4]);
  OutFileName=createName(InFileName, niter);
char *createName(char *InFileName, int niter){
  char *point;
  char *name3;
  char name[40];
  char name2[40];
  name3 = (char *)strdup(InFileName);
  point=strstr(name3,".");
  if(point)
    name=strtok(name,".");
  strcat("out_",name);
  strcat(name,"_niter");
  name2=(char*)niter;
  strcat(name2,".txt");
  strcat(name,name2);
  return name;
}
Purtroppo non va. Inoltre vorrei essere sicuro di non fare casini tra char*
e char [40]. Ricordo che bisognava usare una cosa tipo strdup poichè il
char* è solo un puntatore ed invece la stringa andava correttamente
allocata.
Insomma so di avere un po' di confusione in merito, ma non trovo nulla in
rete che possa aiutarmi.
Vi sarei grato se mi chiariste un po' la confusione/ignoranza.
GRAZIE, COME SEMPRE
P.S.: OUTFileName riceve il return della funzione è corretto o posso esserci
casini per una non corretta allocazione della memoria alla stringa?

   return name;
Stai restituendo il puntatore a un'area di memoria non piů valida, 
all'uscita della funzione, in quanto appartenente allo stack.
Scritto al volo:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *createName(const char *name) {
    char *result=0;
    char *myext = ".miaestensione";
    if ((result=calloc(strlen(name)+strlen(myext)+1,1)))
       sprintf(result, "%s%s", name, myext); 
 
    return result;
}
int main()
{
     printf("\"%s\"\n", createName("paperino"));
     return 0;
}

"Andrea Laforgia" <x...@xx.xx> ha scritto nel messaggio
news:61vAe.13155$b93....@tornado.fastwebnet.it...

Ho capito gli errori, ma i problemi che ho io sono poichč devo fare
tutt'altra cosa, e cioč?
- verificare se il nome del file di input ha l'estensione (č stato scritto
pippo oppure pippo.txt?)
- prendere il nome senza estenzione (se c'era) ed aggiugere avanti al nome
"out_" e dopo il nome "_niter" ed il numero di iterazioni
-mettere l'estenzione ".txt"
Ok, ma leggendo un po' il manuale, come mi avevi giustamente consigliato
avevo pensato di fare una cosa tipo:
punt = strchr(inputname,".");
*punt = 0x0;
 sprintf(output,"out_%s_niter_%d.txt",inputname,niter);
Ma ho sempre i dubbi sulle allocazioni da fare nella funzione e nel main.
Cosě non dovrebbe andare bene?
Grazie

 *punt = 0x0;
E se punt è 0 (i.e. non c'è l'estensione) ?

 E se punt è 0 (i.e. non c'è l'estensione) ?
ok questa la risolvo così:
  point=strchr(name3,".");
  if(point)
    *punt = 0x0;
Ma per le allocazioni?

 Ciobin wrote:
[CUT]
La mia funzione sarebbe:
char *createName(char *InFileName, int niter){
  punt = strchr(InFileName,".");
  if(punt)
    *punt = 0x0;
  sprintf(output,"out_%s_niter_%d.txt",inputname,niter);
  return output;
}
Il problema è come e dove allocare output, e se nel main è corretto:
  InFileName  = argv[1];
  OutFileName = argv[2];
  niter  = atoi(argv[3]);
  prttyp = atoi(argv[4]);
  OutFileName=createName(InFileName, niter);
con:
  FILE *InFile, *OutFile;
  char *InFileName, *OutFileName;
Oppure bisogna fare allocazioni varie?


E se il nome del file č: "a.me.piace.usare.il.punto.nel.nome.dei.files.txt" 
? :)
Te lo tronca e diventa "a".
Forse sarebbe piů opportuno usare strrchr() che trova l'ultima occorenza
di un carattere piuttosto che la prima.
Andrea Fontana
www.e-nuts,net 

 Il problema è come e dove allocare output, e se nel main è corretto:
Se tu avessi guardato il codice che ho scritto nel mio messaggio 
precedente, adesso lo sapresti.

 di un carattere piuttosto che la prima.
Altamente inefficiente, meglio scorrere all'indietro la stringa.
In un mio messaggio precedente nel gruppo ho postato una funzione che 
estrae l'estensione.  Questo mi pare l'avessi già scritto...

"Andrea Laforgia" <x...@xx.xx> ha scritto nel messaggio
news:XTvAe.13302$b93....@tornado.fastwebnet.it...

Ok, allora rileggo il tuo codice:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *createName(const char *name) {
    char *result=0;
    char *myext = ".miaestensione";
    if ((result=calloc(strlen(name)+strlen(myext)+1,1)))
       sprintf(result, "%s%s", name, myext);
    return result;
}
int main()
{
     printf("\"%s\"\n", createName("paperino"));
     return 0;
}
L'allocazione la capisco, ma nel tuo main passi una const char* mentre a me
la cosa è totalmente diversa.
Quello che sto cercando di chiedere e se quanto da me scritto è corretto.
Scusa ma non vedo nulla che risponda ai miei dubbi nel tuo main().
Ho provato a modificare tutto con la corretta allocazione nella funzione, ma
restano i miei dubbi sul main() e mi saresti davvero di grande aiuto se me
li chiarissi o se mi dicessi se quanto scritto qui sotto è ok.
char *createName(char *InFile, char* niter){
  char *punt;
  punt = strchr(InFile,".");
  if(punt)
    *punt = 0x0;
  if
((result=calloc(strlen(InFile)+strlen("_niter")+strlen("out_")+strlen(niter)
+strlen(".txt")+1,1)))
      sprintf(result,"out_%s_niter_%s.txt",inFile,niter);
  return result
}
Nella calloc sono stato prolisso poichè volevo fosse chiaro tutto.
Nel Main:
char *InFileName, *OutFileName;
InFileName  = argv[1];     <-------  Questo basta o bisogna allocare?
niter  = atoi(argv[2]);
OutFileName=createName(InFileName, argv[2]);  <----- passo niter come char*
in modo che posso usare strlen()
OutFileName è a posto dato che viene allocato nella funzione createName() e
poi lorestituito con la return result.
Giusto?
Adesso è tutto corretto, vero?
Spero che la tua pazienza non sia finita. :-)))

"Andrea Laforgia" <x...@xx.xx> ha scritto nel messaggio
news:6VvAe.13304$b93....@tornado.fastwebnet.it...

Questo non è un problema. I file avratto sempre ho l'estesione nome.ext
oppure non l'avranno.
Grazie

 poi lorestituito con la return result.
Esatto.  Il che risolve il tuo problema originale.

"Andrea Laforgia" <x...@xx.xx> ha scritto nel messaggio
news:tewAe.13336$b93....@tornado.fastwebnet.it...

Quindi quel codice è corretto, giusto?
If(tua_risposta)
    printf("ALEEEEEEEEEEEEEEEEE !!!!\nGRAZIE MILLE");
else
    printf(":-((((((( \n GRAZIE CMQ!!!");
Ciao

"Andrea Laforgia" <x...@xx.xx> ha scritto nel messaggio
news:tewAe.13336$b93....@tornado.fastwebnet.it...

Ho due problemi:
1) strchr(cs,c)  --> c deve essere un int invece io devo cercare "."
2) Nel main() InFile risulta modificato e non deve esserlo.

 Quindi quel codice è corretto, giusto?
Il codice che io ti ho postato è corretto.

"Andrea Laforgia" <x...@xx.xx> ha scritto nel messaggio
news:tewAe.13336$b93....@tornado.fastwebnet.it...

Ottengo anche un warning:
"maxsat12.c": W8060 Possibly incorrect assignment in function createName at
line 147
è la riga della calloc.
Ho fatto alcune modifiche per risolvere quei problemi che avevo, gli daresti
un occhio?
char *createName(char *InFile, char* niter){
  char *punt;
  char *result;
  char *InFile_tmp;
  InFile_tmp=strdup(InFile);
  punt = strstr(InFile_tmp,".");
  if(punt) *punt = 0x0;
if((result=calloc(strlen(InFile_tmp)+strlen("_niter")+strlen("out_")+strlen(
niter)+strlen(".txt")+1,1)))
    sprintf(result,"out_%s_niter_%s.txt",InFile_tmp,niter);
  return result;
}

 Il codice che io ti ho postato è corretto.
IO mi riferivo all'ultimo che io ho mandato

 2) Nel main() InFile risulta modificato e non deve esserlo.
Ho creato un char * nella funzione ed ho fatto una strdup. Così è ok, vero?


[CUT]
Ok, dimentica che strdup non è standard quindi:
NON :      InFile_tmp=strdup(InFile);
Ma:
  if(InFile_tmp=calloc(strlen(InFile)+1,1))
    sprintf(InFile_tmp,"%s",InFile);
A questo punto mi da anche su questa calloc il warning:
W8060 Possibly incorrect assignment in function createName
E ora che diavolo ha che non va?

 ha scritto nel messaggio
news:TRwAe.10934$QV1.1...@twister2.libero.it...

Ho risolto, gli dava fastidio l'assegnazione nell'if. Ma?!!! :-OOOOO

 Ho risolto, gli dava fastidio l'assegnazione nell'if. Ma?!!! :-OOOOO
Semplicemente il compilatore ti informa che quell'assegnamento e`
sospetto. Un errore abbastanza comune e` scrivere:
if (foo = bar)
al posto di:
if (foo == bar)
generando quindi un'assegnamento al posto di un confronto. Il tuo
compilatore ti segnala appunto questa cosa. Per zittire il warning (e
per chiarire la cosa ad eventuali lettori del tuo codice - anche se in
questo cosa non e` ambiguo) puoi scrivere:
if ((foo = bar))
Luca
-- 
Home: 
http://kronoz.cjb.net
Non ho ancora capito se il mio cane e` maschio o femmina:
quando fa la pipi` si chiude in bagno