সি-তে কনসোল থেকে একটি লাইন কীভাবে পড়বেন?


108

সি কনসোল প্রোগ্রামে সম্পূর্ণ লাইনটি পড়ার সহজ উপায়টি কী কী প্রবেশ করানো হয়েছে তার পাঠ্যটির দৈর্ঘ্য দৈর্ঘ্য হতে পারে এবং আমরা এর বিষয়বস্তু সম্পর্কে কোনও ধারণা নিতে পারি না।


আপনি কি স্পষ্ট করে বলতে পারেন? @ টিম নীচে যেমন বলেছে, এটি আপনি যা চাইছেন তা বিভ্রান্ত করছে :)
ওয়ারেন

উত্তর:


81

আপনার ডায়নামিক মেমরি পরিচালনা দরকার এবং fgetsআপনার লাইনটি পড়তে ফাংশনটি ব্যবহার করুন । তবে এটি কত অক্ষর পড়ে তা দেখার কোনও উপায় নেই বলে মনে হয়। সুতরাং আপনি fgetc ব্যবহার:

char * getline(void) {
    char * line = malloc(100), * linep = line;
    size_t lenmax = 100, len = lenmax;
    int c;

    if(line == NULL)
        return NULL;

    for(;;) {
        c = fgetc(stdin);
        if(c == EOF)
            break;

        if(--len == 0) {
            len = lenmax;
            char * linen = realloc(linep, lenmax *= 2);

            if(linen == NULL) {
                free(linep);
                return NULL;
            }
            line = linen + (line - linep);
            linep = linen;
        }

        if((*line++ = c) == '\n')
            break;
    }
    *line = '\0';
    return linep;
}

দ্রষ্টব্য : ব্যবহার কখনও পায় না! এটি সীমানা যাচাই করে না এবং আপনার বাফারকে উপচে ফেলতে পারে


গুহাত - সেখানে পুনর্বিবেচনার ফলাফল পরীক্ষা করা দরকার। তবে যদি এটি ব্যর্থ হয়, তবে আরও খারাপ সমস্যাগুলি সম্ভবত রয়েছে।
টিম

4
আপনি সম্ভবত বাফারের সাহায্যে fgets করে দক্ষতাটি কিছুটা বাড়িয়ে দিতে পারেন এবং শেষে আপনার নিউলাইন চরিত্র আছে কিনা তা পরীক্ষা করে। যদি আপনি এটি না করেন তবে আপনার সংগ্রহের বাফারটি পুনরায় চালু করুন, এতে অনুলিপি করুন এবং আবার কল্পনা করুন।
পল টমলিন

3
এই ফাংশনটির একটি সংশোধন দরকার: "লেন = লেমনেক্স" রেখাটি; রিলোকটির পরে হয় পুনর্বিবেচনার পূর্বে বা "লেন = লেনম্যাক্স >> 1;" হওয়া উচিত - বা অন্য কোনও সমতুল্য যেটির অর্ধেক দৈর্ঘ্য ইতিমধ্যে ব্যবহৃত হয়েছে for
ম্যাট গ্যালাগার

1
@ জোহানেস, আপনার প্রশ্নের জবাবে, @ পলের পদ্ধতির বেশিরভাগ (যেমন পুনরায় অনুশীলনকারী) এলবিসি বাস্তবায়নের ক্ষেত্রে দ্রুত হওয়া উচিত, যেহেতু আপনার পদ্ধতিটি প্রতিটি চরিত্রের জন্য স্পষ্টতই স্টিডিনকে লক করে রাখে যেখানে তার বাফার প্রতি একবার এটি লক করে। fgetc_unlockedথ্রেড সুরক্ষা যদি উদ্বেগের বিষয় না হয় তবে পারফরম্যান্স হয় তবে আপনি কম পোর্টেবল ব্যবহার করতে পারেন ।
ভ্লাদর

3
মনে রাখবেন যে getline()এটি পসিক্স স্ট্যান্ডার্ড getline()ফাংশন থেকে পৃথক ।
জোনাথন লেফলার

28

আপনি যদি জিএনইউ সি লাইব্রেরি বা অন্য কোনও পসিক্স-কমপ্লায়েন্ট লাইব্রেরি ব্যবহার করছেন তবে আপনি ফাইল স্ট্রিমের জন্য এটি ব্যবহার করতে getline()এবং stdinএটিতে যেতে পারেন ।


16

স্থির বরাদ্দের জন্য লাইন পড়ার জন্য একটি খুব সাধারণ তবে অনিরাপদ বাস্তবায়ন:

char line[1024];

scanf("%[^\n]", line);

বাফার ওভারফ্লো হওয়ার সম্ভাবনা ছাড়াই একটি নিরাপদ বাস্তবায়ন, তবে পুরো লাইনটি না পড়ার সম্ভাবনা সহ, হ'ল:

char line[1024];

scanf("%1023[^\n]", line);

ভেরিয়েবল ঘোষণা করে নির্দিষ্ট দৈর্ঘ্যের এবং বিন্যাসের স্ট্রিংয়ে উল্লিখিত দৈর্ঘ্যের মধ্যে 'একের ব্যবধানে' নয়। এটি একটি historicalতিহাসিক নিদর্শন।


14
এটি মোটেই নিরাপদ নয়। এটি পুরোপুরি একই সমস্যা থেকে ভুগছে কেন getsপুরোপুরি মান থেকে সরানো হয়েছিল
আন্তি হাপালা

6
মডারেটর দ্রষ্টব্য: উপরের মন্তব্যটি উত্তরের পূর্ববর্তী সংশোধনকে
রবার্ট হার্ভে

13

সুতরাং, আপনি যদি আদেশের তর্কগুলি সন্ধান করেন তবে টিমের উত্তরটি একবার দেখুন। আপনি যদি কেবল কনসোল থেকে একটি লাইন পড়তে চান:

#include <stdio.h>

int main()
{
  char string [256];
  printf ("Insert your full address: ");
  gets (string);
  printf ("Your address is: %s\n",string);
  return 0;
}

হ্যাঁ, এটি সুরক্ষিত নয়, আপনি বাফারকে ছাড়িয়ে যেতে পারেন, এটি ফাইলের শেষের জন্য যাচাই করে না, এটি এনকোডিংগুলি এবং প্রচুর অন্যান্য সামগ্রী সমর্থন করে না। বাস্তবে আমি ভাবিনিও যে এটি এই স্টাফগুলির কোনও কাজ করে কিনা। আমি সম্মত হই যে আমি কৃপা করলাম :) তবে ... যখন আমি "সি-তে কনসোল থেকে একটি লাইন কীভাবে পড়ব?" এর মতো একটি প্রশ্ন দেখি তখন আমি ধরেই নিয়েছি যে কোনও ব্যক্তির জন্য সহজ সরল কিছু দরকার, যেমন গেটস () এবং 100 টি কোডের কোড নয় উপরের মত আসলে, আমি মনে করি, আপনি যদি এই 100 টি কোড লাইনের বাস্তবে লেখার চেষ্টা করেন তবে আপনি যা করেছেন তা বেছে নেওয়ার চেয়ে আপনি আরও অনেক ভুল করতে পারবেন;)


1
এটি দীর্ঘ স্ট্রিংয়ের জন্য অনুমতি দেয় না ... - যা আমি মনে করি তার প্রশ্নের সূত্রপাত।
টিম

2
-1, পায় () ব্যবহার করা উচিত নয় যেহেতু এটি সীমানা পরীক্ষা করে না।
বিনোদন

7
অন্যদিকে আপনি যদি নিজের জন্য একটি প্রোগ্রাম লিখছেন এবং কেবল একটি ইনপুট পড়ার প্রয়োজন এটি একেবারে ঠিক। কোনও প্রোগ্রামের কতটুকু সুরক্ষা দরকার তা অনুমানের সমান every আপনি এটিকে প্রতিবার অগ্রাধিকার হিসাবে রাখতে চান না।
মার্টিন Beckett

4
@ টিম - আমি সমস্ত ইতিহাস বজায় রাখতে চাই :)
পল কাপুস্টিন

4
Downvoted। getsআর বিদ্যমান নেই, সুতরাং এটি সি 11 এ কাজ করে না।
আন্তি হাপালা

11

আপনার কোনও বাফার ওভারফ্লো নেই এবং ইনপুটটি কেটে যাবে না তা নিশ্চিত করতে আপনার অক্ষর দ্বারা একটি অক্ষর (getc ()) লুপ ব্যবহার করতে হতে পারে।


9

getline চলমান উদাহরণ

এই উত্তরে উল্লিখিত তবে এখানে একটি উদাহরণ রয়েছে।

এটি পজিক্স is , আমাদের জন্য মেমরি বরাদ্দ করে এবং একটি লুপে বরাদ্দ করা বাফারটিকে সুন্দরভাবে পুনরায় ব্যবহার করে।

পয়েন্টার newbs, এটি পড়ুন: কেন getline প্রথম পয়েন্টার পয়েন্টার পয়েন্টার "চর **" পরিবর্তে "চর *"?

#define _XOPEN_SOURCE 700

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char *line = NULL;
    size_t len = 0;
    ssize_t read = 0;
    while (read != -1) {
        puts("enter a line");
        read = getline(&line, &len, stdin);
        printf("line = %s", line);
        printf("line length = %zu\n", read);
        puts("");
    }
    free(line);
    return 0;
}

glibc বাস্তবায়ন

পসিক্স নেই? হতে পারে আপনি glibc 2.23 বাস্তবায়নটি দেখতে চান

এটি সমাধান করে getdelim, যা getlineএকটি স্বেচ্ছাসেবী লাইন টার্মিনেটর সহ একটি সাধারণ পসিক্স সুপারস্টেট ।

এটি যখনই বৃদ্ধি প্রয়োজন তখন বরাদ্দ করা মেমরি দ্বিগুণ করে এবং থ্রেড-নিরাপদ দেখায়।

এটিতে কিছু ম্যাক্রো সম্প্রসারণ প্রয়োজন, তবে আপনি আরও ভাল করার সম্ভাবনা কম।


lenএখানে উদ্দেশ্য কী , যখন পড়ার
আব্দুল

@ আবদুল দেখুন man getlinelenবিদ্যমান বাফার দৈর্ঘ্য, 0যাদু এবং এটি বরাদ্দ করতে বলে। পড়ার নাম পড়ার সংখ্যা। বাফার আকার এর চেয়ে বড় হতে পারে read
সিরো সান্তিলি :40 冠状 病 六四 事件

6

আমার মতো অনেকেই এই পোস্টে শিরোনামটির সাথে কী অনুসন্ধান করা হয় তার সাথে মিল আসে, যদিও বর্ণনাটি পরিবর্তনশীল দৈর্ঘ্যের বিষয়ে বলছে। বেশিরভাগ ক্ষেত্রে, আমরা দৈর্ঘ্য আগেই জানি।

আপনি যদি হাতের আগে দৈর্ঘ্য জানেন তবে নীচে চেষ্টা করুন:

char str1[1001] = { 0 };
fgets(str1, 1001, stdin); // 1000 chars may be read

উত্স: https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm


5

প্রস্তাবিত হিসাবে, আপনি নিজের বাফার তৈরি করে কোনও কনসোল থেকে পাঠানোর জন্য getchar () ব্যবহার করতে পারেন an আপনি যদি যুক্তিসঙ্গত সর্বাধিক লাইনের আকার নির্ধারণ করতে না পারেন তবে গতিশীলভাবে বাড়ানো বাফার ঘটতে পারে।

আপনি সি নাল-টার্মিনেটেড স্ট্রিং হিসাবে লাইন পাওয়ার নিরাপদ উপায় হিসাবে fgets ব্যবহার করতে পারেন:

#include <stdio.h>

char line[1024];  /* Generously large value for most situations */

char *eof;

line[0] = '\0'; /* Ensure empty line if no input delivered */
line[sizeof(line)-1] = ~'\0';  /* Ensure no false-null at end of buffer */

eof = fgets(line, sizeof(line), stdin);

আপনি যদি কনসোল ইনপুটটি ক্লান্ত করে ফেলেছেন বা কোনও কারণে যদি অপারেশন ব্যর্থ হয় তবে eof == NULL ফিরে আসে এবং লাইন বাফারটি অপরিবর্তিত হতে পারে (এজন্য প্রথম চরটি '\ 0' এ সেট করা কার্যকর)।

fgets লাইন ওভারফিল করবে না] এবং এটি নিশ্চিত করবে যে সফল ফিরতিতে সর্বশেষ গৃহীত চরিত্রের পরে কোনও শূন্যতা রয়েছে।

যদি শেষ অবধি পৌঁছে যায় তবে '\ 0' এর সমাপ্তির আগে থাকা অক্ষরটি '\ n' হবে।

'\ 0' সমাপ্তির আগে যদি কোনও সমাপ্তি '\ n' না থাকে তবে এটি আরও বেশি ডেটা থাকতে পারে বা পরবর্তী অনুরোধটি ফাইল-এর শেষে রিপোর্ট করবে। কোনটি তা নির্ধারণ করতে আপনাকে আরও একটি কল্পিত কাজ করতে হবে। (এক্ষেত্রে, গেটচার () দিয়ে লুপিং করা সহজ)

উপরের (আপডেট করা) উদাহরণ কোডে, লাইন যদি [আকারের (লাইন) -1] == '\ 0' সফল fgets পরে, আপনি জানেন যে বাফার পুরোপুরি পূর্ণ হয়ে গেছে। যদি সেই অবস্থানটি '\ n' দ্বারা চালিত হয় আপনি জানেন আপনি ভাগ্যবান। অন্যথায়, স্ট্যাডিনে আরও ডেটা বা ফাইলের শেষের ব্যবস্থা রয়েছে। (যখন বাফার পুরোপুরি পূরণ করা হয় না, আপনি তখনও ফাইলের শেষের দিকে থাকতে পারেন এবং বর্তমান লাইনের শেষে '\ n' নাও থাকতে পারে Since যেহেতু আপনাকে স্ট্রিংটি সন্ধান করতে হবে এবং / বা স্ট্রিংটি শেষ হওয়ার আগে যে কোনও '\ n' (বাফারে প্রথম '\ 0') মুছে ফেলুন, আমি গেচচার () প্রথম স্থানে ব্যবহার করতে পছন্দ করি)

প্রথম অংশ হিসাবে আপনি যে পরিমাণ পড়ছেন তার চেয়ে এখনও বেশি লাইন থাকার জন্য আপনাকে যা করার দরকার তা করুন। গতিবেগের সাথে বাফার বৃদ্ধির উদাহরণগুলি গেটচার বা fgets দ্বারা কাজ করার জন্য তৈরি করা যেতে পারে। নজরদারি করার জন্য কিছু জটিল এজ রয়েছে (যেমন পরবর্তী ইনপুটটি '\ 0' অবস্থানে স্টোরেজ শুরু করার কথা মনে করে যা বাফার বাড়ানোর আগে পূর্ববর্তী ইনপুটটি শেষ করে))


2

সি-তে কনসোল থেকে একটি লাইন কীভাবে পড়বেন?

  • আপনার নিজস্ব ফাংশন তৈরি করা, কনসোল থেকে একটি লাইন পড়া অর্জনে আপনাকে সহায়তা করবে এমন একটি উপায়

  • প্রয়োজনীয় মেমরির প্রয়োজনীয় পরিমাণ বরাদ্দ করতে আমি গতিশীল মেমরি বরাদ্দ ব্যবহার করছি

  • যখন আমরা বরাদ্দ মেমরিটি শেষ করতে চলেছি তখন আমরা মেমরির আকার দ্বিগুণ করার চেষ্টা করি

  • এবং এখানে আমি getchar()ব্যবহারকারীর প্রবেশ '\n'বা EOFঅক্ষর না হওয়া পর্যন্ত ফাংশনটি ব্যবহার করে স্ট্রিংয়ের প্রতিটি অক্ষর একেকটি স্ক্যান করতে একটি লুপ ব্যবহার করছি

  • অবশেষে আমরা লাইনটি ফেরার আগে অতিরিক্ত বরাদ্দ হওয়া কোনও মেমরি সরিয়ে ফেলি

//the function to read lines of variable length

char* scan_line(char *line)
{
    int ch;             // as getchar() returns `int`
    long capacity = 0;  // capacity of the buffer
    long length = 0;    // maintains the length of the string
    char *temp = NULL;  // use additional pointer to perform allocations in order to avoid memory leaks

    while ( ((ch = getchar()) != '\n') && (ch != EOF) )
    {
        if((length + 1) >= capacity)
        {
            // resetting capacity
            if (capacity == 0)
                capacity = 2; // some initial fixed length 
            else
                capacity *= 2; // double the size

            // try reallocating the memory
            if( (temp = realloc(line, capacity * sizeof(char))) == NULL ) //allocating memory
            {
                printf("ERROR: unsuccessful allocation");
                // return line; or you can exit
                exit(1);
            }

            line = temp;
        }

        line[length] = (char) ch; //type casting `int` to `char`
    }
    line[length + 1] = '\0'; //inserting null character at the end

    // remove additionally allocated memory
    if( (temp = realloc(line, (length + 1) * sizeof(char))) == NULL )
    {
        printf("ERROR: unsuccessful allocation");
        // return line; or you can exit
        exit(1);
    }

    line = temp;
    return line;
}
  • এখন আপনি এইভাবে একটি সম্পূর্ণ লাইন পড়তে পারেন:

    char *line = NULL;
    line = scan_line(line);

ফাংশনটি ব্যবহার করে এখানে একটি উদাহরণ প্রোগ্রাম রয়েছেscan_line() :

#include <stdio.h>
#include <stdlib.h> //for dynamic allocation functions

char* scan_line(char *line)
{
    ..........
}

int main(void)
{
    char *a = NULL;

    a = scan_line(a); //function call to scan the line

    printf("%s\n",a); //printing the scanned line

    free(a); //don't forget to free the malloc'd pointer
}

নমুনা ইনপুট:

Twinkle Twinkle little star.... in the sky!

নমুনা আউটপুট:

Twinkle Twinkle little star.... in the sky!

0

কিছুক্ষণ আগে আমি একই সমস্যাটি পেরিয়ে এসেছি, এটি ছিল আমার একাকীকরণ, আশা করি এটি সাহায্য করবে।

/*
 * Initial size of the read buffer
 */
#define DEFAULT_BUFFER 1024

/*
 * Standard boolean type definition
 */
typedef enum{ false = 0, true = 1 }bool;

/*
 * Flags errors in pointer returning functions
 */
bool has_err = false;

/*
 * Reads the next line of text from file and returns it.
 * The line must be free()d afterwards.
 *
 * This function will segfault on binary data.
 */
char *readLine(FILE *file){
    char *buffer   = NULL;
    char *tmp_buf  = NULL;
    bool line_read = false;
    int  iteration = 0;
    int  offset    = 0;

    if(file == NULL){
        fprintf(stderr, "readLine: NULL file pointer passed!\n");
        has_err = true;

        return NULL;
    }

    while(!line_read){
        if((tmp_buf = malloc(DEFAULT_BUFFER)) == NULL){
            fprintf(stderr, "readLine: Unable to allocate temporary buffer!\n");
            if(buffer != NULL)
                free(buffer);
            has_err = true;

            return NULL;
        }

        if(fgets(tmp_buf, DEFAULT_BUFFER, file) == NULL){
            free(tmp_buf);

            break;
        }

        if(tmp_buf[strlen(tmp_buf) - 1] == '\n') /* we have an end of line */
            line_read = true;

        offset = DEFAULT_BUFFER * (iteration + 1);

        if((buffer = realloc(buffer, offset)) == NULL){
            fprintf(stderr, "readLine: Unable to reallocate buffer!\n");
            free(tmp_buf);
            has_err = true;

            return NULL;
        }

        offset = DEFAULT_BUFFER * iteration - iteration;

        if(memcpy(buffer + offset, tmp_buf, DEFAULT_BUFFER) == NULL){
            fprintf(stderr, "readLine: Cannot copy to buffer\n");
            free(tmp_buf);
            if(buffer != NULL)
                free(buffer);
            has_err = true;

            return NULL;
        }

        free(tmp_buf);
        iteration++;
    }

    return buffer;
}

1
আপনি যদি gotoত্রুটি কেস পরিচালনা করতে ব্যবহার করেন তবে আপনার কোডটি অনেক সহজ হয়ে উঠবে । তবুও, আপনি কি ভাবেন না যে লুপটিতে একই মাপের সাথে বার বার এটির tmp_bufপরিবর্তে আপনি পুনরায় ব্যবহার করতে পারেন malloc?
শাহবাজ

has_errত্রুটিগুলি প্রতিবেদন করার জন্য একটি একক গ্লোবাল ভেরিয়েবল ব্যবহার এই ফাংশনটিকে থ্রেড-অনিরাপদ এবং ব্যবহার করা কম আরামদায়ক করে তোলে। সেভাবে করবেন না। আপনি ইতিমধ্যে NULL ফিরিয়ে একটি ত্রুটি নির্দেশ করেছেন। এমন ভাবারও অবকাশ রয়েছে যে সাধারণ-উদ্দেশ্যে লাইব্রেরি ফাংশনে মুদ্রিত ত্রুটি বার্তাগুলি ভাল ধারণা নয়।
জোনাথন লেফলার

0

বিএসডি সিস্টেম এবং অ্যান্ড্রয়েডে আপনি এটি ব্যবহার করতে পারেন fgetln:

#include <stdio.h>

char *
fgetln(FILE *stream, size_t *len);

তাই ভালো:

size_t line_len;
const char *line = fgetln(stdin, &line_len);

lineনাল সমাপ্ত হয় না এবং ধারণ করে \nশেষ (অথবা যাই হোক না কেন আপনার প্ল্যাটফর্মে ব্যবহার করছে)। স্ট্রিমের পরবর্তী আই / ও অপারেশনের পরে এটি অবৈধ হয়ে যায়।


হ্যাঁ, ফাংশন বিদ্যমান। এটি যে নাল-টার্মিনেটেড স্ট্রিং সরবরাহ করে না তা যথেষ্ট পরিমাণে বড় এবং সমস্যাযুক্ত যে এটি ব্যবহার না করা সম্ভবত এটি ভাল it's এটি বিপজ্জনক।
জোনাথন লেফলার

0

এটার মতো কিছু:

unsigned int getConsoleInput(char **pStrBfr) //pass in pointer to char pointer, returns size of buffer
{
    char * strbfr;
    int c;
    unsigned int i;
    i = 0;
    strbfr = (char*)malloc(sizeof(char));
    if(strbfr==NULL) goto error;
    while( (c = getchar()) != '\n' && c != EOF )
    {
        strbfr[i] = (char)c;
        i++;
        strbfr = (void*)realloc((void*)strbfr,sizeof(char)*(i+1));
        //on realloc error, NULL is returned but original buffer is unchanged
        //NOTE: the buffer WILL NOT be NULL terminated since last
        //chracter came from console
        if(strbfr==NULL) goto error;
    }
    strbfr[i] = '\0';
    *pStrBfr = strbfr; //successfully returns pointer to NULL terminated buffer
    return i + 1; 
    error:
    *pStrBfr = strbfr;
    return i + 1;
}

0

কনসোল থেকে একটি লাইন পড়ার সবচেয়ে সহজ এবং সহজ উপায়টি getchar () ফাংশনটি ব্যবহার করছে, যার মাধ্যমে আপনি একবারে একটি অক্ষরে একটি অ্যারে সংরক্ষণ করবেন store

{
char message[N];        /* character array for the message, you can always change the character length */
int i = 0;          /* loop counter */

printf( "Enter a message: " );
message[i] = getchar();    /* get the first character */
while( message[i] != '\n' ){
    message[++i] = getchar(); /* gets the next character */
}

printf( "Entered message is:" );
for( i = 0; i < N; i++ )
    printf( "%c", message[i] );

return ( 0 );

}


-3

এই ফাংশনটি আপনি যা চান তা করা উচিত:

char* readLine( FILE* file )
 {
 char buffer[1024];
 char* result = 0;
 int length = 0;

 while( !feof(file) )
  {
  fgets( buffer, sizeof(buffer), file );
  int len = strlen(buffer);
  buffer[len] = 0;

  length += len;
  char* tmp = (char*)malloc(length+1);
  tmp[0] = 0;

  if( result )
   {
   strcpy( tmp, result );
   free( result );
   result = tmp;
   }

  strcat( result, buffer );

  if( strstr( buffer, "\n" ) break;
  }

 return result;
 }

char* line = readLine( stdin );
/* Use it */
free( line );

আশা করি এটা কাজে লাগবে.


1
আপনার করা উচিত fgets( buffer, sizeof(buffer), file );নয় sizeof(buffer)-1fgetsসমাপ্ত নাল জন্য স্থান ছেড়ে।
ব্যবহারকারী 102008

মনে রাখবেন যে while (!feof(file))সর্বদা ভুল এবং এটি ভুল ব্যবহারের আরও একটি উদাহরণ।
জোনাথন লেফলার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.