Unicode文件操作静态库制作

在日常的C++编程中,使用频率最多的应该是Unicode文件的读写,今天我们用VS2015来制作个属于自己的简单类库,这样能够会大大提高编程效率。

环境

  • IDE:Visual Studio 2015
  • Language: C++

一、创建静态库工程

  • 打开VS2015,创建新工程,选择"Win32 Project",命名为UnicodeFileLib


    新建项目
  • 勾选Static Library和MFC选项,若不需要MFC类库,可以不选。


    选择项目类型

点击“完成”。

二、编写Unicode文件操作类

1.添加一个新类

新建类

右键工程名,如图新建类。

新建类

直接点“添加” 按钮

填写类名

如图,将类命名为“CUnicodeFile”,点击“完成” 按钮。

2.实现CUnicodeFile

工程中出现了一组新文件,UnicodeFile.h和UnicodeFile.cpp。这里不具体介绍文件操作的内容,直接贴出代码,如有问题欢迎邮件讨论。

  • UnicodeFile.h

      #pragma once
    
      #include <set>
              #include "stdafx.h"
    
      #define FOR_READ    0x10
      #define FOR_WRITE   0x11
      #define FOR_RE_WR   0x12
    
      class CUnicodeFile
      {
      public:
          CUnicodeFile(void);
          ~CUnicodeFile(void);
      
          BOOL Load(TCHAR* pFileName, USHORT operateType);
          VOID Release(VOID);
      
          BOOL CheckUnicodeFile();
      
          BOOL SkipUnicodeFlag(VOID);
          VOID SetUnicodeFlag(VOID);
      
          static BOOL Delete(CUnicodeFile& fileDel);
          static BOOL Delete(CString strFileName);
      
          CString GetFileName(VOID);
          CString GetFileNameExt(VOID);
      
          FILE *GetFilePointer(VOID);
      
          VOID SetFlag(USHORT flag);
          USHORT GetFlag(VOID);
      
          BOOL ReadLine(CString& cstr);
      
          BOOL WriteLine(CString cstr);
      
          BOOL WriteSet(std::set< CString > *pCStringSet);
      
          VOID WriteLineEnd(VOID);
      
          int Seek(LONG offset, int origin);
          LONG TellOffset(VOID);
      
          VOID WriteAWord(TCHAR ch);
          BOOL ReadAWord(TCHAR& ch);
      
          int WriteBuffer(const void* buffer, size_t itemSize, size_t count);
          int ReadBuffer(void* buffer, size_t itemSize, size_t count);
      
          BOOL Flush(VOID);
          BOOL GetFileAsBuffer(CString strFileName);
      
      protected:
          // The flag for operate type. FOR_READ, for reading; FOR_WRITE, for writing
          USHORT m_fileOperateFlag;
          // The pointer for file which will be operated
          FILE* m_pFile;
          // The file name
          CString m_strFileName;
          // The file name extension
          CString m_strFileNameExt;
          // The temp TCHAR buffer
          TCHAR* m_pBuffer;
      };
    
  • UnicodeFile.cpp

      #include "stdafx.h"
    
      #include "UnicodeFile.h"
      
      #include <iostream>
      
      #define MAXCHARS 511
      
      #define Succeeded   TRUE
      #define Failed      FALSE
      
      /*---------------------------------------------------------------------------
      **        Name : CUnicodeFile
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description : Construct function
      **       Input : None
      **      Output : None
      **---------------------------------------------------------------------------*/
      CUnicodeFile::CUnicodeFile(void)
      {
          m_fileOperateFlag = 0;
          m_pFile = NULL;
          m_pBuffer = NULL;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : CUnicodeFile
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description :
      **       Input : None
      **      Output : None
      **---------------------------------------------------------------------------*/
      CUnicodeFile::~CUnicodeFile(void)
      {
          // Do nothing
      }
      
      /*---------------------------------------------------------------------------
      **        Name : Load
      **      Author : Barry Tang
      **        Date : 2010/1/8
      ** Description : Init the attribute of the object
      **       Input : pFileName, the file name buffer
      operateType, the operate method
      **      Output : TRUE or FALSE
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::Load(TCHAR* pFileName, USHORT operateType)
      {
          // Save the file name
          m_strFileName = pFileName;
      
          // Get the file name extension
          int find = m_strFileName.ReverseFind('.');
      
          if (find == -1)
          {
              m_strFileNameExt.Empty();
          }
          else
          {
              m_strFileNameExt = m_strFileName.Mid(find + 1).Trim();
          }
      
          // Set the operate method
          m_fileOperateFlag = operateType;
      
          switch (operateType)
          {
          case FOR_READ:
              _wfopen_s(&m_pFile, pFileName, TEXT("rb"));
              break;
          case FOR_WRITE:
              _wfopen_s(&m_pFile, pFileName, TEXT("wb"));
              break;
          case FOR_RE_WR:
              _wfopen_s(&m_pFile, pFileName, TEXT("w+")); // The file must exist
              break;
          default:
              break;
          }
      
          if (m_pFile == NULL)
          {
              /*std::cout << "Can not open the file" << pFileName << std::endl;
              system( "pause" );*/
              CString str = _T("Can not open the file ");
              str.Append(pFileName);
              AfxMessageBox(str);
      
              return FALSE;
          }
      
          m_pBuffer = new TCHAR[MAXCHARS];
      
          return TRUE;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : Release
      **      Author : Barry Tang
      **        Date : 2010/1/8
      ** Description : Free the resurce
      **       Input : None
      **      Output : None
      **---------------------------------------------------------------------------*/
      VOID CUnicodeFile::Release(VOID)
      {
          if (m_pBuffer != NULL)
          {
              delete[] m_pBuffer;
          }
      
          m_strFileName = _T("");
          fclose(m_pFile);
      }
      
      /*---------------------------------------------------------------------------
      **        Name : CheckUnicodeFile
      **      Author : Barry Tang
      **        Date : 2011/3/21
      ** Description : Check if the file is Unicode file
      **       Input : None
      **      Output : TRUE or FALSE
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::CheckUnicodeFile()
      {
          TCHAR ch = fgetwc(m_pFile);
      
          if (ch == 0xfeff)
          {
              return TRUE;
          }
          else
          {
              return FALSE;
          }
      }
      
      /*---------------------------------------------------------------------------
      **        Name : Release
      **      Author : Barry Tang
      **        Date : 2010/1/15
      ** Description : Delete file from disk
      **       Input : fileDel, the CUnicodeFile object
      **      Output : None
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::Delete(CUnicodeFile& fileDel)
      {
          CString strName = fileDel.GetFileName();
          if (strName.IsEmpty())
          {
              AfxMessageBox(_T("The file is release..."));
              return FALSE;
          }
      
          int num = strName.GetLength();
          char* operate = new char[num + 5];
          operate[0] = 'D';
          operate[1] = 'e';
          operate[2] = 'l';
          operate[3] = ' ';
      
          int i;
          for (i = 0; i < num; i++)
          {
              operate[4 + i] = (char)LOWORD(strName.GetAt(i));
          }
      
          operate[4 + i] = '\0';
      
          fileDel.Release();
      
          system(operate);
      
          delete[] operate;
      
          return TRUE;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : Release
      **      Author : Barry Tang
      **        Date : 2010/1/15
      ** Description : Delete file from disk
      **       Input : strFileName, the file name
      **      Output : None
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::Delete(CString strFileName)
      {
          int num = strFileName.GetLength();
          char* operate = new char[num + 5];
          operate[0] = 'D';
          operate[1] = 'e';
          operate[2] = 'l';
          operate[3] = ' ';
      
          int i;
          for (i = 0; i < num; i++)
          {
              operate[4 + i] = (char)LOWORD(strFileName.GetAt(i));
          }
      
          operate[4 + i] = '\0';
      
          system(operate);
      
          delete[] operate;
      
          return TRUE;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : CUnicodeFile
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description : Get the file pointer
      **       Input : None
      **      Output : The file pointer
      **---------------------------------------------------------------------------*/
      FILE* CUnicodeFile::GetFilePointer(VOID)
      {
          return m_pFile;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : GetFlag
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description : Get the file operate flag
      **       Input : None
      **      Output : The flag
      **---------------------------------------------------------------------------*/
      USHORT CUnicodeFile::GetFlag(VOID)
      {
          return m_fileOperateFlag;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : SetFlag
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description : Set the file operate flag
      **       Input : flag, the flag for reading or writing
      **      Output : None
      **---------------------------------------------------------------------------*/
      VOID CUnicodeFile::SetFlag(USHORT flag)
      {
          m_fileOperateFlag = flag;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : ReadLine
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description : Read a line information into the cstr
      **       Input : cstr, the string for getting the string
      **      Output : Succeeded,
      Failed,
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::ReadLine(CString& cstr)
      {
          CString str;
          cstr.Empty();
      
          //The file can not for reading
          if (m_fileOperateFlag == FOR_WRITE)
          {
              return Failed;
          }
      
          do
          {
              if (fgetws(m_pBuffer, MAXCHARS, m_pFile) == NULL)
              {
                  //Modify by Barry on 2011-01-21.
                  if (cstr.IsEmpty())
                  {
                      return Failed;
                  }
                  else
                  {
                      break;
                  }
              }
              str = m_pBuffer;
              cstr.Append(str);
          } while (str.Find(0x000a) == -1);
      
          if (cstr.GetAt(cstr.GetLength() - 1) == 0x000a)
          {
              cstr.Delete(cstr.GetLength() - 1);
          }
          else
          {
              //AfxMessageBox( _T("Read a part of line...") );
          }
      
          if (cstr.GetAt(cstr.GetLength() - 1) == 0x000d)
          {
              cstr.Delete(cstr.GetLength() - 1);
          }
          else
          {
              //AfxMessageBox( _T("Read a part of line...") );
          }
      
          return Succeeded;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : WirteLine
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description : Write the string cstr into the file
      **       Input : cstr, the string will be wrote into the file
      **      Output : Succeeded,Failed,
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::WriteLine(CString cstr)
      {
          //The file can not for writing
          if (m_fileOperateFlag == FOR_READ)
          {
              return Failed;
          }
      
          fputws(cstr.GetBuffer(0), m_pFile);
      
          WriteLineEnd();
      
          return Succeeded;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : WirteSet
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description : Write the set vector into the file
      **       Input : pCStrintSet, the set pointer
      **      Output : Succeeded,Failed,
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::WriteSet(std::set< CString > *pCStringSet)
      {
          //The file can not for writing
          if (m_fileOperateFlag == FOR_READ)
          {
              return Failed;
          }
      
          CString cstr;
      
          std::set< CString >::iterator it;
          for (it = pCStringSet->begin(); it != pCStringSet->end(); it++)
          {
              WriteLine(*it);
          }
      
          return Succeeded;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : WirteLine
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description : Write a line end into the file
      **       Input : None
      **      Output : None
      **---------------------------------------------------------------------------*/
      VOID CUnicodeFile::WriteLineEnd(VOID)
      {
          //The file can not for writing
          if (m_fileOperateFlag == FOR_READ)
          {
              return;
          }
      
          fputwc(0x000d, m_pFile);
          fputwc(0x000a, m_pFile);
      }
      
      /*---------------------------------------------------------------------------
      **        Name : SkipUnicodeFlag
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description : Skip over the Unicode flag
      **       Input : None
      **      Output : Succeeded,Failed,
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::SkipUnicodeFlag(VOID)
      {
          // The file can not for reading
          if (m_fileOperateFlag == FOR_WRITE)
          {
              return Failed;
          }
      
          // Check if the file is Unicode file
          if (!CheckUnicodeFile())
          {
              CString str;
              str = _T("The file \"") + m_strFileName + _T("\" is not Unicode file!");
              AfxMessageBox(str);
      
              return Failed;
          }
      
          fseek(m_pFile, sizeof(TCHAR), SEEK_SET);
      
          return Succeeded;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : SetUnicodeFlag
      **      Author : Barry Tang
      **        Date : 2009/10/15
      ** Description : Set the Unicode flag into the file
      **       Input : None
      **      Output : None
      **---------------------------------------------------------------------------*/
      VOID CUnicodeFile::SetUnicodeFlag(VOID)
      {
          //The file can not for writing
          if (m_fileOperateFlag == FOR_READ)
          {
              return;
          }
      
          fputwc(0xfeff, m_pFile);
      }
      
      /*---------------------------------------------------------------------------
      **        Name : Seek
      **      Author : Barry Tang
      **        Date : 2009/12/11
      ** Description : Move the file pointer to another place
      **       Input : offset, the steps of the moving (Byte)
      origin, move method
      **      Output :  0,-1,
      **---------------------------------------------------------------------------*/
      int CUnicodeFile::Seek(LONG offset, int origin)
      {
          int ret;
      
          switch (origin)
          {
          case SEEK_SET:
              ret = fseek(m_pFile, offset, SEEK_SET);
              break;
          case SEEK_CUR:
              ret = fseek(m_pFile, offset, SEEK_CUR);
              break;
          case SEEK_END:
              ret = fseek(m_pFile, offset, SEEK_END);
              break;
          default:
              break;
          }
      
          return ret;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : WriteBuffer
      **      Author : Barry Tang
      **        Date : 2009/12/11
      ** Description : Write information in the buffer into the file
      **       Input :
      **      Output :
      **---------------------------------------------------------------------------*/
      int CUnicodeFile::WriteBuffer(const void* buffer, size_t itemSize, size_t count)
      {
          return((int)fwrite(buffer, itemSize, count, m_pFile));
      }
      
      /*---------------------------------------------------------------------------
      **        Name : ReadBuffer
      **      Author : Barry Tang
      **        Date : 2009/12/11
      ** Description : Read information into the buffer
      **       Input :
      **      Output :
      **---------------------------------------------------------------------------*/
      int CUnicodeFile::ReadBuffer(void* buffer, size_t itemSize, size_t count)
      {
          return((int)fread(buffer, itemSize, count, m_pFile));
      }
      
      /*---------------------------------------------------------------------------
      **        Name : WriteAWord
      **      Author : Barry Tang
      **        Date : 2009/12/11
      ** Description : Write a char into file
      **       Input : ch, the char
      **      Output :
      **---------------------------------------------------------------------------*/
      VOID CUnicodeFile::WriteAWord(TCHAR ch)
      {
          //The file can not for writing
          if (m_fileOperateFlag == FOR_READ)
          {
              return;
          }
      
          fputwc(ch, m_pFile);
      }
      
      /*---------------------------------------------------------------------------
      **        Name : ReadAWord
      **      Author : Barry Tang
      **        Date : 2009/12/11
      ** Description : Read a char from the file
      **       Input : ch, the parameter to get the char
      **      Output : None
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::ReadAWord(TCHAR& ch)
      {
          //The file can not for writing
          if (m_fileOperateFlag == FOR_READ)
          {
              return Failed;
          }
      
          ch = fgetwc(m_pFile);
      
          if (ch == EOF)
          {
              return Failed;
          }
          else
          {
              return Succeeded;
          }
      }
      
      /*---------------------------------------------------------------------------
      **        Name : TallOffset
      **      Author : Barry Tang
      **        Date : 2009/12/11
      ** Description : Get current pointer position
      **       Input : None
      **      Output : the position
      **---------------------------------------------------------------------------*/
      LONG CUnicodeFile::TellOffset(VOID)
      {
          return ftell(m_pFile);
      }
      
      /*---------------------------------------------------------------------------
      **        Name : GetFileName
      **      Author : Barry Tang
      **        Date : 2010/1/15
      ** Description : Get the file name
      **       Input : None
      **      Output : The file name
      **---------------------------------------------------------------------------*/
      CString CUnicodeFile::GetFileName(VOID)
      {
          return m_strFileName;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : GetFileNameExt
      **      Author : Barry Tang
      **        Date : 2011/3/28
      ** Description : Get the file name extension
      **       Input : None
      **      Output : The file name extension
      **---------------------------------------------------------------------------*/
    
      CString CUnicodeFile::GetFileNameExt(VOID)
      {
          return m_strFileNameExt;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : GetFileAsBuffer
      **      Author : Barry Tang
      **        Date : 2010/1/15
      ** Description : Copy a whole file into this file
      **       Input : fileGet, the file need to copy
      **      Output : TRUE,FALSE,
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::GetFileAsBuffer(CString strFileName)
      {
          HANDLE hFile = CreateFile(strFileName.GetBuffer(0), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
          if (hFile == NULL)
          {
              AfxMessageBox(_T("\"CreateFile\" error!"));
          }
      
          DWORD dwFileLength = GetFileSize(hFile, NULL);
          HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, NULL, NULL, NULL);
          LPVOID lpBase = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
      
          WriteBuffer(lpBase, sizeof(BYTE), dwFileLength);
      
          Flush();
          UnmapViewOfFile(lpBase);
      
          CloseHandle(hMap);
          CloseHandle(hFile);
      
          return TRUE;
      }
      
      /*---------------------------------------------------------------------------
      **        Name : Flush
      **      Author : Barry Tang
      **        Date : 2010/1/15
      ** Description : Flush the buffer information into the file will be written
      **       Input : None
      **      Output : Succeeded,Failed,
      **---------------------------------------------------------------------------*/
      BOOL CUnicodeFile::Flush(VOID)
      {
          //The file can not for writing
          if (m_fileOperateFlag == FOR_READ)
          {
              return Failed;
          }
      
          fflush(m_pFile);
      
          return Succeeded;
      }
    

三、发布

编译这个工程,成功后在解决方案的Debug目录下会找到*.lib文件。

注:如果选择的编译模式是Release,那么Lib文件会生成在Release目录中。

四、使用

1.新建一个可执行工程,如:Win32 Console Application;

新建控制台工程

2.将UnicodeFileLib.lib 和 UnicodeFile.h 两个文件复制到新工程目录中;

3.配置工程属性,在配置属性->链接器->输入页面中,在“附加依赖项”中配置UnicodeFileLib.lib路径;

配置静态库路径

4.将UnicodeFile.h引入新工程中;

5.现在,在新工程里,带有#include "UnicodeFile.h" 的页面能够直接访问CUnicodeFile类了。在main函数中加入如下代码:

// TODO: 在此处为应用程序的行为编写代码。
CUnicodeFile file;
file.Load(_T("abc.txt"), FOR_WRITE);
file.SetUnicodeFlag();
file.WriteLine(_T("12345"));
file.WriteLineEnd();
file.Release();

如需下载完整Demo源码,请访问这里

欢迎邮件讨论。

天花板Email:tianhuaban527@126.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 1、他俩是多么美好 都没有夏的躁动 冬的冷漠 是多么得好 多么多么让人留恋,让人羡慕不已 2、他俩又是多么遗憾 既...
    艾冰茶阅读 174评论 0 0
  • 亲爱的宝贝,今天是8月13日,离你出生还有14天了,爸爸和妈妈特别期待你的到来,爸爸每天问我为什么还不出来,我笑着...
    小猫的梅阅读 61评论 0 0
  • 梦想是什么? 我的兄弟航神曾经不止一次的说:把脚放在油门上,听着汽车引擎活塞运动的声音,这大概就是男人的梦想。 我...
    陆先森阅读 589评论 0 1
  • 南山碧水。热天蒸气,暑地营垒。 方圆尽是忠烈,伤情处,男儿含泪。 不计光阴飞度,教璞玉纯粹。 意在行,远路深浅,上...
    淡淡的生活了阅读 231评论 2 1