CannibalSmith ([info]cannibalsmith) rakstīja [info]koderi kopienā,
@ 2007-02-22 10:12:00

Previous Entry  Add to memories!  Tell a Friend!  Next Entry
C: fread()
struct stuff { int a; int b; }; Kāpēc sizeof(stuff) > 4 ? Kādus savus sūdus kompilators zagšus bāž manos tipos?

Bet Galvenais jautājums ir, kāpēc sekojošais kods nestrādā? Sākot ar height tiek ielasītas kaut kādas mistiskas vērtības, kas katram kompilatoram ir citas.
#include <stdio.h>

struct BitmapHeader
{
    char type[2];
    unsigned long fileSize;
    unsigned long reserved;
    unsigned long offset;
    unsigned long headerSize;
    unsigned long width;
    unsigned long height;
    unsigned int planes;
    unsigned int bits;
    unsigned long compression;
    unsigned long imageSize;
    unsigned long pixelsPerMeterX;
    unsigned long pixelsPerMeterY;
    unsigned long colorsUsed;
    unsigned long colorsImportant;
};

int main(int argc, char* argv[])
{
    FILE* input,* output;
    struct BitmapHeader bitmap;

    if (argc == 1)
    {
        printf("Usage:\nconvert <input> [<output>]\n");
        return 1;
    }

    if (argc >= 2)
    {
        printf("Opening file %s\n", argv[1]);
        if (!(input = fopen(argv[1], "r")))
        {
            printf("Cannot open input file!\n");
            return 2;
        }
        //fread(&bitmap, sizeof(struct BitmapHeader), 1, input);
        fread(bitmap.type, 1, 2, input);
        fread(&bitmap.fileSize, 4, 1, input);
        fread(&bitmap.reserved, 4, 1, input);
        fread(&bitmap.offset, 4, 1, input);
        fread(&bitmap.headerSize, 4, 1, input);
        fread(&bitmap.width, 4, 1, input);
        fread(&bitmap.height, 4, 1, input);
        fread(&bitmap.planes, 2, 1, input);
        fread(&bitmap.bits, 2, 1, input);
        fread(&bitmap.compression, 4, 1, input);
        fread(&bitmap.imageSize, 4, 1, input);
        fread(&bitmap.pixelsPerMeterX, 4, 1, input);
        fread(&bitmap.pixelsPerMeterY, 4, 1, input);
        fread(&bitmap.colorsUsed, 4, 1, input);
        fread(&bitmap.colorsImportant, 4, 1, input);
        printf("type = %c%c\n", bitmap.type[0], bitmap.type[1]);
        printf("fileSize = %u\n", bitmap.fileSize);
        printf("offset = %u\n", bitmap.offset);
        printf("headerSize = %u\n", bitmap.headerSize);
        printf("width = %u\n", bitmap.width);
        printf("height = %u\n", bitmap.height);
        printf("planes = %u\n", bitmap.planes);
        printf("bits = %u\n", bitmap.bits);
        printf("compression = %u\n", bitmap.compression);
        printf("imageSize = %u\n", bitmap.imageSize);
        printf("pixelsPerMeterX = %u\n", bitmap.pixelsPerMeterX);
        printf("pixelsPerMeterY = %u\n", bitmap.pixelsPerMeterY);
        printf("colorsUsed = %u\n", bitmap.colorsUsed);
        printf("colorsImportant = %u\n", bitmap.colorsImportant);
    }

    if (input)
    {
        fclose(input);
    }
    getchar();
    return 0;
}


(Ierakstīt jaunu komentāru)


[info]smejmoon
2007-02-22 11:13 (saite)
kas tās tev par platformām?? īstenībā jau intam un longam izmērs baitos var mainīties. nevaru iedomāties, kur mūsdienās ints ir 2 baiti.

(Atbildēt uz šo) (Diskusija)


[info]cannibalsmith
2007-02-22 11:45 (saite)
Microsoft Visual C++ 2003
Borland Turbo C++ Explorer
Visi viņi nojūdzas tieši pie height. Man domāt, ja mainīgo izmēri būtu līki, tad nekas nenolasītos.

Programmas sākumā ieliku memset(&bitmap, 0, sizeof(struct BitmapHeader)); . Izrādās, visi mainīgie sākot no height vispār netiek ielasīti. WTF!

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]smejmoon
2007-02-22 11:56 (saite)
Es domāju dzelžu arhitektūru un operētājsistēmu. Bet izskatās pēc windows32 :)

Saraksti tajā failā 0x0123 4567 89AB CDEF0; vai kautko tādu un izseko, kas, cik tālu nolasās.

int ir 4 baitus garš.

Tas ir mājasdarbs?

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]cannibalsmith
2007-02-22 12:12 (saite)
Tarajs! Kā vienmēr, kļūda ir kaut kas vienkāršs un vienkārši debīls. Fopen režīmā "r" vietā, jāraksta "rb", jo binārais nevis teksta fails, redz. Nekad nesapratīšu, kāpēc ir atšķirība. Izlaboju, un viss aizgāja.

Studiju darbs.

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]bubu
2007-02-22 13:37 (saite)
b chara esamība tajā modē garantē, ka C runtaims nemainīs ne bitu no nolasītajiem datiem, bet pados tev tieši to, kas ir failā. Pretējā gadījumā chari var pārvērsties/pazust/uzrasties no nekuriens, it īpaši baitiem ar kodu 10 vai 13, (un arī 0 laikam).

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]smejmoon
2007-02-22 16:40 (saite)
a kas ir nulle? EOF? vai EOF ir 0xFF ?

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]bubu
2007-02-22 16:45 (saite)
Nulle ir tad, ka, ja nulli skaitot nullei klāt, iegūst arī nulli.
EOF ir -1, ja nemaldos.

(Atbildēt uz šo) (Iepriekšējais)


[info]bubu
2007-02-22 13:39 (saite)
Jā, un abiem taviem nosauktajiem kompilatoriem sizeof(int) ir 4. Tāpēc arī struktūras izmērs ir >4 (visdrīzāk =8, vai ne?). Nedzīvojam taču 16-bit real mode DOSā jau sen vairs, kur int bija 2-baitīgs.

(Atbildēt uz šo) (Iepriekšējais)


Neesi iežurnalējies. Iežurnalēties?