2016-04-08 21 views
1

Belirli bir basit biçim için bir dizi karakter dizisini kontrol etmem ve iki sayının değerlerini aynı anda almam gerekiyor. Mesaj formatı: START numarası numarası END. Ben ile gelebilir Bütün bunlar oldu:Biçimi kontrol edin ve sayıları sscanf ile değiştirin C++

int x,y; 
if (sscanf(buffer, "START %d %d END", &x, &y) != 2) 
    return false; 
... 
... 
... 
return true; 

Ama tabii bu rakamlar elde edilmiştir çünkü biten tamamen farklı olma sonra bile başarılı olur. Bunu yapmanın en iyi yolu ne? Önerileriniz için teşekkürler.

+0

Arabellek içeriğini ve "START% d% d END" dizenizi karıştırdınız. sscanf, dize ve ikinci bir dize ile format verilerinizi i.e.'sscanf ("START 9 10 END", "% s% d% d% s", buff1, & x, & y, buff2) 'yi içeren bir arabellek bekler. Ne yapmaya çalışıyorsun ? – auburg

+0

Biçimlendirme dizgisi "START% d% d" ile çağrı yapın ve her şey yolundaysa, "% s" biçimlendirme dizesiyle sscanf dosyasını arayın ve sonucu "END" ile karşılaştırın. – pointer

+0

@auburg, biçim verisi **, ** '" START% d% d END "' dür, yani dize bu sıradan karakterleri içermelidir. % S'i bir scanf biçiminde kullanmak tehlikelidir ve her zaman önlenmelidir,% 5s ve% 3s kullandıysanız öneriniz Tamam olur. –

cevap

1

C standardını kontrol ettikten sonra bunu tespit etmek için taşınabilir bir yol olmadığına hayran kaldım.

Linux'ta errno ayarlandığında, ferror'u da kullanabilirsiniz. Windows errno da ayarlanmış, ancak MSDN ferror bahsetmiyor.


Bunun yerine karışık ama taşınabilir bir çözüm için bu yapabilirdi:

int x,y; 
char d; 
if (sscanf(buffer, "START %d %d EN%c", &x, &y, &d) != 3 || 'D' != d) 
    return false; 
+0

'Ferror', sscanf' için alakasız çünkü bir dosya akışından okunmuyor. –

+0

@JonathanWakely özür dilerim "fscanf" değil "sscanf" belgelerini okuyordum. – Simple

+0

Çözümünüz 'buffer' holding için başarısız oluyor ** START END ** –

0

Hep sscanf() ve benzeri fonksiyonların zahmetli kullanımını buldum

int x, y; 
size_t pos = -1; 
char str[4]; 
if (sscanf(buffer, "START %d %d %3s%zn", &x, &y, str, &pos) != 3 || strcmp(pos, "END") || pos != strlen(buffer)) 
    return false; 
//... 
return true; 
1

deneyin. Diğer çözümler çok daha şık olmasına rağmen, strtok() 'a dayanan daha basit ve daha kolay bakım kodlarını tercih ediyorum.

#include <cstdio> 
#include <cstring> 

int main() 
{ 
    char buf[250]; 

    const char* delimiters=" \n"; 

    while(fgets(buf,250,stdin)!=nullptr){ 
     // fgets() reads the newline... 
     printf("%s",buf); 
     // Tokenize the buffer using 'delimiters'. The nullptr will re-use the same buffer. 
     char* pBegin = strtok(buf,delimiters); 
     char* pNumb1 = strtok(nullptr,delimiters); 
     char* pNumb2 = strtok(nullptr,delimiters); 
     char* pEnd = strtok(nullptr,delimiters); 
     // Protect our strcmp from a nullptr(missing data) and do some validity tests. 
     if((pEnd!=nullptr)&&(strcmp(pBegin,"BEGIN")==0)&&(strcmp(pEnd,"END")==0)){ 
      printf(" Begin = '%s'\n",pBegin); 
      printf(" Numb1 = '%s'\n",pNumb1); 
      printf(" Numb2 = '%s'\n",pNumb2); 
      printf(" End = '%s'\n",pEnd); 
     }else{ 
      printf(" Error!\n"); 
     } 
    } 
} 

Ve (sonunda bazı boş satırlar ile) bazı test verileri: Burada denemek için biraz programdır

BEGIN 106 635 END 
BEGIN 107 636 END 
BEGaN 108 637 ENDING 
BeGIN 115 644 End 
BEGIN 116 645 END 
BEGIN 117 646 END of it all 
BEgIN 128 657 END 
BEGIN 129 658 END 
BEGIN 130 659 Finish 
131 660 END 
BEGIN 662 END 
BEGIN 136 665 
BEGIN 136 
BEGIN 

Ve bu çıkış olurdu ...

BEGIN 106 635 END 
    Begin = 'BEGIN' 
    Numb1 = '106' 
    Numb2 = '635' 
    End = 'END' 
BEGIN 107 636 END 
    Begin = 'BEGIN' 
    Numb1 = '107' 
    Numb2 = '636' 
    End = 'END' 
BEGaN 108 637 ENDING 
    Error! 
BeGIN 115 644 End 
    Error! 
BEGIN 116 645 END 
    Begin = 'BEGIN' 
    Numb1 = '116' 
    Numb2 = '645' 
    End = 'END' 
BEGIN 117 646 END of it all 
    Begin = 'BEGIN' 
    Numb1 = '117' 
    Numb2 = '646' 
    End = 'END' 
BEgIN 128 657 END 
    Error! 
BEGIN 129 658 END 
    Begin = 'BEGIN' 
    Numb1 = '129' 
    Numb2 = '658' 
    End = 'END' 
BEGIN 130 659 Finish 
    Error! 
131 660 END 
    Error! 
BEGIN 662 END 
    Error! 
BEGIN 136 665 
    Error! 
BEGIN 136 
    Error! 
BEGIN 
    Error! 

    Error! 
İlgili konular