Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Wie gebe ich st_size aus?

8 views
Skip to first unread message

Max Werner

unread,
Aug 14, 2001, 4:54:33 AM8/14/01
to
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);

Wie mache ich das?

TIA,
Max
--
fortune says:
"Besides, I think [Slackware] sounds better than 'Microsoft,' don't you?"
(By Patrick Volkerding)

Toni Erdmann

unread,
Aug 14, 2001, 5:03:09 AM8/14/01
to
Max Werner wrote:
>
> 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);

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

Max Werner

unread,
Aug 14, 2001, 5:09:05 AM8/14/01
to

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)

Toni Erdmann

unread,
Aug 14, 2001, 5:22:55 AM8/14/01
to
Max Werner wrote:
>
> Toni Erdmann <Antonius...@icn.siemens.de> wrote:
> > Max Werner wrote:
> >>
> >> 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);
> >
> > Ich denk' mal, st_size ist vom Typ 'typedef int off_t', oder so
> >
> > printf( "%d\n", buffer.st_size ); ist da eher angebracht.
>
> 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?

Ist ja 'nur' eine warning !

ganz brutal: give him what he wants

printf( "%d\n", (int)buffer.st_size );

Toni

Anselm Lingnau

unread,
Aug 14, 2001, 5:13:37 AM8/14/01
to
Max Werner <m...@home-werner.de> schrieb:

> 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

Friedrich Dominicus

unread,
Aug 14, 2001, 8:21:00 AM8/14/01
to
"Max Werner" <m...@home-werner.de> writes:

> 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

Max Werner

unread,
Aug 14, 2001, 6:21:46 PM8/14/01
to
Anselm Lingnau <anselm...@strathspey.org> wrote:
> Max Werner <m...@home-werner.de> schrieb:
>
>> 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).

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)

Felix von Leitner

unread,
Aug 14, 2001, 9:02:13 PM8/14/01
to
Thus spake Max Werner (m...@home-werner.de):

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

Lies dir die Frage nochmal genau durch.
Wenn sie sich dir dann immer noch so stellt, solltest du das
Programmieren sofort einstellen.

Felix

Anselm Lingnau

unread,
Aug 14, 2001, 7:05:49 PM8/14/01
to
Max Werner <m...@home-werner.de> schrieb:

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

Max Werner

unread,
Aug 15, 2001, 4:08:07 AM8/15/01
to

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

Frank Wilde

unread,
Aug 16, 2001, 4:02:10 PM8/16/01
to
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.

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>

Oliver Bandel

unread,
Aug 17, 2001, 3:02:12 AM8/17/01
to

Anselm Lingnau <anselm...@strathspey.org> wrote:
[...]

> (In 30 Jahren gibt es dann dasselbe Spiel mit »long long long«.)
[...]

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)

Andi Kleen

unread,
Aug 17, 2001, 3:15:25 AM8/17/01
to
pe...@cs.tu-berlin.de (Frank Wilde) writes:

> 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

Anselm Lingnau

unread,
Aug 17, 2001, 5:17:23 AM8/17/01
to
Oliver Bandel <oli...@first.in-berlin.de> schrieb:

> 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

Frank Klemm

unread,
Sep 4, 2001, 8:11:24 AM9/4/01
to
On 14 Aug 2001 23:05:49 +0000, Anselm Lingnau <anselm...@strathspey.org> wrote:
>Max Werner <m...@home-werner.de> schrieb:
>
>> 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«.)
>
und der Fehlermeldung:

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

unread,
Sep 4, 2001, 8:12:35 AM9/4/01
to
On 17 Aug 2001 09:02:12 +0200, Oliver Bandel <oli...@first.in-berlin.de> wrote:
>
>Anselm Lingnau <anselm...@strathspey.org> wrote:
>[...]
>> (In 30 Jahren gibt es dann dasselbe Spiel mit »long long long«.)
>[...]
>
>Mit etwas Glück nutzt in 30 Jahren keine Sau mehr C.
>
Atomkrieg ?
Biologische Killerviren ?
Wunder ?

--
Frank Klemm

0 new messages