समस्या
scanf() से पूर्णांक पढ़ने के बाद gets() या scanf("%s") से स्ट्रिंग पढ़ने पर स्ट्रिंग छोड़ दी जाती है।
कारण
scanf("%d", &n) संख्या पढ़ता है लेकिन नई लाइन (\n) बफर में छोड़ देता है। बाद में gets() या scanf("%s") उस \n को देखता है और तुरंत समाप्त हो जाता है (खाली स्ट्रिंग)।
समाधान
- अतिरिक्त scanf("%c") से नई लाइन खपत करें
- fgets() उपयोग करें (सुरक्षित, पूरी लाइन पढ़ता है)
- scanf() फॉर्मेट में स्पेस:
" %s"या" %[^\n]"
समाधान 1: अस्थायी char पढ़ें
#include <stdio.h>
struct Student {
char name[50];
int roll;
char temp; // बफर खपत के लिए
};
int main() {
struct Student s;
printf("रोल नंबर: ");
scanf("%d", &s.roll);
scanf("%c", &s.temp); // \n खपत करें
printf("नाम: ");
fgets(s.name, sizeof(s.name), stdin);
// fgets \n शामिल करता है, हटाएं
size_t len = strlen(s.name);
if (len > 0 && s.name[len-1] == '\n')
s.name[len-1] = '\0';
printf("\nरोल: %d\nनाम: %s\n", s.roll, s.name);
return 0;
}
समाधान 2: fgets() + sscanf() (अनुशंसित)
#include <stdio.h>
#include <stdlib.h>
int main() {
char line[100];
int roll;
char name[50];
printf("रोल नंबर: ");
fgets(line, sizeof(line), stdin);
roll = atoi(line); // या sscanf(line, "%d", &roll)
printf("नाम: ");
fgets(name, sizeof(name), stdin);
name[strcspn(name, "\n")] = '\0'; // \n हटाएं
printf("रोल: %d, नाम: %s\n", roll, name);
return 0;
}
समाधान 3: scanf() में अग्रणी स्पेस
int roll;
char name[50];
scanf("%d", &roll);
scanf(" %49[^\n]", name); // %c/%s/%[ से पहले स्पेस व्हाइटस्पेस छोड़ता है
तुलना
| विधि | पक्ष | विपक्ष |
|---|---|---|
| temp char | सरल | केवल एक वर्ण खपत, एकाधिक \n विफल |
| fgets + sscanf | सुरक्षित, पूरी लाइन, बफर ओवरफ्लो नहीं | थोड़ा अधिक कोड |
| scanf(" %s") | संक्षिप्त | स्पेस नहीं पढ़ता, बफर ओवरफ्लो संभव |
| scanf(" %[^\n]") | स्पेस सहित पूरी लाइन | बफर आकार सीमा (width specifier आवश्यक) |
सर्वोत्तम अभ्यास
✅ अनुशंसित पैटर्न
// 1. पूर्णांक पढ़ें
int n;
char line[100];
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &n);
// 2. स्ट्रिंग पढ़ें
char str[100];
fgets(str, sizeof(str), stdin);
str[strcspn(str, "\n")] = '\0'; // नई लाइन हटाएं
यह सबसे मजबूत है: कोई बफर समस्या नहीं, स्पेस संभालता है, आकार सीमा सम्मान करता है।
महत्वपूर्ण: gets() कभी उपयोग न करें
gets()C11 में हटाया गया, असुरक्षित (बफर ओवरफ्लो)- हमेशा
fgets()याscanf()विद विड्थ उपयोग करें