স্ক্যানফ দিয়ে স্ট্রিং পড়া Read


147

আমি কিছু সম্পর্কে কিছুটা বিভ্রান্ত। আমি ছাপে ছিলাম যে একটি সি স্ট্রিং পড়ার সঠিক উপায়টি scanf()লাইন দিয়ে চলেছে

(সম্ভাব্য বাফার ওভারফ্লোকে কখনই মনে করবেন না, এটি কেবল একটি সহজ উদাহরণ)

char string[256];
scanf( "%s" , string );

তবে, নিম্নলিখিতগুলিও কাজ করে বলে মনে হচ্ছে,

scanf( "%s" , &string );

এটি কি কেবল আমার সংকলক (জিসিসি), খাঁটি ভাগ্য, বা অন্য কিছু?


দ্বিতীয় ক্ষেত্রে, আসলে কোনও সম্ভাব্য বাফার ওভারফ্লো নেই কারণ আপনি যে বাফারটি একেবারেই ব্যবহার করছেন না। হয় তা হয়, বা আপনি বলতে পারেন যে 3 টি অক্ষরের চেয়ে বড় স্ট্রিং আপনার "বাফার" উপচে যাবে।
টেড

আমি প্রথম উদাহরণ উল্লেখ করছি। এছাড়াও, অন্যরা ইতিমধ্যে এখানে কী চলছে তা দেখিয়েছে।
আবেলান

হা. এটি চেষ্টা করে দেখুন, এবং গ্যারেথ ঠিক বলেছেন। রহস্যময়।
টেড

যেহেতু এই প্রশ্নটি "স্ক্যানফের সাহায্যে স্ট্রিংটি কীভাবে পড়তে হবে" অনুসন্ধান করে ফিরে আসে, তাই এই প্রশ্নটি বাফারে পয়েন্টারটি পাস করার উপায় scanfসম্পর্কে এবং প্রশ্ন এবং স্বীকৃত উত্তর উভয়ের দিকেই ফোকাস দেওয়া উপযুক্ত হতে পারে appropriate যা, এবং সর্বাধিক ইনপুট দৈর্ঘ্যের জন্য সমালোচনামূলকভাবে গুরুত্বপূর্ণ বিধিনিষেধগুলি বাদ দেয় যা বাস্তব কোডে ব্যবহার করা উচিত (তবে এই প্রশ্নের মূল বিষয়টি ছাড়াও)।
আরক্কু

উত্তর:


141

একটি অ্যারে তার প্রথম উপাদানটির একটি পয়েন্টারে "ক্ষয়" করে, এর scanf("%s", string)সমতুল্য scanf("%s", &string[0])। অন্যদিকে, scanf("%s", &string)একটি পয়েন্টার-টু- পাস করে char[256]তবে এটি একই জায়গায় নির্দেশ করে।

তারপরে scanf, এটির যুক্তি তালিকার লেজটি প্রক্রিয়া করার সময়, এটিকে বের করার চেষ্টা করবে char *। যে রাইট আর যখন আপনি পাস করেছি stringবা &string[0], কিন্তু যখন আপনি পাস করেছি &stringআপনাকে কিছু উপর নির্ভর করে করছি সেই ভাষাটি কি প্রমিত গ্যারান্টি নয়, যে আছে যথা যে পয়েন্টার &stringএবং &string[0]- পয়েন্টার বিভিন্ন ধরনের এবং আকারের বস্তু যে একই জায়গায় শুরু - একই উপায়ে প্রতিনিধিত্ব করা হয়।

আমি বিশ্বাস করি না যে আমি এমন কোনও সিস্টেমের মুখোমুখি হয়েছি যেখানে এটি কাজ করে না, এবং বাস্তবে আপনি সম্ভবত নিরাপদ। কিছুই কম নয়, এটি ভুল, এবং এটি কিছু প্ল্যাটফর্মে ব্যর্থ হতে পারে। (হাইপোথিটিক্যাল উদাহরণ: একটি "ডিবাগিং" বাস্তবায়ন যা প্রতিটি পয়েন্টারের সাথে টাইপ তথ্য অন্তর্ভুক্ত করে I আমি মনে করি প্রতীক "লিস্প মেশিনস" এর উপর সি বাস্তবায়ন এরকম কিছু করেছিল))


5
+1 টি। অ্যারে ক্ষয় ফলাফল &stringএকই হিসাবে কাজ করে যাচাই করাও তুচ্ছ - string(অন্য উত্তরগুলি ভুলভাবে জোর দিয়ে বলে, এলোমেলো স্মৃতি দুর্নীতির ফলস্বরূপ):printf("%x\n%x\n", string, &string);
জোশ কেলি

@ জোশ কেলি আকর্ষণীয়, আমি তখন এটি গ্রহণ করব যে ম্যালোক () এর মাধ্যমে বরাদ্দ স্ট্রিংয়ের পয়েন্টারের সাথে এটি হবে না?
আবেলান

4
@ আবেলান: সঠিক। Malloc () এর মাধ্যমে বরাদ্দকৃত স্ট্রিংয়ের জন্য, stringএটি একটি পয়েন্টার এবং &stringএটি সেই পয়েন্টারের ঠিকানা, সুতরাং দুটি বিনিময়যোগ্য নয়। যেমন গ্যারেথ ব্যাখ্যা করেছেন, এমনকি অ্যারে ক্ষয় হওয়ার ক্ষেত্রেও stringএবং &stringপ্রযুক্তিগতভাবে একই ধরণের নয় (যদিও এটি বেশিরভাগ আর্কিটেকচারের জন্য আদান-প্রদানযোগ্য হতে পারে) এবং আপনি যদি চালু করেন তবে জিসিসি আপনার দ্বিতীয় উদাহরণের জন্য একটি সতর্কতা দেবে -Wall
জোশ কেলি

@ জোশ কেলি: ধন্যবাদ, আমি খুশি এই বিষয়ে আমি আমার মন পরিষ্কার করতে পারলাম।
আবলান

1
@ জে.কোপার স্ট্রিং, আরআরটি [0] উভয়ই একই জিনিস (অ্যারের শুরু) উপস্থাপন করে এবং যদিও প্রয়োজন হয় না যে অ্যান্ডআরটি একই মেমরি ঠিকানাও নয়। এখন আরআরপিটিআরটিআরআরটি পয়েন্ট তাই আরআরপিআরটির ভিতরে সঞ্চিত মেমরি ঠিকানাটি স্ট্রের মতো এবং 12fe60 হয়। শেষ অবধি & strPtr হ'ল ভেরিয়েবলের ঠিকানা, এটি স্ট্রপ্ট্রিতে মান স্টোর নয় তবে স্ট্রপ্ট্রির আসল মেমরি ঠিকানা। যেহেতু স্ট্র্যাপ্টর অন্য সকলের থেকে পৃথক পরিবর্তনশীল এটির একটি পৃথক মেমরি ঠিকানাও রয়েছে, এক্ষেত্রে 12fe54
জুয়ান বেসা

-9

আমি মনে করি যে নীচে এটি সঠিক এবং এটি সাহায্য করতে পারে। আপনি যদি কোনও ত্রুটি দেখতে পান তবে এটি নির্দ্বিধায় মনে করুন আমি সি তে নতুন

char str[]  
  1. টাইপ চর এর মানগুলির অ্যারে, মেমরিতে তার নিজস্ব ঠিকানা
  2. অ্যারেতে উপাদান হিসাবে বিভিন্ন ক্রমাগত ঠিকানা মেমরির নিজস্ব ঠিকানা সহ চরের প্রকারের মানগুলির অ্যারে
  3. পরিসমাপ্তি নাল চরিত্র সহ '\0' &str, &str[0]এবং strতিন মেমরি একই অবস্থানে যা অ্যারের প্রথম উপাদান এর ঠিকানা হল প্রতিনিধিত্বstr

    চর * strPtr = & str [0]; // ঘোষণা এবং সূচনা

বিকল্পভাবে, আপনি এটি দুটি বিভক্ত করতে পারেন:

char *strPtr; strPtr = &str[0];
  1. strPtr একটি পয়েন্টার char
  2. strPtr অ্যারে এ পয়েন্ট str
  3. strPtr মেমরির নিজস্ব ঠিকানা সহ একটি পরিবর্তনশীল
  4. strPtr একটি পরিবর্তনশীল যা ঠিকানার মান সংরক্ষণ করে &str[0]
  5. strPtr মেমরিতে নিজের ঠিকানা মেমরির ঠিকানা থেকে আলাদা যা এটি সঞ্চয় করে (মেমরির অ্যারের ঠিকানা ওরফে এবং স্ট্রিং [0])
  6. &strPtr আরআরপিটিআর এর ঠিকানা প্রতিনিধিত্ব করে

আমি মনে করি আপনি কোনও পয়েন্টারকে পয়েন্টার হিসাবে এটি ঘোষণা করতে পারেন:

char **vPtr = &strPtr;  

আরআরপিটিআর পয়েন্টারের ঠিকানা দিয়ে ঘোষণা এবং আরম্ভ করে

বিকল্পভাবে আপনি দুটি বিভক্ত করতে পারে:

char **vPtr;
*vPtr = &strPtr
  1. *vPtr strPtr পয়েন্টারে বিন্দু
  2. *vPtr মেমরির নিজস্ব ঠিকানা সহ একটি পরিবর্তনশীল
  3. *vPtr এমন একটি পরিবর্তনশীল যা ঠিকানার মান এবং স্ট্রিংআরপিটিআর সঞ্চয় করে
  4. চূড়ান্ত মন্তব্য: আপনি করতে পারবেন না str++, strঠিকানা একটি constতবে আপনি করতে পারেনstrPtr++
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.