fscanf()
एक साधन लिखने के लिए "अब तक fscanf
समारोह को यह कॉल द्वारा इनपुट स्ट्रीम से पढ़ने वर्णों की संख्या" के रूप में "%n"
निर्देश निर्दिष्ट करता C11dr §7.21.6.2 12.fscanf में "वर्णों की संख्या पढ़ने" की सीमा क्या है?
हमें इस नंबर पर कॉल करते हैं: ncount
।
"%n"
निर्देश लंबाई संशोधक hh, h, l, ll, j
और पूर्व अन्य लोगों द्वारा किया जा सकता है। उदाहरण:
FILE *stream = stdin;
int n_i;
fscanf(stream, "%*s%n", &n_i); // save as int
signed char n_hh;
fscanf(stream, "%*s%hhn", &n_hh); // save as signed char
long long n_ll;
fscanf(stream, "%*s%lln", &n_ll); // save as long long
प्रकार या
ncount
के न्यूनतम उम्मीद सीमा क्या है?
क्या होता है, या तब होना चाहिए, जब "इनपुट स्ट्रीम से वर्णित वर्णों की संख्या" बड़ा है?
मेरे निष्कर्ष:
सी कल्पना ncount
की न्यूनतम सीमा/प्रकार की परिभाषा पर शांत दिखाई देता है। ncount
आमतौर पर "%n"
के माध्यम से सहेजा जाता है जो int
गंतव्य निर्दिष्ट करता है हालांकि int
स्रोत नहीं है।
प्रयोग करके, ncount
को मेरे प्लेटफ़ॉर्म पर int
या long
जैसा माना जाता है - कोई वास्तविक आश्चर्य नहीं है। (मेरा int/long/long long
4/4/8 बाइट्स है।) ncount
को long long
पर सहेजते समय, बचाया गया मान INT_MAX/LONG_MAX
से अधिक नहीं है। ncount
unsigned
long long
पर असाइन किए जाने पर उपयोग करने योग्य सीमा से दोगुनी हो सकती है, फिर भी, यह एक चरम कोने है और शायद कार्यान्वयनकर्ताओं द्वारा नहीं माना जाता है।
नीचे दिए गए मेरे परीक्षणों में ncount
int
रेंज के बाद के रूप में सहेजे जाने पर भी विस्तारित सीमा दिखाई नहीं दी गई है।
मेरी रुचि एक (चरम) रेखा लंबाई निर्धारित करने के लिए "%*[^\n]%lln"
का उपयोग करने से उत्पन्न हुई।
कार्यान्वयन नोट:
जीएनयू सी 11 (जीसीसी) संस्करण 6.4.0 (i686-पीसी-cygwin) GNU सी संस्करण 6.4.0, जीएमपी संस्करण 6.1.2, MPFR संस्करण 3.1.5 द्वारा संकलित -पी 10, एमपीसी संस्करण 1.0.3, आईएसएल संस्करण 0.14 या 0.13
glibc 2.26 जारी किया गया।
इंटेल जिऑन W3530, 64-बिट ऑपरेटिंग सिस्टम (विंडोज 7)
टेस्ट कोड
#include <limits.h>
#include <stdio.h>
#include <string.h>
int print(FILE *stream, long long size, int ch) {
char buf[4096];
memset(buf, ch, sizeof buf);
while (size > 0) {
size_t len = size < (long long) sizeof buf ? (size_t) size : sizeof buf;
size_t y = fwrite(buf, 1, len, stream);
if (len != y) {
perror("printf");
return 1;
}
size -= len;
}
return 0;
}
int scan(FILE *stream) {
rewind(stream);
long long n = -42;
int cnt = fscanf(stream, "%*s%lln", &n);
printf("cnt:%d n:%lld ", cnt, n);
return cnt != 0;
}
int testf(long long n) {
printf("%10lld ", n);
FILE *f = fopen("x.txt", "w+b");
if (f == NULL) {
perror("fopen");
return 1;
}
if (print(f, n, 'x')) {
perror("print");
fclose(f);
return 2;
}
if (scan(f)) {
perror("scan");
fclose(f);
return 3;
}
fclose(f);
puts("OK");
fflush(stdout);
return 0;
}
int main(void) {
printf("%d %ld %lld\n", INT_MAX, LONG_MAX, LLONG_MAX);
testf(1000);
testf(1000000);
testf(INT_MAX);
testf(INT_MAX + 1LL);
testf(UINT_MAX);
testf(UINT_MAX + 1LL);
testf(1);
return 0;
}
टेस्ट उत्पादन
2147483647 2147483647 9223372036854775807
File length Reported bytes read
1000 cnt:0 n:1000 OK
1000000 cnt:0 n:1000000 OK
2147483647 cnt:0 n:2147483647 OK
2147483648 cnt:0 n:-2147483648 OK // implies ncount is internally an `int/long`
4294967295 cnt:0 n:-1 OK
4294967296 cnt:0 n:-1088421888 OK // This `n` value may not be consistent. -1 also seen
1 cnt:0 n:1 OK
[संपादित करें]
कुछ के साथके रन 10, मुझे अन्य असंगत परिणाम जैसे '42 9 4 9 672 9 6 सीएनटी: 0 एन: 1239482368 ओके' मिला। Hmmmm।
नमूना fscanf()
support source codencount
के लिए int
का उपयोग करता है।
मैंने एक दिलचस्प प्रश्न के लिए वोटिंग के बीच संघर्ष किया और मतदान नहीं किया क्योंकि, यदि आपका इनपुट विदेशी है, तो आपको अपना खुद का पार्सिंग लिखना चाहिए और 'fscanf' का उपयोग नहीं करना चाहिए। फिर भी, मुझे उम्मीद है कि उत्तर सी 2011 5.2.4.1 है: "कार्यान्वयन कम से कम एक कार्यक्रम का अनुवाद और निष्पादन करने में सक्षम होगा ..." आपका कार्यक्रम वह नहीं है। –
मैं मानक के आपके विश्लेषण से सहमत हूं। यह इस बात पर बाध्य नहीं करता है कि 'ncount' कितना बड़ा होना चाहिए। यह निर्दिष्ट करता है कि 'll' (और' z' और 't') लंबाई विनिर्देशक 'n' निर्देश में प्रकट हो सकते हैं, और निश्चित रूप से आप सही हैं कि प्राप्त करने वाले चर के आकार का वर्णन करता है, स्रोत संख्या नहीं । –
@EricPostpischil 'fscanf()' का उपयोग पढ़ने से पहले नहीं जानता है कि इनपुट विदेशी है या नहीं। मुद्दा यह नहीं है कि इनपुट विदेशी है, लेकिन '% * s% n" 'विदेशी इनपुट के लिए लचीला नहीं है। उदाहरण के लिए, '"% 1000s% n "' विदेशी इनपुट के साथ काम करेगा - जब तक 'ncount' कम से कम 10 बिट होगा। – chux