質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.54%

  • C++

    4316questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • オブジェクト指向

    321questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • char

    32questions

    charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

  • integer

    8questions

    integerは、一般的に整数を表します。プラスやマイナス、ゼロもなりうる全ての数です。(例 : -2, -1, 0, 1, 2...)

char文字列をunsigned int型のクラスメンバに渡して実行

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,006

yamayamak

score 77

前提・実現したいこと

C++のプログラムを記載しています。

あるchar型のdata1にクラスメンバの「unsigned int buf[]」に渡して実行したいです。

class testObj
{
public:
void sendData(unsigned int buf[], int len);
}

こんな感じで書いたりしているのですが、よくわからないです。

  char data1[20] = "0x123,0x456,0x789";

  testObj test();
  int objSize = sizeof(data2) / sizeof(unsigned int);

  test.sendData((unsigned int)data1[], objSize );

ちなみに、char型ではなく

unsigned int data1[] = {0x123,0x456,0x789};

で定義した場合は

test.sendData( data1, objSize );

で問題なく動いております。
現状はArduinoのEEPROMにあるデータが文字列で保存されておりchar型で読み出して利用したいということになります。

すみませんがHelpしてください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • ozwk

    2017/02/01 11:28

    そもそもなんでEEPROMに文字列なんかで保持しているんですか?

    キャンセル

  • yamayamak

    2017/02/01 12:07

    センサーのライブラリが文字列(0x123,0x456)で出力しています。確かにライブラリの修正もありえますが、さっぱりでしたし保証もされないので、unsigned int型へ変更するのが良いと考えている次第です。

    キャンセル

  • ozwk

    2017/02/01 12:12

    本筋とは離れますが、可能であればそのライブラリを教えてもらえますか?

    キャンセル

回答 2

+1

こんにちは。

カンマ区切りの0以上の10進数をunsigned intの並びへ変換して、sendData()を呼び出すのであれば、下記で出来ます。

#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>

void sendData(unsigned int buf[], int len, int hz)
{
    for (std::size_t i=0; i < len; ++i)
    {
        if (i) std::cout << ", ";
        std::cout << "0x" << std::hex << std::setfill('0') << std::setw(8)
                  << buf[i];
    }
}

int main()
{
    std::stringstream ss("123,456,789");
    std::vector<unsigned int> buffer;

    while(ss.good())
    {
        unsigned int data;
        ss >> data;
        if (ss.fail())
    break;
        buffer.push_back(data);

        char delim=0;
        ss >> delim;
        if (delim != ',')
    break;
    }

    sendData(&buffer[0], buffer.size(), 38);

    return 0;
}

数値定数は、0xを付けると16進数表現ができますが、文字列に"0x"を付けてもコンピュータにとっては文字列のままです。数値に変わるわけではありません。文字列を数値へ変換処理する必要が有ります。

変換方法には実に様々な方法がありますが、お手軽なstring streamを使ってみました。
std::cinから読み込む時と同じ処理で出来ます。

バッファの組み立てはstd::vectorを使ってみました。効率は悪いですが、お手軽です。

sendData()でデバック用に0x付きの16進数表現で表示してみました。これは人が目で見て分かりやすいようにするためです。マニュピュレータを使ってます。


【追加】
コメントにも書きましたが、数値表現についてはWikipedia等の記事を参考にされて下さい。
文字列からの変換サンプル・ソースはググってみたけど標準ライブラリを使わないケースを見つけることができませんでした。アルゴリズムを提示しているサイトは、数学的(文字列と数値を区別しない)に書いているところばかりでしたので、更に混乱しそうです。

簡単ですの書いてみました。エラー処理をほとんどしていませんので、想定外の文字列がdata1に入っているとエラーにならずに誤動作します。

void sendData(unsigned int buf[], int len, int hz);

int main()
{
    char data1[20] = "123,456,789";
    unsigned int buf[100];

    int index=0;
    buf[index]=0;
    for (char* p=data1; *p != 0; ++p)
    {
        if (*p == ',')
        {
            ++index;
            buf[index]=0;
    continue;
        }
        else if ((*p < '0') || ('9' < *p))
    continue;

        buf[index] *= 10;
        buf[index] += *p-'0';
    }

    sendData(buf, index+1, 38);

    return 0;
}

#include <iostream>
#include <iomanip>

void sendData(unsigned int buf[], int len, int hz)
{
    for (std::size_t i=0; i < len; ++i)
    {
        if (i) std::cout << ", ";
        std::cout << "0x" << std::hex << std::setfill('0') << std::setw(4)
                  << buf[i];
    }
}

EEPROMへ書き込むフォーマットに"0x"が追加されてますね。面倒なのでそれには対応していません。ご自身で改造されてみて下さい。

しかし、EEPROMへ書き込むフォーマットを選択できるのでしたら、最初からunsigned int buf[SIZE];形式で書いておけば楽と思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/01 10:35

    すみません、質問が複雑になっておりましたのでシンプルに質問させて頂きました。
    Arduinoを用いた開発ですので、メモリがなくIncludeがほとんどできない状況です。
    すみませんが、初心者向けに回答頂けますと非常に幸いです。

    キャンセル

  • 2017/02/01 10:46

    回答、大変ありがとうございます。ただ、データはEEPROMに入っており、char data1[20]型に読み出したいと思っております。そちらから、「unsigned int buf[]」へは可能でしょうか?
    すみませんが、よろしくお願いします。

    キャンセル

  • 2017/02/01 11:23

    私はArduinoを把握していないので具体的なことは分かりませんが、Wikipediaをみると「C++風のArduino言語」と書かれてました。
    https://ja.wikipedia.org/wiki/Arduino#Arduino_IDE

    C++標準ライブラリを使えない場合はかなり厳しいです。
    コンピュータの数値表現方法はご存知でしょうか? もし、知らないようでしたその辺りから学習されないとちょっと無理です。
    https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%81%AE%E6%95%B0%E5%80%A4%E8%A1%A8%E7%8F%BE

    > char data1[20]型に読み出したいと思っております。そちらから、「unsigned int buf[]」へは可能でしょうか?

    NULLで終端する形式(C言語形式)でdata1[20]へ読み込んでしまえば、回答で示した考え方で処理できます。
    標準ライブラリを一切使えない場合は、自力で文字列を数値へ変換するプログラムを書くことになります。難しいものではありませんが、数値表現や文字列についてきちんと理解していないと厳しいです。

    キャンセル

  • 2017/02/01 11:38

    回答大変ありがとうございます。
    私の理解では、unsigned int?2バイトの領域なので負の値がない最大65535が入る領域というレベルの理解です。16bitを0/1で表現できるので、メモリ位置などにも利用できる?ということくらいしか理解できておりません。
    ご指摘の通り、自力で文字列を数値へ変換するプログラムを書くしかないということでしたら、そのようにしたいと考えますが、参考になるURLなどありましたら、アドバイス頂きたいです。
    ROMには文字列で保存されておりますので、「unsigned int buf[]」は16bit単位で0/1に置きなおすということでしょうか?
    0x123,0x456・・・というのはbit列で置き換えると。。。ということを考える必要があるということですね。確かにハードルが高そうですが何としても超えないといけない壁ですので、すみませんがアドバイスお願いします。

    キャンセル

  • 2017/02/01 11:51

    回答に追記します

    キャンセル

  • 2017/02/01 12:13

    回答大変ありがとうございます。参考にさせて頂きます。
    いろいろ助かりました。まずはやってみます!

    キャンセル

  • 2017/02/01 13:33

    非常にありがとうございます・ただ、Arduinoでの実装が難しかったので、個別に数値に変更して代入する方法で解決できました。いろいろ本当にありがとうございました。おかげさまで無事に解決できましたので、ありがとうございました。

    キャンセル

checkベストアンサー

0

Arduinoに詳しくないので手順のみ示します。

各関数の使い方は、ArduinoやC言語の入門サイトなどを参考にしてください。

以下はstrtokでカンマ毎に文字列を切り出す例です。

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    char str[] = "123,012";
    char *tok = strtok( str, "," );
    while( tok){
        printf( "%d\n", strtol( tok , NULL, 16));
        tok = strtok( NULL, "," );
    }
    return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/01 11:48

    回答大変ありがとうございます。参考になります!

    char data1[20] = "0x123,0x456,0x789"

    上記をカンマで分けれたとして、unsigned int型に置き換える?というのが理解できておりません。
    例えば上記の123というが、16進数だとして、10進数になると291です。

    unsigned int data2[];

    に置き換えたい場合は、

    data2[0] = 291; // 0x123
    data2[1] = 1110; // 0x456
    ・・・

    というような処理を記載すればよいでしょうか?それとも、Bit列か何かで置き換える様なことが必要でしょうか?また、そもそも考え方が違いますでしょうか?

    よろしくお願いします。

    キャンセル

  • 2017/02/01 11:59

    strtol関数は「0x123」のような文字列を「291」という数値に変換します。
    つまりdata2[0] = stortol( "0x123",0,16);のようにすればよいです。

    キャンセル

  • 2017/02/01 12:15

    ありがとうございます。そういうことですか!
    それなら、こちらでもプログラムを書けそうな気がしてきました。
    まずは実装してみますので、また、うまくいけば回答させて頂きます。

    キャンセル

  • 2017/02/01 13:31

    非常にありがとうございます。以下で解決できました!
    tmpIrsig[4]はtmpIrsig[6]として"0x"も付与してもどちらでも結果は同じでした。
    -----------------------------------
    char irsig[30] = "123,456,789,012";
    unsigned int irData[10] = {};
    char tmpIrsig[4];
    long temNum;
    uint8_t datanum = 0;

    for (int i = 0; i <= sizeof(irsig); i=i+4 ) {
    if ( i == 0 || irsig[i-1] == ',' ) {
    Serial.print("DEBUG:");
    Serial.print(i);
    Serial.print(":");
    tmpIrsig[0] = irsig[i];
    tmpIrsig[1] = irsig[i+1];
    tmpIrsig[2] = irsig[i+2];
    tmpIrsig[3] = '\0';
    temNum = strtol(tmpIrsig, NULL, 16);
    irData[datanum] = temNum;
    datanum++;
    Serial.print(tmpIrsig);
    Serial.print(":");
    Serial.print(datanum);
    Serial.print(":");
    Serial.println(temNum);
    }
    }
    --------------------------------------

    キャンセル

  • 2017/02/01 13:49

    解決してよかったです。
    例を追記しました。strtokを使えばさらに簡潔に記述できます。
    機会があれば挑戦してみてください。

    キャンセル

  • 2017/02/01 13:52

    なるほど、なるほど、勉強になります。
    そちらに書き換えます!

    キャンセル

同じタグがついた質問を見る

  • C++

    4316questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • オブジェクト指向

    321questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • char

    32questions

    charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

  • integer

    8questions

    integerは、一般的に整数を表します。プラスやマイナス、ゼロもなりうる全ての数です。(例 : -2, -1, 0, 1, 2...)