2009-04-06 12 views
29

जावा में मैं एक स्कैनर एक स्ट्रिंग पारित कर सकते हैं और फिर मैं की तरह, scanner.hasNext() या scanner.nextInt(), scanner.nextDouble() आदिस्ट्रिंग के लिए सी # में स्कैनर क्लास के बराबर है?

यह एक स्ट्रिंग है संख्याओं की पंक्तियां हैं पार्स करने के लिए कुछ बहुत साफ कोड की अनुमति देता है काम कर सकते हैं।

यह सी # भूमि में कैसे किया जाता है?

आप एक स्ट्रिंग है था कहना था:

"0 0 1 22 39 0 0 1 2 33 33" 

जावा में मैं एक स्कैनर है कि गुजरती हैं और एक

while(scanner.hasNext()) 
    myArray[i++] = scanner.nextInt(); 

या बहुत कुछ इसी तरह करना होगा। ऐसा करने के लिए सी # 'आश रास्ता क्या है?

+0

(हमें सी # लोगों के लिए) आप कैसे एक स्कैनर आरंभ नहीं हो जाता के लिए कोड दिखा सकता है - उदाहरण के लिए, आप की जरूरत है उस प्रकार को बताएं जिसके लिए आप स्कैनिंग कर रहे हैं? –

+0

स्कैनर एस = नया स्कैनर (इनपुट) जहां इनपुट कई अलग-अलग प्रकार की चीजें हैं (स्ट्रिंग, फ़ाइल, पठनीय, इनपुटस्ट्रीम, आदि ..) http://java.sun.com/javase/6/docs/api/java/ util/Scanner.html। इसके अलावा हैक्स्ट (जैसे hasNextInt()) विधियों को देखने के लिए कि क्या आप खोज रहे हैं अगली बात पढ़ने के लिए है। – TofuBeer

+0

स्ट्रिंग में किसी भी प्रकार के किसी भी प्रकार के टोकन हैं या नहीं, यह देखने के लिए इसमें एक सामान्य है अगला() भी है। – mmcdole

उत्तर

2

हालांकि यह ठीक उसी मौलिक अवधारणा नहीं है, क्या आप इस लैम्ब्डा अभिव्यक्ति के साथ किया जा सकता है के लिए देख रहे:

string foo = "0 0 1 22 39 0 0 1 2 33 33"; 

int[] data = foo.Split(' ').Select(p => int.Parse(p)).ToArray(); 

यह क्या करता है पहले Splitstring, एक के रूप में एक स्थान का उपयोग सीमांकक। Select फ़ंक्शन आपको इस उदाहरण में किसी दिए गए सदस्य के लिए उपनाम निर्दिष्ट करने की अनुमति देता है (जिसे मैंने 'p' के रूप में संदर्भित किया है), फिर अंतिम परिणाम देने के लिए उस सदस्य पर एक ऑपरेशन करें। ToArray() कॉल तब इस अमूर्त संख्यात्मक वर्ग को एक ठोस सरणी में बदल देता है।

तो इस अंत में, यह string को विभाजित करता है, फिर प्रत्येक तत्व को int में परिवर्तित करता है और परिणामस्वरूप मानों के साथ int[] पॉप्युलेट करता है।

+0

स्कैनर का पूरा बिंदु यह था कि यह किसी भी संख्या के लिए काम करता है (न केवल पूर्णांक।) – Samuel

+0

फिर उसी अवधारणा को लागू करें, केवल int.Parse को डबल से बदलें। पर्स, फ्लोट। पर्स, इत्यादि –

+0

यह अभी भी बिंदु खो रहा है। क्या होगा यदि उसके स्ट्रिंग में 5 पूर्णांक, 2 युगल और एक फ्लोट है? आपका समाधान बिल्कुल मदद नहीं करता है। – Samuel

3

मेरे ज्ञान के लिए, ऐसा करने के लिए ढांचे में कक्षाओं में कोई भी निर्मित नहीं है। आपको अपना खुद का रोल करना होगा।

यह बहुत कठिन नहीं होगा। एक अच्छा सी # संस्करण IEnumerable लागू हो सकता है तो आप कह सकते हैं:

var scanner = new Scanner<int>(yourString); 
foreach(int n in scanner) 
    ; // your code 
+2

स्कैनर का पूरा बिंदु यह था कि यह किसी भी संख्या के लिए काम करता है (न केवल पूर्णांक।) – Samuel

+0

नहीं: नमूना कोड केवल इस कोड के समान ही पूर्णांक के लिए काम करता है। मुझे सामान्य विचार पसंद है। –

+3

स्कैनर वर्ग में कई और विधियां हैं, और अक्सर वे उसी स्कैनर से अलग-अलग चीजों को पढ़ने के लिए उपयोग की जाती हैं। उदाहरण के लिए एक स्ट्रिंग पढ़ें तो एक संख्या पढ़ें। – TofuBeer

0

मैं तुम्हें LINQ समर्थन के साथ नवीनतम नेट ढांचे का उपयोग कर रहे हैं कि क्या 1) के आधार पर एक जोड़े को एक तरीके से यह करना होगा और 2) क्या आप जानते हैं मान वैध पूर्णांक हैं। यहाँ दोनों प्रदर्शित करने के लिए एक समारोह है:

int[] ParseIntArray(string input, bool validateRequired) 
    { 
    if (validateRequired) 
    { 
     string[] split = input.Split(); 
     List<int> result = new List<int>(split.Length); 
     int parsed; 
     for (int inputIdx = 0; inputIdx < split.Length; inputIdx++) 
     { 
      if (int.TryParse(split[inputIdx], out parsed)) 
       result.Add(parsed); 
     } 
     return result.ToArray(); 
    } 
    else 
     return (from i in input.Split() 
       select int.Parse(i)).ToArray(); 
    } 

अन्य जवाब (रों) में टिप्पणी के आधार पर, मैं तुम्हें का सत्यापन करना होगा मान। उन टिप्पणियों को पढ़ने के बाद, मुझे लगता है कि आपको जो सबसे नज़दीकी चीज मिल जाएगी वह int है। ट्राईपर्स और डबल। ट्राईपर्स, जो हैक्स्टइन्ट और अगली इंटेंट (या हैक्स्ट डबल और अगले डबल का संयोजन) का संयोजन है।

1

तुम इतनी तरह यह पूरा करने के LINQ इस्तेमाल कर सकते हैं:

string text = "0 0 1 22 39 0 0 1 2 33 33"; 
text.Where(i => char.IsNumber(i)).Write(); // do somthing usefull here... 
2

अपने वाक्य रचना करने के लिए अधिक से अधिक निकट पाने के लिए, यह अगर आप केवल में एक प्रकार ("पूर्णांक" में रुचि रखते हैं काम करेंगे उदाहरण):

static void Main(string[] args) 
{ 
    if (args.Length == 0) { args = new string[] { "3", "43", "6" }; } 
    var scanner = args.Select<string, Func<Type, Object>>((string s) => { 
      return (Type t) => 
      ((IConvertible)s).ToType(t, System.Globalization.CultureInfo.InvariantCulture); 
     }).GetEnumerator(); 
    while (scanner.MoveNext()) 
    { 
     Console.Write("{0} ", scanner.Current(typeof(int))); 
    }    
} 
:

static void Main(string[] args) 
{ 
    if (args.Length == 0) { args = new string[] { "3", "43", "6" }; } 
    IEnumerator<int> scanner = (from arg in args select int.Parse(arg)).GetEnumerator(); 
    while (scanner.MoveNext()) 
    { 
     Console.Write("{0} ", scanner.Current); 
    }    
} 

यहाँ एक और भी अधिक विशेषज्ञ-धमाके के संस्करण है कि आप किसी भी प्रकार कि स्ट्रिंग के IConvertible कार्यान्वयन के द्वारा समर्थित है का उपयोग करने की अनुमति देता है है

टाइप टाइप करने के लिए बस लूप में "टाइपफ़ोफ़" ऑपरेटर को बस एक अलग प्रकार को पास करें।

इन दोनों को सी # और .NET ढांचे के नवीनतम संस्करणों की आवश्यकता है।

21

मैं इसे एक अलग उत्तर के रूप में जोड़ने जा रहा हूं क्योंकि यह पहले से दिए गए उत्तर से काफी अलग है। यहाँ कैसे आप अपने खुद के स्कैनर वर्ग का निर्माण शुरू कर सकते हैं:

class Scanner : System.IO.StringReader 
{ 
    string currentWord; 

    public Scanner(string source) : base(source) 
    { 
    readNextWord(); 
    } 

    private void readNextWord() 
    { 
    System.Text.StringBuilder sb = new StringBuilder(); 
    char nextChar; 
    int next; 
    do 
    { 
     next = this.Read(); 
     if (next < 0) 
      break; 
     nextChar = (char)next; 
     if (char.IsWhiteSpace(nextChar)) 
      break; 
     sb.Append(nextChar); 
    } while (true); 
    while((this.Peek() >= 0) && (char.IsWhiteSpace((char)this.Peek()))) 
     this.Read(); 
    if (sb.Length > 0) 
     currentWord = sb.ToString(); 
    else 
     currentWord = null; 
    } 

    public bool hasNextInt() 
    { 
    if (currentWord == null) 
     return false; 
    int dummy; 
    return int.TryParse(currentWord, out dummy); 
    } 

    public int nextInt() 
    { 
    try 
    { 
     return int.Parse(currentWord); 
    } 
    finally 
    { 
     readNextWord(); 
    } 
    } 

    public bool hasNextDouble() 
    { 
    if (currentWord == null) 
     return false; 
    double dummy; 
    return double.TryParse(currentWord, out dummy); 
    } 

    public double nextDouble() 
    { 
    try 
    { 
     return double.Parse(currentWord); 
    } 
    finally 
    { 
     readNextWord(); 
    } 
    } 

    public bool hasNext() 
    { 
    return currentWord != null; 
    } 
} 
+0

भले ही यह कोड जावा के मुकाबले कार्यक्षमता का प्रतिनिधित्व कर सके, मुझे संदेह है कि एक ही समस्या को कुछ समान विकल्प द्वारा हल किया जा सकता है जिसे मूल्य को दो बार पार्स नहीं करना पड़ता है (एक बार यह देखने के लिए कि इसे पार्स किया जा सकता है और एक बार वास्तव में मूल्य प्राप्त करने के लिए)। – BlueMonkMN

2

जवाब पहले ही दिया के हिस्से का उपयोग करना, मैं एक StringReader कि Enum और किसी भी डेटा प्रकार है कि IConvertible लागू करता निकाल सकते हैं बना लिया है।

प्रयोग

using(var reader = new PacketReader("1 23 ErrorOk StringValue 15.22") 
{ 
    var index = reader.ReadNext<int>(); 
    var count = reader.ReadNext<int>(); 
    var result = reader.ReadNext<ErrorEnum>(); 
    var data = reader.ReadNext<string>(); 
    var responseTime = reader.ReadNext<double>(); 
} 

कार्यान्वयन

public class PacketReader : StringReader 
{ 
    public PacketReader(string s) 
     : base(s) 
    { 
    } 

    public T ReadNext<T>() where T : IConvertible 
    { 
     var sb = new StringBuilder(); 

     do 
     { 
      var current = Read(); 
      if (current < 0) 
       break; 

      sb.Append((char)current); 

      var next = (char)Peek(); 
      if (char.IsWhiteSpace(next)) 
       break; 

     } while (true); 

     var value = sb.ToString(); 

     var type = typeof(T); 
     if (type.IsEnum) 
      return (T)Enum.Parse(type, value); 

     return (T)((IConvertible)value).ToType(typeof(T), System.Globalization.CultureInfo.CurrentCulture); 
    } 

} 
ब्याज में से
संबंधित मुद्दे