ページ 11

コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

Posted: 2010年6月12日(土) 21:39
by shiro4ao
コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

例)
111 2222 33

111
2222
33
のようにしたいです。
で配列に入れて、簡単にアクセス出来るようになりたいです。

=================ここから==============================
#include <stdio.h>
#include <windows.h>

int main(void){

wchar_t buf[1024];
int nNumArgs,i;

gets(buf);
PWSTR *ppArgv = CommandLineToArgvW(buf,&nNumArgs);

for(i;i<nNumArgs;i++){
printf("%s\n",(char)*ppArgv[0]);
}

return 0;
}
=============ここまで======================================

ところがこんなエラーが出てきます。
エラー E2034 divcmdl.cpp 10: 'wchar_t *' 型は 'char *' 型に変換できない(関数 main() )
エラー E2342 divcmdl.cpp 10: パラメータ '__s' は char * 型として定義されているので wchar_t * は渡せない(関数 main() )
エラー E2034 divcmdl.cpp 13: 'wchar_t *' 型は 'char' 型に変換できない(関数 main() )

CommandLineToArgvW()がUnicode版なのでまずいのでしょうか・・・

何別の方法があるのでしょうか・・・?

Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

Posted: 2010年6月12日(土) 21:52
by たかぎ
C++のようですが、それなら...

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include <algorithm>

int main()
{
std::vector<std::string> v;

std::string buffer;
std::getline(std::cin, buffer);
std::istringstream iss(buffer);
std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter(v));

std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

return 0;
}

これでよくないですか?
配列ではなくvectorですが、やりたいことはこれでできるはずです。

Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

Posted: 2010年6月12日(土) 22:05
by shiro4ao
素早いご回答ありがとうございます!
C++は使ったことがないので勉強してみようとおもいます・・・
難しいですね・・・

関数にして、変換前の文字列へのポインタ、配列の数へのポインタをもらい、
変換後の文字列の配列を戻り値にするような関数を作りたかったのです。

C++だと関数は使えないのでしょうか・・・・?

Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

Posted: 2010年6月12日(土) 22:18
by たかぎ
> C++は使ったことがないので

いや、C++を使っていると思いますよ。

> 関数にして、変換前の文字列へのポインタ、配列の数へのポインタをもらい、
> 変換後の文字列の配列を戻り値にするような関数を作りたかったのです。

↓でよいのでは?

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include <algorithm>

std::vector<std::string> split(const std::string* s, std::size_t* n = 0)
{
std::istringstream iss(*s);
std::vector<std::string> v;
std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter(v));
if (n != 0)
*n = v.size();
return v;
}

int main()
{
std::string buffer;
std::getline(std::cin, buffer);
std::vector<std::string> v = split(&buffer);
std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}

> C++だと関数は使えないのでしょうか・・・・?

そんなことはありません。

Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

Posted: 2010年6月12日(土) 23:38
by shiro4ao
PWSTR split(char buf, int *n)のようにchar型の文字列を配列に
変えて戻り値にして、配列の個数をint型で渡したかったのですが、
うまくいきませんでした。もう少し勉強してみます。

Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

Posted: 2010年6月13日(日) 07:24
by shiro4ao
以下のようなコードが
エラーに成ります・・・・
どこが良くなかったのでしょう…?


エラー E2034 divcmdl.cpp 11: 'int' 型は 'char *' 型に変換できない(関数 CmdTok(ch
ar *,char *,int,char *) )
エラー E2342 divcmdl.cpp 11: パラメータ '__s1' は char * 型として定義されている
ので char は渡せない(関数 CmdTok(char *,char *,int,char *) )
エラー E2034 divcmdl.cpp 11: 'char *' 型は 'char' 型に変換できない(関数 CmdTok(c
har *,char *,int,char *) )
エラー E2034 divcmdl.cpp 12: 'char *' 型は 'char' 型に変換できない(関数 CmdTok(c
har *,char *,int,char *) )


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//buf コマンドライン、div 区切り文字、n 何番目かのコマンドライン、 ret 切り出されたコマンドライン
int CmdTok(char *buf ,char *div,int n ,char *ret){
int i;

*ret = strtok(buf,div);
for(i=0;i<n-1;i++) *ret = strtok(NULL,div);

return 0;
}



/* main */
int main(void) {
char s1[1024],cmd[1024];

gets(s1);

CmdTok(s1," ",2,cmd);

printf("%s\n", cmd);

return 0;
}

Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

Posted: 2010年6月13日(日) 07:44
by シエル
ざっとしか見てませんが…

char *retはポインタですよね?

じゃあ *ret = strtok(buf,div)の*は要らないのでは?

Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

Posted: 2010年6月13日(日) 08:07
by shiro4ao
ありがとうございます。
うっかりしてました…

/* header files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//buf ごっちゃのコマンドライン、div 区切り文字、n 何番目かのコマンドライン、 ret 切り出されたコマンドライン
int CmdTok(char *buf ,char *div,int n ,char *ret){
int i;
ret = strtok(buf,div);
for(i=0;i<n-1;i++) ret = strtok(NULL,div);
return 0;
}

int main(void) {
char s1[1024],*code;

  gets(s1);

CmdTok(s1," ",4,code);

printf("cmdtok: %s\n", code);

return 0;
}

コンパイルはできたんですが、今度はトークン切り出しが出来ていないようです。
111 222 333 444 555 666 777
を入力しても、
cmdtok:
としか出てきませんでした・・・・

Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

Posted: 2010年6月13日(日) 17:28
by シエル
すいません。イメージってこんな感じですか?


/* header files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//buf ごっちゃのコマンドライン、div 区切り文字、n 何番目かのコマンドライン、 ret 切り出されたコマンドライン
int CmdTok(char *buf ,char *div,int n ,char **ret){
int i;
*ret = strtok(buf,div);
for(i=0;i<n-1;i++) *ret = strtok(NULL,div);
return 0;
}

int main(void) {
char s1[1024],*code;

gets(s1);

CmdTok(s1," ",3,&code);

printf("cmdtok: %s\n", code);

return 0;
}

Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

Posted: 2010年6月15日(火) 20:10
by shiro4ao
>for(i=0;i<n-1;i++) *ret = strtok(NULL,div);

なるほど!分かりました!
ありがとうございました。