printf("%s\n",buffer.st_size);
Wie mache ich das?
TIA,
Max
--
fortune says:
"Besides, I think [Slackware] sounds better than 'Microsoft,' don't you?"
(By Patrick Volkerding)
Ich denk' mal, st_size ist vom Typ 'typedef int off_t', oder so
printf( "%d\n", buffer.st_size ); ist da eher angebracht.
Toni
Beim Kompilieren mit "gcc -Wall -o fsize fsize.c" beschwert sich gcc:
fsize.c: In function `main':
fsize.c:19: warning: int format, __off_t arg (arg 2)
Gibt's da noch was, worüber der gcc sich nicht beschwert?
Max
--
fortune says:
"...Deep Hack Mode--that mysterious and frightening state of
consciousness where Mortal Users fear to tread."
(By Matt Welsh)
Ist ja 'nur' eine warning !
ganz brutal: give him what he wants
printf( "%d\n", (int)buffer.st_size );
Toni
> ich habe hier ein Programm, das die Funktion stat benutzt. Jetzt will
> ich die Größe der gestat'eten Datei ausgeben. Das geht nicht:
>
> printf("%s\n",buffer.st_size);
»%s« ist das printf-Format zur Ausgabe von Zeichenketten, aber die
»st_size«-Komponente einer »struct stat« ist vom Typ »off_t«, was ein
numerischer Typ ist (in der Regel »long«). Das ist der entscheidende
Fehler, denn in Deinem Code würde »printf()« den Inhalt von
»buffer.st_size« als Zeiger auf den Anfang der Zeichenkette
interpretieren, und das geht in aller Regel schief.
Leider kommt es noch etwas komplizierter: Bei Typen wie »off_t« kann
man strenggenommen auch nicht ohne weiteres sagen, welches Format man
zur Ausgabe benutzen sollte; zur Auswahl stehen »%d«, »%ld« oder gar
»%lld« (auf Systemen, die »long long« unterstützen). Gerade »off_t«
hat im Zeitalter von Dateisystemen, die Dateien ermöglichen, die
länger als 2^31 Bytes sind, gute Chancen, nicht mehr in ein »long« zu
passen, wenn aus Kompatibilitätsgründen »int« und »long« beide 32 Bit
benutzen (etwa auf i386-Linux).
Rein offiziell sollte man nach dem neuen Standard (»ISO
C99«) alles prophylaktisch auf »long long« casten können, also
printf("%lld", (long long)buffer.st_size);
aber das gibt natürlich Probleme beim Portieren auf ältere C-Systeme.
Für den Moment ist es vielleicht am sichersten, etwas wie
printf("Dateigröße: " OFF_T_FMT, OFF_T_FMT_CAST(buffer.st_size));
zu verwenden und »OFF_T_FMT« und »OFF_T_FMT_CAST« irgendwo geeignet
zu definieren, nachdem man sich -- etwa per Autoconf -- über die
Breite von »off_t« schlau gemacht hat.
Anselm
--
Anselm Lingnau .......................................... ans...@strathspey.org
Excuse me while I open Pandora's box. -- Ed Berard
> Hi,
> ich habe hier ein Programm, das die Funktion stat benutzt. Jetzt will
> ich die Größe der gestat'eten Datei ausgeben. Das geht nicht:
>
> printf("%s\n",buffer.st_size);
man stat sagt mir:
struct stat
{
dev_t st_dev; /* Device */
ino_t st_ino; /* INode */
umode_t st_mode; /* Protection */
nlink_t st_nlink; /* Anzahl d. Hard_Links */
uid_t st_uid; /* UID des Besitzers */
gid_t st_gid; /* GID des Besitzers */
dev_t st_rdev; /* Typ (wenn INode-Device) */
off_t st_size; /* Grösse in Bytes*/
unsigned long st_blksize; /* Blockgrösse */
unsigned long st_blocks; /* Allozierte Blocks */
time_t st_atime; /* Letzter Zugriff */
time_t st_mtime; /* Letzte Modifikation */
time_t st_ctime; /* Letzte Aenderung */
};
also ist off_t der Typ von st_size
ein bisschen buddeln in den Headern ergibt:
# ifndef __off_t_defined
# ifndef __USE_FILE_OFFSET64
typedef __off_t off_t;
# else
typedef __off64_t off_t;
# endif
# define __off_t_defined
# endif
typedef long int __off_t;
Also muß Du dich fragen welchen Typ benutzt Dein Linux. Bei mir ist es
long int auf Intel Pentium also ein "normaler" long (oder int)
Ja, Header greppen macht Spaß
Somit sollte das ungefähr tun:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
enum {BUFSIZE=512};
static void usage (){
fprintf(stdout, "program-name <file to run stat on>\n");
exit (EXIT_FAILURE);
}
int main (int argc, char* argv[]){
struct stat stats = {0};
char *file_to_stat = NULL;
int ret_val = 0;
char error_msg [BUFSIZE];
if (argc < 2) {
usage();
}
;
file_to_stat = argv[1];
errno = 0;
ret_val = stat(file_to_stat, &stats);
if (ret_val < 0) {
strncpy(error_msg, strerror(errno), (size_t) BUFSIZE);
fprintf (stderr, "stat failed on %s with %s\n", file_to_stat,
error_msg);
exit (EXIT_FAILURE);
}
printf("file %s is %ld Bytes long\n", file_to_stat, (long)stats.st_size);
exit (EXIT_SUCCESS);
}
Bis dann
Friedrich
Warum wird eigentlich off_t als Typ genommen und nicht long int oder so?
Denn so wie ich das jetzt verstanden habe, ist off_t nichts anderes
als ein long int bzw. ein long long int.
TIA,
Max
--
fortune says:
"World domination. Fast"
(By Linus Torvalds)
Lies dir die Frage nochmal genau durch.
Wenn sie sich dir dann immer noch so stellt, solltest du das
Programmieren sofort einstellen.
Felix
> Warum wird eigentlich off_t als Typ genommen und nicht long int oder so?
> Denn so wie ich das jetzt verstanden habe, ist off_t nichts anderes
> als ein long int bzw. ein long long int.
Genau das ist das Problem. Bei manchen Systemen ist es »long«, bei
anderen »long long«. Darum hat man dafür einen eigenen Typ definiert,
damit die Leute, die eine Variable brauchen, die für eine Dateigröße
reicht, keine #ifdef-Orgie veranstalten müssen, sondern einfach
»off_t bla;« sagen können.
Heutzutage könnte man wahrscheinlich von vornherein »long long«
festlegen, aber das ist (a) bei manchen Betriebssystemen
Verschwendung, und (b) war, als man sich auf die Typen der »struct
stat«-Komponenten geeinigt hat, »long long« noch nicht erfunden. (c)
gibt es jede Menge C-Übersetzer auf dieser Welt, die »long long« nicht
kennen und es auch nie mehr lernen werden.
(In 30 Jahren gibt es dann dasselbe Spiel mit »long long long«.)
Anselm
--
Anselm Lingnau .......................................... ans...@strathspey.org
The obvious mathematical breakthrough [for breaking modern encryption] would
be the development of an easy way to factor large prime numbers.
-- Bill Gates, *The Road Ahead*
Um genau zu sein habe ich noch nicht mal ernsthaft angefangen. Ich
habe bis jetzt immer nur Source Code von anderen Programmen angeguckt
und dran rumgespielt, ohne mein C-Buch richtig gelesen zu
haben. Deswegen manchmal solche Fragen.
A propos: Das Buch "GoTo C-Programmierung" von Guido Krüger kann ich
nicht empfehlen.
Max
--
fortune says:
"A word to the wise: a credentials dicksize war is usually a bad idea on the
net."
(David Parsons in c.o.l.development.system, about coding in C.)
> (In 30 Jahren gibt es dann dasselbe Spiel mit »long long long«.)
Auf den ersten Blick scheint es mir, als ob die Grammatik von C eindeutig
bliebe (modulo dangling else), wenn man Formulierungen wie " int 32 "
einfuehren wuerde. Waere vielleicht weniger pervers, als eines Tages raten
zu muessen, was " short long long long " bei den meisten Compilern bedeutet.
Damit koennte man dann z.B. uint32_t in sys/types.h portabel definieren.
Naja, Wunschdenken.
Ciao,
Perle
--
____ Frank Wilde | pe...@cs.TU-Berlin.DE | +49 30 3454141
/ +-.\ Spelling errors are covert channels
| |-' | PLEASE TELL ME IF YOU RECORD MY EMAIL ADDRESS SO I CAN FORWARD CHANGES
\_|__/ Subject: Please inform <your address>
Mit etwas Glück nutzt in 30 Jahren keine Sau mehr C.
Ciao,
Oliver
--
Obviously, because programming is a creative activity there is not
going to be a set of rules which will always lead us mechanically
to a solution to a problem.
(Simon Thompson: Haskell - The Craft of Functional Programming)
> Anselm Lingnau <anselm...@strathspey.org> wrote:
>
> > (In 30 Jahren gibt es dann dasselbe Spiel mit »long long long«.)
>
> Auf den ersten Blick scheint es mir, als ob die Grammatik von C eindeutig
> bliebe (modulo dangling else), wenn man Formulierungen wie " int 32 "
> einfuehren wuerde. Waere vielleicht weniger pervers, als eines Tages raten
> zu muessen, was " short long long long " bei den meisten Compilern bedeutet.
>
> Damit koennte man dann z.B. uint32_t in sys/types.h portabel definieren.
>
> Naja, Wunschdenken.
Nicht ganz. C99 hat stdint.h eingefuehrt,das dir diese Typen portabel
definiert.
-Andi
> Mit etwas Glück nutzt in 30 Jahren keine Sau mehr C.
Das haben sie 1970 auch über COBOL gesagt.
Anselm
--
Anselm Lingnau .......................................... ans...@strathspey.org
The physician can bury his mistakes, but the architect can only advise his
clients to plant vines. -- Frank Lloyd Wright
test.c:1: warning: Microsoft-ISO C2019 does not support 'long long long'
test.c:1: 'long long long long' is too long for GCC
This error message was sponsored by Microsoft.
--
Frank Klemm
--
Frank Klemm