Verwenden der Zeigerdifferenz mit printf ("%. * S")
Das Problem, mit dem ich konfrontiert bin, hat mit dem intptr_tDatentyp und der Art und Weise zu tun, wie fprintf()Argumente für das %.*sFormat verwendet werden. Das %.*sFormat erwartet int, dass die Feldgenauigkeit einen Typ hat , und vielleicht ist das an sich nicht unangemessen.
In diesem Fall jedoch nicht:
#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);
}
}
}
}
Wenn ich das kompiliere, funktioniert es nicht gut damit
%.*s, und der Compiler weist darauf hin:Warnung: Die Feldgenauigkeit sollte den Typ 'int' haben, aber das Argument hat den Typ 'intptr_t' (auch bekannt als 'long') [-Wformat]
Wenn ich es schaffe
int o;, spielt es gut mit, ist%.*saber natürlich nicht ideal, und der Compiler sagt das auch:Warnung: Die implizite Konvertierung verliert an ganzzahliger Genauigkeit: 'long' bis 'int' [-Wshorten-64-to-32]
Nun, dies ist Demo-Code, und die maximale Größe, die enthalten sein okann, ist 500hier, aber in meinem tatsächlichen Code kann es sein 10,000oder sogar 100,000(immer noch sehr viel in der Größe eines 32-Bit-Int, nicht wahr?)
Was löst dieses Problem am besten mit den geringsten Änderungen?
Kompiliert auf Clang (könnte auf GCC sehr ähnlich sein) mit -Wall -Wextra -pedantic.
Antworten
Der Unterschied zwischen zwei Zeigern ist der Typ ptrdiff_t. "... ist der vorzeichenbehaftete Integer-Typ des Ergebnisses der Subtraktion von zwei Zeigern;"
// intptr_t o = p-in;
ptrdiff_t o = p - in;
Angesichts dieser beiden Punkte char in[501]passt der Unterschied auch in eine int.
Einfach besetzen. Das .*erwartet ein Match int, kein intptr_tNor ptrdiff_t.
// fprintf(write,"%.*s",o,in);
fprintf(write,"%.*s", (int) o, in);
Oder auf einmal:
fprintf(write,"%.*s", (int) (p - in), in);
p-inist eher ein ptrdiff_toder ein size_t. In diesem Fall würde ich jedenfalls Folgendes verwenden 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);
}
Fügen Sie dann Fehlerprüfungen hinzu.