Utilizzo della differenza di puntatori con printf ("%. * S")
Il problema che sto affrontando ha a che fare con il intptr_ttipo di dati e il modo in cui fprintf()accetta argomenti per il %.*sformato. Il %.*sformato prevede che la precisione del campo abbia il tipo int, e forse non è irragionevole di per sé.
Non in questo caso però:
#include <stdio.h>
#include <stdint.h>
int main() {
char fname[] = "Some_File.txt";
FILE *write = fopen(fname,"w");
if(write!=NULL){
printf("\n\tType below :\n\n");
char in[501]=""; char *p;
while(1){
fgets(in,MAX_LN,stdin);
/*** Region with compiler warnings begins ***/
if((p=strstr(in,"/end/"))!=0){
intptr_t o = p-in;
fprintf(write,"%.*s",o,in);
/*** Region with compiler warnings ends ***/
fclose(write);
break;
}
else{
fputs(in,write);
}
}
}
}
Se lo compilo, non funziona bene
%.*se il compilatore lo fa notare:avvertenza: la precisione del campo dovrebbe avere il tipo "int", ma l'argomento ha il tipo "intptr_t" (noto anche come "long") [-Wformat]
Se lo faccio
int o;, funziona bene%.*sma ovviamente non è l'ideale, e il compilatore lo dice:avviso: la conversione implicita perde la precisione del numero intero: da "long" a "int" [-Wshorten-64-to-32]
Ora, questo è il codice demo e la dimensione massima che opuò contenere è 500qui, tuttavia, nel mio codice effettivo, può essere 10,000o anche 100,000(ancora molto entro la dimensione di un int a 32 bit, non è vero?)
Quindi cosa risolverà questo meglio con il minimo cambiamento?
Compilato su Clang (potrebbe essere molto simile su GCC) con -Wall -Wextra -pedantic.
Risposte
La differenza di due puntatori è il tipo ptrdiff_t. "... è il tipo intero con segno del risultato della sottrazione di due puntatori;"
// intptr_t o = p-in;
ptrdiff_t o = p - in;
Dato che entrambi puntano char in[501], la differenza rientra anche in un file int.
Lancia semplicemente. Si .*aspetta una corrispondenza int, non un intptr_tné ptrdiff_t.
// fprintf(write,"%.*s",o,in);
fprintf(write,"%.*s", (int) o, in);
O tutto in una volta:
fprintf(write,"%.*s", (int) (p - in), in);
p-inè più un ptrdiff_to un size_t. Ad ogni modo, in questo caso, userei fwrite:
if ((p = strstr(in, "/end/")) != NULL) {
size_t len = p - in;
fwrite(in, sizeof(char), len, write);
fclose(write);
break;
} else {
fputs(in, write);
}
Quindi aggiungi i controlli di errore.