تبدیل اعداد به متن فارسی در سی شارپ

سلام

همانطور که در پست قبل گفته بودم در این پست قصد دارم روش استفاده از کد تبدیل اعداد به متن را در زبان های سطح بالا با یک مثال بیان کنم.

برای اینکار بهترین روشی که به ذهنم رسید ساخت یک Library و استفاده از آن در یک زبان دیگر بود.

چون به نظرم کاربرد سیستم عامل ویندوز و همینطور دات نت بیشتر از بقیه است کتابخانه DLL و برای زبان برنامه نویسی زبان سی شارپ تحت دات نت را به عنوان مثال انتخاب نمودم. ولی شما میتوانید خودتان این تبدیل را به هر Library دلخواه (مثلا .a تحت لینوکس) و استفاده از آن را با هر زبان دیگر انجام دهید.

برای ارتباط بین Library ساخته شده و زبان سطح بالای مورد نظر به یک پروتکل ساده نیاز داریم. برای این منظور تغییراتی را در برنامه اعمال کردم. به این ترتیب که از این پس در Library به جای چاپ حروف فینگلیش کدی در یک بافر ذخیره میکنیم. زبان سطح بالا با خواندن این بافر متوجه نتیجه خروجی خواهد شد و متن مورد نظر خود را به صورت دلخواه نشان خواهد داد. برای جداسازی کدها هم از کاراکتر کاما استفاده نمودم.

 کد مربوط به نمادهای فارسی اعداد به صورت زیر میباشد:

#define		YEK             1
#define		DO              2
#define		SE              3
#define		CHHAR           4
#define		PANJ            5
#define		SHESH           6
#define		HAFT            7
#define		HASHT           8
#define		NOH             9
#define		DAH             10
#define		YAZDAH          11
#define		DAVAZDAH        12
#define		SIZDAH          13
#define		CHHARDAH        14
#define		PAANZDAH        15
#define		SHAANZDAH       16
#define		HEFDAH          17
#define		HEJDAH          18
#define		NUZDAH          19
#define		BIST            20
#define		SI              21
#define		CHEHEL          22
#define		PANJAH          23
#define		SHAST           24
#define		HAFTAAD         25
#define		HASHTAAD        26
#define		NAVAD           27
#define		SAD             28
#define		DEVIST          29
#define		SISAD           30
#define		CHAHARSAD       31
#define		PAANSAD         32
#define		SHESHSAD        33
#define		HAFTSAD         34
#define		HASHTSAD        35
#define		NOHSAD          36
#define		HEZARHA         37
#define		MILIYUNHA       38
#define		MILIYARDHA      39
#define		BIILIUNHA       40
#define		BILIYAARDHA     41
#define		TIRILIUNHA      42
#define		TIRILIYAARDHA   43
#define		KUADIRILIUNHA   44
#define		KADIRILIYARD    45
#define		KUINTILIUNHA    46
#define		KUAANTINIYARD   47
#define		SECSTILIUNHA    48
#define		SECSTILIYARDHA  49
#define		SEPTILIUNHA     50
#define		SEPTILIYARDHA   51
#define		ACTILIUNHA      52
#define		ACTILIYAARDHA   53
#define		NANILIUNHA      54
#define		NANILIYAARDHA   55
#define		DESILIYUNHA     56
#define		DESILIYAARD     57
#define		GOOGOOL         58
#define		NODEFINE        59
#define		SPACE           60
#define		SEPERATOR       61

 

برای نامگذاری اعداد بزرگ از این مرجع استفاده نمودم. اگر میخواهید مرجع خود را تغییر دهید یا به اعداد بزرگتری نیاز دارید (!!) میتوانید جداول بالا را که در فایل fingilishIndexes.h است و همچنین آرایه معادل با آن را در برنامه سی شارپ که با نام constantNumbersStrings ذخیره شده است را مطابق میل خود تغییر داده و دوباره کامپایل کنید.

کد تغییر یافته پست قبلی (کد DLL) مورد نظر به صورت زیر میباشد:

/*
============================================================================
Name        : digitToPersianSentence.c
Author      : Mohsen Rashidi, Codeblog.ir
Version     : 1.0.0
Copyright   : free
Description : convert digits to persian sentences
============================================================================
*/

/*  --------------------< Include headers >--------------------------*/

// ----<  compiler Headers:
#include "stdafx.h"

// ----<  Ansi Headers:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

// ----<  Our Headers:
#include "./include/fingilishIndexes.h"

/*  ------------------------------------------------------------------*/

/*  --------------------< Macro Definition >--------------------------*/

#define _TRUE			(char)0
#define _FALSE			(char)-1
#define DECIMAL 		۰
#define CENTESIMAL		۱

/*  ------------------------------------------------------------------*/

/*  --------------------< Type Definition >--------------------------*/

typedef int short		int16;
typedef unsigned int 	uint;
typedef char 			boolean;

/*  ------------------------------------------------------------------*/

char outputStr[1000] = {0};
char outputCode[1000] = {0};

boolean strIsDigit(const char* str){

	int i = 0;

	if(!str)
		return _FALSE;
	for( i = 0 ; str[i] ; i++){
		if(!isdigit(str[i]))
			return _FALSE;
	}
	return _TRUE;

}

void digitGroup(char* str, char* output){
	int x = strlen(str);
	strcpy(output, str);
	while( (x-=3) > 0 ){
		memmove(output + x + 1, output + x, strlen(output) - x + 1);
		output[x] = ',';
	}
}

char* deleteZero(const char *inputStr){
	int i = 0;

	if(!(*inputStr))
		return NULL;

	char* result = NULL;
	while (*(result = ((char*)inputStr + i++)) == '0');

	if(!(*result))
		return result - 1;

	return result;
}

int16 checkFormatValidity(const char* str){
	if(strIsDigit(str) != _TRUE)
		return _FALSE;
	return _TRUE;
}

char* editFormat(const char* str){
	return deleteZero(str);
}

int getStairCode(const uint stair){

	switch(stair){

	case 1:
		return NULL;
	case 2:
		return HEZARHA;
		break;
	case 3:
		return MILIYUNHA;
		break;
	case 4:
		return MILIYARDHA;
		break;
	case 5:
		return BIILIUNHA;
		break;
	case 6:
		return BILIYAARDHA;
		break;
	case 7:
		return TIRILIUNHA;
		break;
	case 8:
		return TIRILIYAARDHA;
		break;
	case 9:
		return KUADIRILIUNHA;
		break;
	case 10:
		return KADIRILIYARD;
		break;
	case 11:
		return KUINTILIUNHA;
		break;
	case 12:
		return KUAANTINIYARD;
		break;
	case 13:
		return SECSTILIUNHA;
		break;
	case 14:
		return SECSTILIYARDHA;
		break;
	case 15:
		return SEPTILIUNHA;
		break;
	case 16:
		return SEPTILIYARDHA;
		break;
	case 17:
		return ACTILIUNHA;
		break;
	case 18:
		return ACTILIYAARDHA;
		break;
	case 19:
		return NANILIUNHA;
		break;
	case 20:
		return NANILIYAARDHA;
		break;
	case 21:
		return DESILIYUNHA;
		break;
	case 22:
		return DESILIYAARD;
		break;
	case 23:
		return GOOGOOL;
		break;

	default:
		return NODEFINE;
		break;
	}
	return NULL;
}

int output(int code){

	char ch[5];
	sprintf(ch, "%d", code);

	if( strlen(outputCode) != 0 )
		strcat(outputCode, ",");

	strcat(outputCode, ch);

	return 0;
}

int decimal_OR_Centesimal (char ch, int stair){

	int buffStr;

	switch(ch){
	case '1':
		buffStr = (stair == CENTESIMAL) ? SAD : NULL;
		break;
	case '2':
		buffStr = (stair == DECIMAL) ? BIST : DEVIST;
		break;
	case '3':
		buffStr = (stair == DECIMAL) ?  SI :  SISAD;
		break;
	case '4':
		buffStr = (stair == DECIMAL) ?  CHEHEL :  CHAHARSAD;
		break;
	case '5':
		buffStr = (stair == DECIMAL) ?  PANJAH :  PAANSAD;
		break;
	case '6':
		buffStr = (stair == DECIMAL) ?  SHAST :  SHESHSAD;
		break;
	case '7':
		buffStr = (stair == DECIMAL) ?  HAFTAAD :  HAFTSAD;
		break;
	case '8':
		buffStr = (stair == DECIMAL) ?  HASHTAAD :  HASHTSAD;
		break;
	case '9':
		buffStr = (stair == DECIMAL) ?  NAVAD :  NOHSAD;
		break;
	default:
		break;
	}

	return buffStr;
}

void printTriliteral(char* theTriliteralStr){

	int digit = atoi(theTriliteralStr);
	int temp;
	char* triliteralStr;

	triliteralStr = deleteZero(theTriliteralStr);

	if( digit <= 20 )
		output(digit);

	else if( (digit < 100) && (digit > 20) ){

		output( decimal_OR_Centesimal(triliteralStr[0], DECIMAL) );

		if( digit%10 != 0){
			output( SEPERATOR);
			output( digit%10 );
		}
	}

	else{ //  1000 > digit >= 100
		output( decimal_OR_Centesimal(triliteralStr[0], CENTESIMAL) );
		temp = atoi(&triliteralStr[1]);

		if( temp > 0 ){

			if( temp <= 20 ){
				output( SEPERATOR);
				output(digit%100);
			}
			else {
				output( SEPERATOR);
				output( decimal_OR_Centesimal(triliteralStr[1], DECIMAL) );
				if(triliteralStr[2] != '0'){
					output( SEPERATOR);
					output( digit%10 );
				}
			}
		}
	}
}

extern "C"
{
	__declspec(dllexport) int grouped(char* str, char* output){
		int x = strlen(str);
		strcpy(output, str);
		while( (x-=3) > 0 ){
			memmove(output + x + 1, output + x, strlen(output) - x + 1);
			output[x] = ',';
		}
		return 0;
	}
}

extern "C"
{
	__declspec(dllexport) int convertToPersianSentence(char* strDigit, char* out){

		uint stage = 0;
		uint stair = 0;
		uint digitStrLen = 0;
		char triliteralBuf[3+1] = {0};
		char* editedStrDigit;
		int temp = 0;
		char digitStr[200] = {0};
		memset( outputCode, 0, sizeof(outputCode));
		strcpy(digitStr, strDigit);
		if( checkFormatValidity(digitStr) != _TRUE )
			return 0;

		editedStrDigit = editFormat(digitStr);

		digitStrLen = strlen(editedStrDigit);

		if( digitStrLen == 0 )
			return 0;

		stage = ( (digitStrLen % 3) == 0 ) ? 3 : (digitStrLen % 3);
		stair = ceil( (float)digitStrLen / 3.f );

		strncpy(triliteralBuf, editedStrDigit, stage);

		printTriliteral(triliteralBuf);

		temp = getStairCode(stair--);

		if(temp){
			output(SPACE);
			output( temp );
		}

		while( stage < digitStrLen ) {
			strncpy(triliteralBuf, editedStrDigit + stage , 3);
			if( atoi(triliteralBuf) > 0 ){
				output( SEPERATOR );
				printTriliteral(triliteralBuf);
				temp = getStairCode(stair);
				if(temp){
					output( SPACE );
					output( temp );
				}
			}
			stage += 3;
			stair--;
		}

		strcpy(out,outputCode);
		return 0;
	}
}

 

در کد بالا خطوط هایلایت شده برای برقراری ارتباط با کد زبان دیگر تعریف شده اند.

برای روشن تر شدن بهتر موضوع روال زیر را در نظر بگیرید:

  • در زبان سطح بالا کاربر مقدار ۱۲۳ را وارد میکند.
  • برنامه این مقدار را به صورت رشته به متد convertToPersianSentence موجود در Library ارسال میکند.
  • Library کد خروجی را تولید کرده و در پارامتر خروجی (out) ذخیره میکند.
  • برنامه سطح بالا مقدار خروجی را که برای مثال بالا مقدار “۲۸,۶۱,۲۰,۶۱,۳” است خوانده و با استفاده متد createFarsiFromCodes کد را به متن فارسی معادل آن تبدیل میکند.

در رشته بالا

۲۸ معادل “صد”

۶۱ معادل جدا کننده یا همان کاراکتر “و”

۲۰ معادل “بیست”

و ۳ معادل “سه” میباشد.

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;     // DLL support

namespace useFromdllInCsharp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [StructLayout(LayoutKind.Sequential)]

        public class INNER
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 400)]

            public string field1 = "Test";
        }

        [StructLayout(LayoutKind.Sequential)]

        public struct OUTER
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 400)]

            public string field1;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40000)]

            public byte[] inner;
        }

        [DllImport(@"dllTest.dll")]
        public static extern void convertToPersianSentence(string x, ref OUTER po);

        [DllImport(@"dllTest.dll")]
        public static extern void grouped(string x2, ref OUTER po2);

        string[] constantNumbersStrings ={

		"صفر"			, // ۰
 		"یک"			, // ۱
 		"دو"			, // ۲
 		"سه"			, // ۳
 		"چهار"			, // ۴
 		"پنج"			, // ۵
 		"شش"			, // ۶
 		"هفت"			, // ۷
 		"هشت"			, // ۸
 		"نه"			, // ۹
 		"ده"			, // ۱۰
 		"یازده"		    , // ۱۱
 		"دوازده"		, // ۱۲
 		"سیزده"		    , // ۱۳
 		"چهارده"		, // ۱۴
 		"پانزده"		, // ۱۵
 		"شانزده"		, // ۱۶
 		"هفده"		    , // ۱۷
 		"هجده"		    , // ۱۸
 		"نوزده"		    , // ۱۹
 		"بیست"			, // ۲۰
 		"سی"			, // ۲۱ ۳۰
 		"چهل"	    	, // ۲۲ ۴۰
 		"پنجاه"		    , // ۲۳ ۵۰
 		"شصت"			, // ۲۴ ۶۰
 		"هفتاد"		    , // ۲۵ ۷۰
 		"هشتاد"		    , // ۲۶ ۸۰
 		"نود"			, // ۲۷
 		"صد"			, // ۲۸ ۱۰۰
 		"دویست"		    , // ۲۹ ۲۰۰
 		"سیصد"			, // ۳۰ ۳۰۰
 		"چهارصد"		, // ۳۱ ۴۰۰
 		"پانصد"		    , // ۳۲ ۵۰۰
 		"ششصد"		    , // ۳۳ ۶۰۰
 		"هفتصد"		    , // ۳۴ ۷۰۰
 		"هشتصد"		    , // ۳۵ ۸۰۰
 		"نهصد"		    , // ۳۶ ۹۰۰
 		"هزار"			, // ۳۷ ۱,۰۰۰
 		"میلیون"		, // ۳۸ ۱,۰۰۰,۰۰۰
 		"میلیارد"		, // ۳۹ ۱,۰۰۰,۰۰۰,۰۰۰
 		"بیلیون"		, // ۴۰ ۱,۰۰۰,۰۰۰,۰۰۰,۰۰۰
 		"بیلیارد"		, // ۴۱ ۱,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰
        "تریلیون"		, // ۴۲ ۱,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰
 		"تریلیارد"  	, // ۴۳ ۱,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰
 		"کوآدریلیون"	, // ۴۴
		"کادریلیارد"	, // ۴۵
		"کوینتیلیون"	, // ۴۶
		"کوانتینیارد"	, // ۴۷
		"سکستیلیون"     , // ۴۸
		"سکستیلیارد"	, // ۴۹
		"سپتیلیون"		, // ۵۰
		"سپتیلیارد" 	, // ۵۱
		"اکتیلیون"	    , // ۵۲
		"اکتیلیارد"	    , // ۵۳
		"نانیلیون"	    , // ۵۴
		"نانیلیارد" 	, // ۵۵
		"دسیلیون"	    , // ۵۶
		"دسیلیارد"		, // ۵۷
		"گوگول"	        , // ۵۸

		"NODEFINE"		, // ۵۹
         " "            , // ۶۰
        " و "           , // ۶۱

        };

        private void createFarsiFromCodes(string[] codes)
        {
            int i = 0;
            string farsiStr = "";
            while (i < codes.Length)
            {
                farsiStr += constantNumbersStrings[System.Convert.ToInt64(codes[i])];
                farsiStr += " ";
                i++;
            }
            persianSentenceTextBox.Text = farsiStr;

        }

        private void convertButton_Click(object sender, EventArgs e)
        {
            OUTER ed = new OUTER();
            OUTER ed2 = new OUTER();

            INNER[] inn = new INNER[200];

            INNER test = new INNER();

            int iStructSize = Marshal.SizeOf(test);

            int sz = inn.Length * iStructSize;

            ed.inner = new byte[sz];
            ed2.inner = new byte[sz];

            string digitStr = digitTextBox.Text;

            if(digitStr.Length != 0){
                stringLengthLabel.Text = digitStr.Length.ToString() + " رقم";
                grouped(digitStr, ref ed2);
                groupedTextBox.Text = ed2.field1.ToString();
                convertToPersianSentence(digitStr, ref ed);
                string farsiDigitCode = ed.field1.ToString();
                string[] codes;
                codes = farsiDigitCode.Split(',');
                createFarsiFromCodes(codes);

            }
        }
    }
}

 

دانلود کامل پروژه سی شارپ در محیط Visual Studio 2008

 

تصاویری از اجرای برنامه برای چند عدد نمونه:

 

2014-03-30_153117

 

2014-03-30_153255

 

2014-03-30_153550

 

و در آخر چاپ عدد معروف گوگل 🙂

2014-03-30_154541

 

به امید دیدار مجدد.

برنامه‌نویس ++‏C/C‏ - برنامه‌نویس سیستم‌های گرافیکی با استفاده از کتابخانه ‏OpenGL - برنامه‌نویس #‏C و ..‏

3 thoughts on “تبدیل اعداد به متن فارسی در سی شارپ

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

هجده − شانزده =

Back To Top