字符串类型的转换

时间:2015-12-17 08:56:54

标签: c++ c++builder

C ++中有很多字符串类型:WideString,UnicodeString,String,wstring,string,AnsiString,Variant

在我的代码中有很多转换,比如

sc(s1,s2);      // s1 = convert to, s2 = convert from

这就是一个词:令人困惑!

是否有一种简单的方法来处理所有字符串转换,其中一个帮助类从不再考虑如何将一个字符串类型转换为另一个字符串类型,如:

package com.example.arduinoandroidledtesting;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.ToggleButton;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

         /********************************/
        /*    Define all the buttons    */
       /********************************/
       Switch led1 = (Switch) findViewById(R.id.Led1);
       ToggleButton led2 = (ToggleButton) findViewById(R.id.Led2);
       Button led3 = (Button) findViewById(R.id.Led3);

       /*******************************************************/
       /*  Set an onclick/onchange listener for every button  */
      /*******************************************************/

      led1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
          public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
              if (isChecked) {
                  /* Switch is led 1 */
                  new Background_get().execute("led1=1");
              } else {
                  new Background_get().execute("led1=0");
              }
          }
      });


      led2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
          public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
              if(isChecked) {
                  /* Toggle button is led 2 */
                  new Background_get().execute("led2=1");
              } else {
                  new Background_get().execute("led2=0");
              }
          }
      });


      led3.setOnTouchListener(new View.OnTouchListener() {
          @Override
          public boolean onTouch(View v, MotionEvent event) {
              if (event.getAction() == MotionEvent.ACTION_DOWN) {
                  /* button is led 3 */
                  new Background_get().execute("led3=1");
              } else if (event.getAction() == MotionEvent.ACTION_UP) {
                  new Background_get().execute("led3=0");
              }
              return true;
          }
      });
  }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

      /*****************************************************/
    /*  This is a background process for connecting      */
   /*   to the arduino server and sending               */
  /*    the GET request withe the added data           */
 /*****************************************************/

 private class Background_get extends AsyncTask<String, Void, String> {
     @Override
     protected String doInBackground(String... params) {
         try {
             /* Change the IP to the IP you set in the arduino sketch */
             URL url = new URL("http://192.168.1.177/?" + params[0]);
             HttpURLConnection connection = (HttpURLConnection) url.openConnection();

             BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
             StringBuilder result = new StringBuilder();
             String inputLine;
             while ((inputLine = in.readLine()) != null)
                 result.append(inputLine).append("\n");

             in.close();
             connection.disconnect();
             return result.toString();

         } catch (IOException e) {
             e.printStackTrace();
         }
         return null;
     }
 }
}

{{1}}

5 个答案:

答案 0 :(得分:0)

我主要是老式的C89-C99用户,因此我建议使用一些宏。正如alredy建议的那样,模板将更多更优雅和安全(因为将编译器跟踪错误),但只是让你的武器选择。

#define CONV_TO_WSTRING(s1) ( wstring(s1.str().c_str()).c_str()).c_str()

例如

然后在使用中你有:

s1 = CONV_TO_WSTRING(s2);

答案 1 :(得分:0)

创建一个可以处理所有可能转换的包装类。您可以使用 模板类,但请注意,您必须制作其他模板 专业化,因为大多数这些转换不能用a表示 通用方式。例如,您可以轻松地从WideString转换为UnicodeString 使用强制转换,但不能简单地将wstring强制转换为string。对于类型 可以投射,你可以使用通用部分:

template <class TypeFrom, class TypeTo>
TypeTo convert(const TypeFrom &from)
{
    return static_cast<TypeTo>(from);
}

但这不适用于将wstring转换为string。你需要一个模板 专业化:

template <>
std::string convert<std::wstring, std::string>(const std::wstring &from)
{
    return std::string(from.begin(), from.end());
}

在这里列出所有组合是不可能的,你必须要照顾它。这里 是可以帮助进行某些转换的链接:

https://msdn.microsoft.com/en-us/library/ms235631.aspx

答案 2 :(得分:0)

经过一些实验,我决定使用重载函数!

如果我使用模板,我的代码如下所示:

string  s = convert<wstring,string> (wstring(L"hello"));

问题是我必须编写我想要转换的类型。我为什么要那样做?编译器知道类型!

如果我使用重载函数

std::string convert(const std::wstring &from)
{
  return std::string(from.begin(), from.end());
}

std::wstring convert(const std::string &from)
{
  return std::wstring(from.begin(), from.end());
}

我的代码看起来如此:

string str2 = convert(wstring(L"hello"));

这就是我喜欢的方式:永远不要重复自己。偷懒。尽可能简单。 ^^

答案 3 :(得分:0)

这是我目前解决转换问题的方法

std::string convert1(const std::wstring &from) {
  return std::string(from.begin(), from.end()); }

std::string convert1(const UnicodeString &from) {        // String = UnicodeString
  wstring strTemp = from.c_str();
  return std::string(strTemp.begin(), strTemp.end()); }

std::string convert1(const WideString &from) {
  wstring strTemp = from.c_bstr();
  return std::string(strTemp.begin(), strTemp.end()); }


std::wstring convert2(const std::string &from) {
  return std::wstring(from.begin(), from.end()); }

std::wstring convert2(const UnicodeString &from) {
  wstring strTemp = from.c_str();
  return std::wstring(strTemp.begin(), strTemp.end()); }

std::wstring convert2(const WideString &from) {
  wstring strTemp = from.c_bstr();
  return std::wstring(strTemp.begin(), strTemp.end()); }


UnicodeString convert3(const std::string &from) {
  wstring strTemp(from.begin(), from.end());
  return UnicodeString(strTemp.c_str()); }

UnicodeString convert3(const std::wstring &from) {
  return UnicodeString(from.c_str()); }

UnicodeString convert3(const WideString &from) {
  return UnicodeString(from.c_bstr()); }


WideString convert4(const std::string &from) {
  wstring strTemp(from.begin(), from.end());
  return WideString(strTemp.c_str()); }

WideString convert4(const std::wstring &from) {
  return WideString(from.c_str()); }

WideString convert4(const UnicodeString &from) {
  return WideString(from.c_str()); }



wchar_t* convert5(const std::string &from) {
  static wstring strTemp;
  strTemp.clear();
  strTemp.assign(from.begin(), from.end());
  return (wchar_t*) strTemp.c_str(); }

wchar_t* convert5(const std::wstring &from) {
  return (wchar_t*) from.c_str(); }

wchar_t* convert5(const UnicodeString &from) {
  return from.c_str(); }

wchar_t* convert5(const WideString &from) {
  return from.c_bstr(); }

用法:

  std::string   s1  = convert1 (wstring       (L"Hallo1" ));
  std::string   s2  = convert1 (UnicodeString (L"Hallo2" ));
  std::string   s3  = convert1 (WideString    (L"Hallo3" ));
  std::wstring  s4  = convert2 (std::string   ( "Hallo4" ));
  std::wstring  s5  = convert2 (UnicodeString (L"Hallo5" ));
  std::wstring  s6  = convert2 (WideString    (L"Hallo6" ));
  UnicodeString s7  = convert3 (std::string   ( "Hallo7" ));
  UnicodeString s8  = convert3 (std::wstring  (L"Hallo8" ));
  UnicodeString s9  = convert3 (WideString    (L"Hallo9" ));
  WideString    s10 = convert4 (std::string   ( "Hallo10"));
  WideString    s11 = convert4 (std::wstring  (L"Hallo11"));
  WideString    s12 = convert4 (UnicodeString (L"Hallo12"));

  Memo->Lines->Add(convert5(s1));
  Memo->Lines->Add(convert5(s2));
  Memo->Lines->Add(convert5(s3));
  Memo->Lines->Add(convert5(s4));
  Memo->Lines->Add(convert5(s5));
  Memo->Lines->Add(convert5(s6));
  Memo->Lines->Add(convert5(s7));
  Memo->Lines->Add(convert5(s8));
  Memo->Lines->Add(convert5(s9));
  Memo->Lines->Add(convert5(s10));
  Memo->Lines->Add(convert5(s11));
  Memo->Lines->Add(convert5(s12));

结果:

Hallo1
Hallo2
Hallo3
Hallo4
Hallo5
Hallo6
Hallo7
Hallo8
Hallo9
Hallo10
Hallo11
Hallo12

答案 4 :(得分:-1)

使用所有可能的转换制作您自己的template class

在模板中,您应该使用类型安全转换,例如static_cast

然后只有一次令人困惑......

修改

也许它可能是这样的:

template <typename T>
T convert(T x)
{
  T value;
  value = static_cast<T>(x);
  return value;
}

(我没有进入实现,因为这些是我不知道的变量类型。这是我尝试这样做的方式)