নিচে আমি আমার কোড দিলাম।

#include <stdio.h>
#include <string.h>
int main()
{
    int test,t;
    scanf("%d",&test);
    for(t=1;t<=test;t++){
      char str[100];
      gets(str);
      printf("Value : %s\n",str);
    }
    return 0;
}

আমি চাই যে প্রোগ্রামটা চালালে প্রথমে একটি নাম্বার ইনপুট নিবে। নাম্বারের মান যত ততবার লুপ চলবে এবং লুপের ভিতরে ঢুকে প্রথমেই একটি স্ট্রিং ইনপুট নিয়ে সেটি প্রিন্ট করবে এভাবে নাম্বার এর মান যত ততবার লুপ চলবে এবং স্ট্রিং প্রিন্ট করতে থাকবে। কিন্তু আমি যদি টেস্ট কেসের ইনপুট নেয়ার সময় scanf()-এ %d এর পরে একটা স্পেস না দেই তখন প্রথম বার যখন লুপের ভিতরে ঢোকে তখন স্ট্রিং এর মান ইনপুট না নিয়ে প্রথমেই প্রিন্ট হয়ে যায়। যদি টেস্ট কেসের ইনপুট নেয়ার সময় %d-এর পরে স্পেস দেই তাহলে কোড আশানুরূপ কাজ করে। একই সমস্যা জাভাতেও হচ্ছে। এখন আমার প্রশ্ন হলো এটা কেন হয় এবং এর সমাধান কী?

আমি হয়তো ভালোভাবে লিখতে পারিনি। দয়া করে এটা ক্ষমা-সুন্দর দৃষ্টিতে দেখবেন।

asked 31 Aug, 05:35

Sadman%20Shakib's gravatar image

Sadman Shakib
8313

edited 21 Oct, 07:39

Mosharraf%20Hosain's gravatar image

Mosharraf Hosain ♦
60618


ইনপুট নেয়া শেষে আমরা যে Enter চাপি সেটা scanf() গ্রহণ করে না। নির্দিষ্ট ফরমেট স্পেসিফায়ার উল্লেখ থাকায় scanf() শুধু ঐ নির্দিষ্ট টাইপের মানই গ্রহণ করে। তাই রিটার্ন ক্যারেক্টার বা নিউলাইন ক্যারেক্টারটা স্ট্যান্ডার্ড ইনপুট স্ট্রিমে থেকে যায়। gets() যেহেতু ইনপুট স্ট্রিম থেকে ইনপুট নিয়ে থাকে তাই রিটার্ন ক্যারেক্টারটা পাওয়ার সাথে সাথেই ইনপুট নেয়া বন্ধ করে দেয়। তাই প্রথমবার gets() কোনো ইনপুট নিতে পারে না।

ফরমেট স্পেসিফায়ার (এখানে %d) এর পরে স্পেস (বা অন্য কোনো হোয়াইটস্পেস ক্যারেক্টার) দিলে scanf() সব হোয়াইটস্পেস ক্যারেক্টার বাতিল (discard) করে দেয়। তাই gets() স্ট্যান্ডার্ড ইনপুট স্ট্রিমে আগে থেকে কিছু পায় না এবং ব্যবহারকারীর ইনপুটের জন্য অপেক্ষা করে।

এর সমাধান হচ্ছে এভাবেই স্পেস ব্যবহার করা বা scanf()-এর পরে অতিরিক্ত একটা getchar() ব্যবহার করা।

'''''''''''''''''''''''''''
scanf("%d",&t);
getchar();
for (...) {
''''''''''''''''''''''''''

scanf()-এর পরে আবার scanf() থাকলে এই সমস্যা দেখা যায় না। কারণ scanf() উল্লিখিত ফরমেট স্পেসিফায়ার অনুসারে ইনপুট নিয়ে বাড়তি সবকিছু বাতিল করে দেয়।

আপডেটঃ

ফরমেট স্পেসিফায়ারের পরে স্পেস (হোয়াইটস্পেস, \n, \r, \t, \f ইত্যাদি) দিলে scanf() সব হোয়াইটস্পেস ক্যারেক্টার ম্যাচ করতে থাকে। যখন হোয়াইটস্পেস আর পায় না তখন ইনপুট নেয়া সংখ্যাটা রিটার্ন করে যা t-তে জমা হয়। ফলে ইনপুট স্ট্রিমে কোনো কিছু থাকে না। তাই gets() ফাংশনও কিছু পায় না, ব্যবহারকারীর ইনপুটের অপেক্ষায় বসে থাকে। এন্টার কি চাপলে লিনাক্সে \n, উইন্ডোজে \r\n রিটার্ন করে। সমস্যাটা শুধু স্ট্রিঙের মধ্যে হয়, কারণ স্ট্রিঙে হোয়াইটস্পেসসহ সকল প্রকার ক্যারেক্টার থাকতে পারে। gets() বাদ দিয়ে scanf("%s",var) ব্যবহার করলে এই সমস্যা হয় না। তাছাড়া gets() ব্যবহার করতে তীব্রভাবে নিরুৎসাহিত করা হয়।

permanent link

answered 31 Aug, 07:49

Mosharraf%20Hosain's gravatar image

Mosharraf Hosain ♦
60618

edited 31 Aug, 13:20

ধন্যবাদ ভাই উত্তর টা পেয়েছি।

(31 Aug, 09:21) Sadman Shakib

ভাই জাভাতেও একই সমস্যা হচ্ছে কিন্তু আলাদা স্ক্যানার ব্যাবহার করলে সমস্যা হচ্ছে না এটা তে কি করা যায়...?

(31 Aug, 09:24) Sadman Shakib

জাভাতেও একই পদ্ধতি ব্যবহার করতে হবে। অতিরিক্ত একটি var.nextLine() ব্যবহার করলেই হবে।

(31 Aug, 11:04) Mosharraf Hosain ♦

ভাইয়া কেন ইনপুট নেয় না সেটা বুঝেছি কিন্তু ফরমেট স্পেসিফায়ার এর পরে স্পেস দিলে কেন এরকম হয়না সেটা এক্টু ক্লিয়ার করে দেন প্লিজ...আরেকটা প্রশ্ন ছিল জখন আমরা ইনপুট শেসে Enter বাটন চাপি সেটা কি কোন কিছু রিটার্ন করে...? আর এই সমস্যাটা শুধু কেন স্ট্রিং এর বেলায় ই হয় লুপের মধ্যে ইন্টিজার বা অন্য কোন টাইপে এমন সমস্যা হয়না কেন?

(31 Aug, 11:37) Sadman Shakib

উত্তর আপডেট করেছি।

(31 Aug, 13:19) Mosharraf Hosain ♦
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×395
×209
×70

question asked: 31 Aug, 05:35

question was seen: 235 times

last updated: 21 Oct, 07:39