kostenloser Webspace werbefrei: lima-city


Datei einlesen und XY-Koordinaten in Array Speichern

lima-cityForumProgrammiersprachenC/C++ und D

  1. Autor dieses Themas

    lordcodex

    Kostenloser Webspace von lordcodex

    lordcodex hat kostenlosen Webspace.

    Hallo zusammen =)

    Erstmal zum Problem:

    Ich brauche ein Medium wo ich ein Muster speichern kann, welches aus nur 2 verschiedenen Elementen bestehen soll!
    Z.B: 0 oder 1 (im grunde is es egal was genau es is...hauptsache 2 verscheidene)
    Dieses soll in einem rechteckigen Muster angeordnet sein!

    Die Aufgabe dabei ist, das ich mit meiner Funktion das Medium einlesen möchte und dann z.b nur die Koordinaten der 1en in einem Array speichere!

    Ich hatte mir überlegt ich gib als Voraussetzung das man z.B sowas als "Leinwand" benutzt:

    Datei:
    oooooooooo
    ooo####ooo
    oooo##oooo
    oooo##oooo
    oooooooooo


    Dabei müsst ich die einzelnen ASCII Zeichen als Elemente eines Koordinatensystem interpretieren...
    10 Elemente Breit und 5 Elemente Tief!

    Somit wäre wenn man von oben-rechts das Koordinaten System aufsetzt die erste linke obere "#" im X-Y-Koordinatensystem:
    2-4
    Die nachfolgende eine 2-5, ... somit sollte dann in meine Funktion am Ende ein Array mit solchen Tupeln ausgeben:
    2-4, 2-5, 2-6, 2-7, 3-5, 3-6, 4-5, 4-6

    Hoffe konnte es nun mehr oder weniger verständlich erklären!

    Nun zu meiner Frage:

    Eigentlich wollte ich es simpel halten so das man schnell selber Muster bilden kann und dann die Funktion drüber laufen lassen um die Koordinaten zu bekommen...
    Jedoch ist es doch schon ein ziemlicher Aufwand Zeile für Zeile Daten einzulesen und das in ein Koordinatensystem umzuwandeln...

    Hätte vielleicht irgendwer eine andere Möglichkeit wie man sowas realisieren kann?!

    Würde mich über Anregungen sehr freuen ;)

    LG DeX

    //EDIT sollte auf jeden Fall mit C realisierbar sein ^.^

    Beitrag zuletzt geändert: 30.4.2012 22:19:56 von lordcodex
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. t*****b

    Wo ist genau das Problem? Das ganze funktioniert so:

    Textdatei öffnen
    
    Für jede Zeile // Y durchlaufen {
     Für jedes Zeichen // X durchlaufen {
      Ist aktuelles Zeichen ein #? {
       ja: Werte in Array schreiben 
      }
     }
    }


    Außerdem...

    lordcodex schrieb:
    Datei:
    oooooooooo
    ooo####ooo
    oooo##oooo
    oooo##oooo
    oooooooooo


    Somit wäre wenn man von oben-rechts das Koordinaten System aufsetzt die erste linke obere "#" im X-Y-Koordinatensystem:
    2-4


    2|4 = Zwie nach rechts, 4 nach unten. hast du von der oben rechten Ecke nicht definiert
    oder du meinst 2|-4 = zwei nach rechts, 4 nach oben, ist genauso wenig definiert

    ich weiß nicht wie du da irgendwie, egal von welcher Ecke aus, auf ein # gelangen willst, von der Ecke oben rechts aus wäre das erste # -4|2

    Noch ein Tipp: Fang bei Arrays immer mit 0 an zu zählen.
  4. Hallo lordcodex,

    Deine Muster sollten sich eigentlich wunderbar in einem Monochrome-Bild speicher lassen. Der Einfachheit halber kann man dafür z.B.
    das PBM-Format verwenden, dann kannst Du die Muster sogar mit Gimp zeichnen (als PBM ASCII speichern). Laden kannst Du es dann z.B. mit folgendem Code:
    pbm_image.h:
    #ifndef _PBM_IMAGE_H_
    #define _PBM_IMAGE_H_
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    typedef struct pbm_image_
    {
      long width;
      long height;
      unsigned char ** data;
    } pbm_image_t, * PBMImage;
    
    PBMImage PBMImage_Create(long width, long height);
    PBMImage PBMImage_CreateFromFile(const char * path);
    void PBMImage_Free(PBMImage img);
    int PBMImage_Save(PBMImage img, const char * path);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    pbm_image.c:
    #include "pbm_image.h"
    
    #include <stdlib.h>
    #include <stdio.h>
    
    static void pbm_goto_eol(FILE * file)
    {
      int c;
    
      do
      {
        c = fgetc(file);
      }
      while(c!='\r' && c!='\n' && c!=EOF);
    }
    
    static void pbm_skip_whitespace(FILE * file)
    {
      int c;
    
      do
      {
        c = fgetc(file);
        if(c == '#')
        {
          pbm_goto_eol(file);
          c = ' ';
        }
      }
      while(c==' ' || c=='\t' || c=='\r' || c=='\n');
    
      if(c!=EOF)
        ungetc(c,file);
    }
    
    PBMImage PBMImage_Create(long width, long height)
    {
      long i;
      PBMImage img;
    
      if(width < 1 || height < 1)
      {
        fprintf(stderr, "Error: PBMImage_Create: invalid size.\n");
        return NULL;
      }
    
      if(!(img = (PBMImage)calloc(1, sizeof(pbm_image_t))))
      {
        fprintf(stderr, "Error: PBMImage_Create: calloc() for img failed.\n");
        return NULL;
      }
    
      img->width = width;
      img->height = height;
    
      if(!(img->data = (unsigned char **)calloc(height, sizeof(unsigned char *))))
      {
        fprintf(stderr, "Error: PBMImage_Create: calloc() for img->data failed.\n");
        PBMImage_Free(img);
        return NULL;
      }
    
      if(!(img->data[0] = (unsigned char*)calloc(width*height, sizeof(unsigned char))))
      {
        fprintf(stderr, "Error: PBMImage_Create: calloc() for img->data[0] failed.\n");
        PBMImage_Free(img);
        return NULL;
      }
    
      for(i=1; i<height;i++)
        img->data[i] = &img->data[0][width*i];
    
      return img;
    }
    
    PBMImage PBMImage_CreateFromFile(const char * path)
    {
      int c;
      long x, y, width, height;
      PBMImage img;
      FILE * in;
    
      if(!path)
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: path = NULL.\n");
        return NULL;
      }
    
      if(!(in = fopen(path,"rb")))
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: Can't open file.\n");
        return NULL;
      }
    
      c = fgetc(in);
    
      if(c != 'P')
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: invalid file header.\n");
        fclose(in);
        return NULL;
      }
    
      c = fgetc(in);
    
      if(c != '1')
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: invalid file header.\n");
        fclose(in);
        return NULL;
      }
    
      pbm_skip_whitespace(in);
    
      if(fscanf(in,"%ld",&width)!=1)
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: unable to read image width.\n");
        fclose(in);
        return NULL;
      }
    
      if(width < 1)
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: invalid image width.\n");
        fclose(in);
        return NULL;
      }
    
      pbm_skip_whitespace(in);
    
      if(fscanf(in,"%ld",&height)!=1)
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: unable to read image height.\n");
        fclose(in);
        return NULL;
      }
    
      if(height < 1)
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: invalid image height.\n");
        fclose(in);
        return NULL;
      }
    
      if(!(img = PBMImage_Create(width, height)))
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: PBMImage_Create() for img failed.\n");
        fclose(in);
        return NULL;
      }
    
      for(y=0;y<height;y++)
      for(x=0;x<width; x++)
      {
        pbm_skip_whitespace(in);
    
        if(fscanf(in,"%d", &c)!=1)
        {
          fprintf(stderr, "Error: PBMImage_CreateFromFile: I/O or file error.\n");
          PBMImage_Free(img);
          fclose(in);
          return NULL;
        }
    
        if(!c)
          img->data[y][x] = 1;
      }
    
      fclose(in);
      return img;
    }
    
    void PBMImage_Free(PBMImage img)
    {
      if(!img)
        return;
    
      if(img->data)
      {
        if(img->data[0])
          free(img->data[0]);
    
        free(img->data);
      }
    
      free(img);
    }
    
    int PBMImage_Save(PBMImage img, const char * path)
    {
      long idx, counter;
      FILE *out;
    
      if(!img)
      {
        fprintf(stderr, "Error: PBMImage_Save: img = NULL.\n");
        return 0;
      }
    
      if(!path)
      {
        fprintf(stderr, "Error: PBMImage_Save: path = NULL.\n");
        return 0;
      }
    
      if(!(out = fopen(path,"wb")))
      {
        fprintf(stderr, "Error: PBMImage_Save: Can't open file.\n");
        return 0;
      }
    
      if(fprintf(out, "P1\n")<0)
      {
        fprintf(stderr, "Error: PBMImage_Save: I/O error.\n");
        fclose(out);
        return 0;
      }
    
      if(fprintf(out, "%d\n", img->width)<0)
      {
        fprintf(stderr, "Error: PBMImage_Save: I/O error.\n");
        fclose(out);
        return 0;
      }
    
      if(fprintf(out, "%d\n", img->height)<0)
      {
        fprintf(stderr, "Error: PBMImage_Save: I/O error.\n");
        fclose(out);
        return 0;
      }
    
      counter = 0;
    
      for(idx=0;idx<img->width*img->height;idx++)
      {
        if(img->data[0][idx])
        {
          if(fprintf(out, "0 ") < 0)
          {
            fprintf(stderr, "Error: PBMImage_Save: I/O error.\n");
            fclose(out);
            return 0;
          }
        }
        else
        {
          if(fprintf(out, "1 ") < 0)
          {
            fprintf(stderr, "Error: PBMImage_Save: I/O error.\n");
            fclose(out);
            return 0;
          }
        }
    
        counter++;
    
        if(counter == 35)
        {
          if(!fprintf(out, "\n"))
          {
            fprintf(stderr, "Error: PBMImage_Save: I/O error.\n");
            fclose(out);
            return 0;
          }
    
          counter = 0;
        }
      }
    
      fclose(out);
      return 1;
    }
    Die Koordinatenextraktion geht dann so:
    #include <stdio.h>
    #include "pbm_image.h"
    
    typedef struct
    {
      long x;
      long y;
    } coord_t;
    
    long get_coord_count(PBMImage img)
    {
      long x, y, count;
      
      count = 0;
      for(y=0; y<img->height; y++)
      for(x=0; x<img->width; x++)
      {
        if(img->data[y][x])
          count++;
      }
      
      return count;
    }
    
    void get_coords(PBMImage img, coord_t * coords)
    {
      long x, y, idx;
      
      idx = 0;
      
      for(y=0; y<img->height; y++)
      for(x=0; x<img->width; x++)
      {
        if(img->data[y][x])
        {
          coords[idx].x = x;
          coords[idx].y = y;
          idx++;
        }
      }
    }
    
    int main(int argc, char ** argv)
    {
      long i, count;
      coord_t * coords;
      PBMImage img;
      
      img = PGMImage_CreateFromFile("test.pbm");
      
      count = get_coord_count(img);
      coords = calloc(count, sizeof(coord_t));
      get_coords(img, coords);
      
      for(i=0;i<count;i++)
      {
        printf("[%ld; %ld]\n", coord[i].x, coords[i].y);
      }
      
      getchar();
      return 0;
    }


    Beitrag zuletzt geändert: 1.5.2012 17:16:47 von darkpandemic
  5. Autor dieses Themas

    lordcodex

    Kostenloser Webspace von lordcodex

    lordcodex hat kostenlosen Webspace.

    Die Koordinatenextraktion geht dann so:
    #include <stdio.h>
    #include "pbm_image.h"
    
    typedef struct
    {
      long x;
      long y;
    } coord_t;
    
    long get_coord_count(PBMImage img)
    {
      long x, y, count;
      
      count = 0;
      for(y=0; y<img->height; y++)
      for(x=0; x<img->width; x++)
      {
        if(img->data[y][x])
          count++;
      }
      
      return count;
    }
    
    void get_coords(PBMImage img, coord_t * coords)
    {
      long x, y, idx;
      
      idx = 0;
      
      for(y=0; y<img->height; y++)
      for(x=0; x<img->width; x++)
      {
        if(img->data[y][x])
        {
          coords[idx].x = x;
          coords[idx].y = y;
          idx++;
        }
      }
    }
    
    int main(int argc, char ** argv)
    {
      long i, count;
      coord_t * coords;
      PBMImage img;
      
      img = PGMImage_CreateFromFile("test.pbm");
      
      count = get_coord_count(img);
      coords = calloc(count, sizeof(coord_t));
      get_coords(img, coords);
      
      for(i=0;i<count;i++)
      {
        printf("[%ld; %ld]\n", coord[i].x, coords[i].y);
      }
      
      getchar();
      return 0;
    }



    Auf jeden Fall vielen Dank für die super Hilfe...

    Hab mir mal eine einache kleine .pbm Testdatei angelegt und deinen Code getestet:

    Das ist der letzte Sourcecode den du gepostet hattest:
    gcc ./koordinaten.c -o coordinates
    ./koordinaten.c: In Funktion »main«:
    ./koordinaten.c:49:7: Warnung: Zuweisung erzeugt Zeiger von Ganzzahl ohne Typkonvertierung [standardmäßig aktiviert]
    ./koordinaten.c:52:12: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »calloc« [standardmäßig aktiviert]
    /tmp/ccQoKWym.o: In function `main':
    koordinaten.c:(.text+0x131): undefined reference to `PGMImage_CreateFromFile'
    collect2: ld gab 1 als Ende-Status zurück


    Werd nur zur Zeit nicht nicht schlau aus der Fehlermeldung :/
    Ist etwa die img Deklaration falsch?!
    int main(int argc, char ** argv)
    {
      long i, count;
      coord_t * coords;
      PBMImage img;
      
      img = PGMImage_CreateFromFile("test.pbm");


    LG DeX
  6. Hallo lordcodex,

    dass kommt davon, wenn man ungetesteten Code postet. Mein Fehler.
    Es muss:
    PBMImage_CreateFromFile("test.pbm");
    anstelle von
    PGMImage_CreateFromFile("test.pbm");
    heissen ('B' statt 'G'). Dann sollte es gehen.
  7. Autor dieses Themas

    lordcodex

    Kostenloser Webspace von lordcodex

    lordcodex hat kostenlosen Webspace.

    darkpandemic schrieb:
    Hallo lordcodex,

    dass kommt davon, wenn man ungetesteten Code postet. Mein Fehler.
    Es muss:
    PBMImage_CreateFromFile("test.pbm");
    anstelle von
    PGMImage_CreateFromFile("test.pbm");
    heissen ('B' statt 'G'). Dann sollte es gehen.


    Also die beiden Files sehen nun so aus:
    pbm_image.h
    #ifndef _PBM_IMAGE_H_
    #define _PBM_IMAGE_H_
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    typedef struct pbm_image_
    {
      long width;
      long height;
      unsigned char ** data;
    } pbm_image_t, * PGMImage;
    
    PGMImage PGMImage_Create(long width, long height);
    PGMImage PGMImage_CreateFromFile(const char * path);
    void PGMImage_Free(PGMImage img);
    int PGMImage_Save(PGMImage img, const char * path);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif


    koordinaten.c
    #include <stdio.h>
    #include "pbm_image.h"
    
    typedef struct
    {
      long x;
      long y;
    } coord_t;
    
    long get_coord_count(PGMImage img)
    {
      long x, y, count;
      
      count = 0;
      for(y=0; y<img->height; y++)
      for(x=0; x<img->width; x++)
      {
        if(img->data[y][x])
          count++;
      }
      
      return count;
    }
    
    void get_coords(PGMImage img, coord_t * coords)
    {
      long x, y, idx;
      
      idx = 0;
      
      for(y=0; y<img->height; y++)
      for(x=0; x<img->width; x++)
      {
        if(img->data[y][x])
        {
          coords[idx].x = x;
          coords[idx].y = y;
          idx++;
        }
      }
    }
    
    int main(int argc, char ** argv)
    {
      long i, count;
      coord_t * coords;
      PGMImage img;
      
      img = PGMImage_CreateFromFile("test.pbm");
      
      count = get_coord_count(img);
      coords = calloc(count, sizeof(coord_t));
      get_coords(img, coords);
      
      for(i=0;i<count;i++)
      {
        printf("[%ld; %ld]\n", coords[i].x, coords[i].y);
      }
      
      getchar();
      return 0;
    }


    und wenn ich es compilieren möchte kommt:
    gcc ./koordinaten.c -o coords
    ./koordinaten.c: In Funktion »main«:
    ./koordinaten.c:52:12: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »calloc« [standardmäßig aktiviert]
    /tmp/cc6uyge9.o: In function `main':
    koordinaten.c:(.text+0x12c): undefined reference to `PGMImage_CreateFromFile'
    collect2: ld gab 1 als Ende-Status zurück



    Ich hatte suchen/ersetzen benutzt um den Fehler aus beiden Dateien zu tilgen.

    LG DeX
  8. Hallo lordcodex,

    in den beiden Dateien (pbm_image.h / pbm_image.c) war es ja korrekt. In der main() funktion war es falsch.
    Dabei fällt mir noch auf, dass ich vergessen habe den Speicher wieder freizugeben:
    int main(int argc, char ** argv)
    {
      long i, count;
      coord_t * coords;
      PBMImage img;
      
      img = PBMImage_CreateFromFile("test.pbm");
      
      count = get_coord_count(img);
      coords = calloc(count, sizeof(coord_t));
      get_coords(img, coords);
      
      for(i=0;i<count;i++)
      {
        printf("[%ld; %ld]\n", coord[i].x, coords[i].y);
      }
    
      PBMImage_Free(img);
      free(coords);
    
      getchar();
      return 0;
    }


    Edit: Jetzt sehe ich was Du meinst. Für calloc() muss man noch stdlib.h inkludieren. Dann sollte es gehen.

    Edit2: Du musst desweiteren auch die Datei pbm_image.c mitcompilieren:
    gcc -o coords koordinate.c pbm_image.c


    Beitrag zuletzt geändert: 3.5.2012 21:12:47 von darkpandemic
  9. Autor dieses Themas

    lordcodex

    Kostenloser Webspace von lordcodex

    lordcodex hat kostenlosen Webspace.

    Ok das compilieren hat schon mal geklappt :D YAY

    hab mit GIMP 3 pbm test Dateien gemacht!

    erste: 100*100px mit echten farbwerten (schwarz/weiß)
    zweite: 10*10px mit ascii export
    und dritte: gleiche 10*10 mit echt farbwert wieder schwarzweiß

    x-y-laser$ ./coords 
    Error: PBMImage_CreateFromFile: invalid file header.
    Speicherzugriffsfehler (Speicherabzug geschrieben)
    x-y-laser$ ./coords 
    Error: PBMImage_CreateFromFile: I/O or file error.
    Speicherzugriffsfehler (Speicherabzug geschrieben)
    x-y-laser$ ./coords 
    Error: PBMImage_CreateFromFile: I/O or file error.
    Speicherzugriffsfehler (Speicherabzug geschrieben)


    Entweder is der Dateibuffer zu klein oder ich hab nen Fehler in der Testdatei :/
  10. Hallo lordcodex,

    ich habe gedacht, dass die Einsen und Nullen durch Leerzeichen getrennt sind. Sie sind es aber nicht, weshalb der fscanf() in der Funktion PBMImage_CreateFromFile() beim ersten Pixel die ganze Datei auf einmal liest. Hier ist die korrigierte Fassung:
    PBMImage PBMImage_CreateFromFile(const char * path)
    {
      int c;
      long x, y, width, height;
      PBMImage img;
      FILE * in;
    
      if(!path)
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: path = NULL.\n");
        return NULL;
      }
    
      if(!(in = fopen(path,"rb")))
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: Can't open file.\n");
        return NULL;
      }
    
      c = fgetc(in);
    
      if(c != 'P')
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: invalid file header.\n");
        fclose(in);
        return NULL;
      }
    
      c = fgetc(in);
    
      if(c != '1')
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: invalid file header.\n");
        fclose(in);
        return NULL;
      }
    
      pbm_skip_whitespace(in);
    
      if(fscanf(in,"%ld",&width)!=1)
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: unable to read image width.\n");
        fclose(in);
        return NULL;
      }
    
      if(width < 1)
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: invalid image width.\n");
        fclose(in);
        return NULL;
      }
    
      pbm_skip_whitespace(in);
    
      if(fscanf(in,"%ld",&height)!=1)
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: unable to read image height.\n");
        fclose(in);
        return NULL;
      }
    
      if(height < 1)
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: invalid image height.\n");
        fclose(in);
        return NULL;
      }
    
      if(!(img = PBMImage_Create(width, height)))
      {
        fprintf(stderr, "Error: PBMImage_CreateFromFile: PBMImage_Create() for img failed.\n");
        fclose(in);
        return NULL;
      }
    
      for(y=0;y<height;y++)
      for(x=0;x<width; x++)
      {
        pbm_skip_whitespace(in);
    
    	c = getc(in);
    	if(c == '0')
          img->data[y][x] = 1;
    	else if(c != '1')
        {
          fprintf(stderr, "Error: PBMImage_CreateFromFile: I/O or file error.\n");
          PBMImage_Free(img);
          fclose(in);
          return NULL;
        }
      }
    
      fclose(in);
      return img;
    }
    Einfach in der Datei pbm_image.c austauschen. Diesmal habe ich es auch getestet und es funktioniert ;-)
    Wenn Du die Speicherzugriffsverletzungen vermeiden willst, dann musst Du bei PBMImage_CreateFromFile() (in main()) überprüfen, ob NULL zurückgegeben wird. Z.B. so:
    if(!(img = PBMImage_CreateFromFile("test.pbm")))
    {
      fprintf(stderr, "Error: main: PBMImage_CreateFromFile() failed.\n");
      return 1;
    }
  11. Autor dieses Themas

    lordcodex

    Kostenloser Webspace von lordcodex

    lordcodex hat kostenlosen Webspace.

    darkpandemic schrieb:
    Einfach in der Datei pbm_image.c austauschen. Diesmal habe ich es auch getestet und es funktioniert ;-)
    Wenn Du die Speicherzugriffsverletzungen vermeiden willst, dann musst Du bei PBMImage_CreateFromFile() (in main()) überprüfen, ob NULL zurückgegeben wird. Z.B. so:
    if(!(img = PBMImage_CreateFromFile("test.pbm")))
    {
      fprintf(stderr, "Error: main: PBMImage_CreateFromFile() failed.\n");
      return 1;
    }


    Vielen vielen Dank für die super Lösung von dir.
    Und das beste dabei ^^ ich hab wieder was gelernt *g*

    ps: hoffe kann mich mal revangieren ;)

    LG DeX
  12. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!