2017-10-12 83 views
0

转换string strjsonconst char* json,当interate,显示 失败:(IsObject()),功能FindMember,失败了,我不明白为什么这显示出,我觉得这个json对象是正确的格式。将字符串转换为const * json后,当放置json对象时,显示失败:(IsObject()),如何解决这个问题?

// 
// main.cpp 
// rapid 
// 
// Created by Shi Yan on 10/7/17. 
// Copyright © 2017 Shi Yan. All rights reserved. 
// 

#include <iostream> 
#include "rapidjson.h" 
#include "document.h" 
#include <fstream> 
using namespace std; 
using namespace rapidjson; 
void readjson(){ 
    ifstream handle("meta_Books.json"); 
    if(handle.is_open()){ 
     //cout<<"open success"<<endl; 
     const char* json; 
     string strjson; 
     int i=1; 
     while(getline(handle,strjson)){ 
      if(i>4) 
       break; 
      cout<<strjson<<endl; 
      cout<<strjson.length()<<endl; 
      i++;    
      json=strjson.c_str(); 
      cout<<"*********************"<<endl; 
      cout<<*json<<endl; 
      StringStream s (json); 
      Document document; 
      document.ParseStream(s); 
      Value::ConstMemberIterator itr = document.FindMember("asin"); 
      cout<<itr->name.GetString()<<" = "<< itr->value.GetString()<<endl; 
     } 
    } 
} 
int main() { 
    readjson(); 
    return 0; 
} 

我认为json对象的格式,为什么失败?

image

正如你所看到的,getline()方法效果很好,因为串的输出是一个完整的字符串

image

+1

注意,此线'COUT << * JSON << ENDL;'正在输出char数组中的单个字符(通过取消引用'const char *'得到'char') –

+0

但是在前两个输出中,我得到正确答案来查询key =“asin”的值,但是,在处理第三个对象,它失败了。解析第二个对象是正常的,所以我认为不用用一个对象开始就没有它的根。但为什么解析失败? – shiyan

+0

我已经知道为什么要得到第一个字符,谢谢史蒂夫 – shiyan

回答

2

的断言错误意味着FindMember()被称为上Value这并不代表JSON对象(IsObject()为false)。

由于您显示的代码中只有1 FindMember(),这意味着document.FindMember()失败时document.IsObject()为false。您正在解析的JSON不是以其根目标中的对象开始,或者解析失败。您在代码中没有测试哪种条件。

如果我不得不猜测(并且请不要让人猜测!),失败的JSON文档可能包含未编码的换行符(这在JSON字符串值内不是非法的)。这会导致std::getline()过早退出,从而导致解析问题。 您显示的第一张截图支持这一结论,表明strjson在发生错误时正在两条单独的“行”之间进行分割。

比使用std::getline()行由行读取文件,嵌入式换行符冒着错误相反,我建议您尝试使用RapidJSON的BasicIStreamWrapper类读取文件文件逐文件来代替。 ParseStream()具有kParseStopWhenDoneFlag标记允许从单个输入流解析多个根文件:

kParseStopWhenDoneFlag 

After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error.

例如:

#include <iostream> 
#include <fstream> 
#include "rapidjson.h" 
#include "document.h" 
#include "istreamwrapper.h" 

using namespace std; 
using namespace rapidjson; 

void readjson() 
{ 
    ifstream handle("meta_Books.json"); 
    if (!handle.is_open()) 
    { 
     // handle error... 
     cout << "error opening file" << endl; 
    } 
    else 
    { 
     BasicIStreamWrapper<ifstream> s(handle); 
     for(int i = 1; i <= 4; ++i) 
     { 
      Document document; 
      ParseResult pr = document.ParseStream<kParseStopWhenDoneFlag>(s); 
      if (!pr) 
      { 
       // handle error... 
       cout << "error parsing document " << i << endl; 
      } 
      else if (!document.IsObject()) 
      { 
       cout << "document " << i << " is not an object" << endl; 
      } 
      else 
      { 
       Value::ConstMemberIterator itr = document.FindMember("asin"); 
       if (itr != document.MemberEnd()) 
        cout << "asin = " << itr->value.GetString() << endl; 
       else 
        cout << "asin not found" << endl; 
      } 
     } 
    } 
} 

int main() 
{ 
    readjson(); 
    return 0; 
} 
+0

我试过了,它仍然无法工作, 错误:使用类模板'BasicIStreamWrapper'需要模板参数BasicIStreamWrapper(handle); – shiyan

相关问题