Nadesłany przez Tomasz Lubiński, 23 września 2007 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
Kody Kreskowe - C++/Unit1.cpp:
//--------------------------------------------------------------------------- // Generowanie kodow kreskowych ITF-14 // www.algorytm.org // (c)2007 Tomasz Lubinski //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" char codeI25sign[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; char codeI25bars[10][5] = { {'N', 'N', 'W', 'W', 'N'}, {'W', 'N', 'N', 'N', 'W'}, {'N', 'W', 'N', 'N', 'W'}, {'W', 'W', 'N', 'N', 'N'}, {'N', 'N', 'W', 'N', 'W'}, {'W', 'N', 'W', 'N', 'N'}, {'N', 'W', 'W', 'N', 'N'}, {'N', 'N', 'N', 'W', 'W'}, {'W', 'N', 'N', 'W', 'N'}, {'N', 'W', 'N', 'W', 'N'} }; char start[4] = { 1, 0, 1, 0 }; char stop[4] = { 1, 1, 0, 1 }; TForm1 *Form1; int curentPos; // returns letter value for check digit int getLetterValue(char ch) { for (int i=0; i<10; i++) if (codeI25sign[i] == ch) return i; return 0; } // return check digit int checkDigit(char *txt) { int sum = 3 * getLetterValue(txt[0]) + 1 * getLetterValue(txt[1]) + 3 * getLetterValue(txt[2]) + 1 * getLetterValue(txt[3]) + 3 * getLetterValue(txt[4]) + 1 * getLetterValue(txt[5]) + 3 * getLetterValue(txt[6]) + 1 * getLetterValue(txt[7]) + 3 * getLetterValue(txt[8]) + 1 * getLetterValue(txt[9]) + 3 * getLetterValue(txt[10]) + 1 * getLetterValue(txt[11]) + 3 * getLetterValue(txt[12]); sum %= 10; sum = 10 - sum; sum %= 10; return sum; } // returns 1 if letter is correct, 0 otherwise int checkLetter(char ch) { for (int i=0; i<10; i++) if (codeI25sign[i] == ch) return 1; return 0; } // reurns 1 if given EAN-14 is correct, 0 otherwise int check(char *txt) { if (strlen(txt) != 14) return 0; for (unsigned int i=0; i<strlen(txt); i++) if (checkLetter(txt[i]) == 0) return 0; if (checkDigit(txt) != getLetterValue(txt[13])) return 0; return 1; } void drawSignBars(char bars[], int count) { Form1->Image1->Canvas->Brush->Color = clBlack; //print bars for (int i=0; i<count; i++) { if (bars[i] == 1) Form1->Image1->Canvas->Rectangle(curentPos + 20, 10, curentPos + 22, 100); curentPos += 2; } } void drawSignBars(char bars[], char spaces[]) { Form1->Image1->Canvas->Brush->Color = clBlack; //print bars for (int i=0; i<5; i++) { if (bars[i] == 'W') // wide bar { Form1->Image1->Canvas->Rectangle(curentPos + 20, 10, curentPos + 24, 100); curentPos += 4; } else // narrow bar { Form1->Image1->Canvas->Rectangle(curentPos + 20, 10, curentPos + 22, 100); curentPos += 2; } if (spaces[i] == 'W') // wide space { curentPos += 4; } else // narrow space { curentPos += 2; } } } void drawBars(char *txt) { int odd, even; curentPos = 0; Form1->Image1->Canvas->Brush->Color = clWhite; Form1->Image1->Canvas->Rectangle(0, 0, 257, 121); //print start character drawSignBars(start, 4); //print characters for (unsigned int i=0; i<strlen(txt); i+=2) { odd = getLetterValue(txt[i]); even = getLetterValue(txt[i+1]); drawSignBars(codeI25bars[odd], codeI25bars[even]); } //print stop character drawSignBars(stop, 4); //Draw text Form1->Image1->Canvas->Font->Size = 10; Form1->Image1->Canvas->Brush->Color = clWhite; Form1->Image1->Canvas->Font->Color = clBlack; Form1->Image1->Canvas->TextOut(curentPos/2 + 20 - strlen(txt)*3, 100, txt); } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { if (check(Kod->Text.c_str()) == 0) { ShowMessage("Incorrect text"); return; } drawBars(Kod->Text.c_str()); } //---------------------------------------------------------------------------