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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

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

Q&A

解決済

3回答

4089閲覧

visual studioでstrtokをstrtok_sに変換する方法について

iwa28

総合スコア2

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

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

0グッド

1クリップ

投稿2021/08/14 16:58

現在苦しんで覚えるC言語でC++を学んでいるのですが、strtokをstrtok_sに変換する方法がよくわかりません.
整数をカンマで区切って入力した時、縦方向に入力した順に数値を出力したいです.入力値が10以下の時は入力してないところはNULL状態で出力したいです.一応太字の様に(上:記載されていたコード , 下:自分で変えたコード)しましたが&の後にどの変数を入れたらいいかわかりません.どうかアドバイスをお願いします.

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

void main(){
int i, j, val[10];
char str[32], * ch;

fgets(str, sizeof(str), stdin); **ch = strtok(str, ",\n");** ↓ **ch = strtok_s(str,"\n,&ch);** for (i = 0; i < 10; i++) { if (ch == NULL) { break; } else { val[i] = atoi(ch); } **ch = strtok(NULL, ",\n");** ** ↓**

         ch = strtok_s(NULL, ",\n",&ch);
}
for (j = 0; j < i; j++) {
printf("%d\n", val[j]);
}
return;
}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2021/08/15 01:17

> 苦しんで覚えるC言語でC++を学んでいるのですが C++じゃない...
iwa28

2021/08/15 18:02

すいません、ありがとうございます!
guest

回答3

0

入力値が10以下の時は入力してないところはNULL状態で出力したいです.

入力の個数が 10以下なのではありませんか?
入力の値は 10より大きくてもいいんですよね。100,200,300 とか。

strtok_s の第3引数には、char *p; と宣言して、&p を与えてください。

C++ なら istringstream と getline が使えます。

C++

1#include <iostream> // cin, cout, endl 2#include <string> // getline, stoi 3#include <sstream> // istringstream 4using namespace std; 5 6int main() 7{ 8 string line, str; 9 getline(cin, line); 10 istringstream iss(line); 11 while (getline(iss, str, ',')) { 12 int i = stoi(str); 13 cout << i << endl; 14 } 15}

strtok と違って、11,,,,22,33 などはダメです。

投稿2021/08/15 07:11

編集2021/08/15 07:13
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iwa28

2021/08/15 18:09

すいません、そーですね入力個数が10です。。ありがとうございました!
guest

0

[回答ではありません] せっかくのC++なんだから、C++らしく(?)書いてみた:

C++

1#include <iostream> 2#include <string> 3#include <vector> 4 5int main() { 6 using namespace std; 7 vector<int> val; 8 9 string line; 10 getline(cin, line); // 標準入力から一行読み込む 11 12 const string delimiter = ",\n"; // 区切り文字 13 string::size_type bpos = 0; 14 string::size_type epos = 0; 15 // bpos : eposを起点とし、delimiterに含まれない最初の文字の位置 16 // epos : bposを起点とし、delimiterに含まれる最初の文字の位置 17 // 切り出すtokenは 範囲 [bpos, epos) となる 18 while ( (bpos = line.find_first_not_of(delimiter, epos)) != string::npos ) { 19 std::string token = line.substr(bpos, (epos = line.find_first_of(delimiter, bpos))-bpos); 20 val.emplace_back(std::stoi(token)); // tokenをintに変換しvalの末尾に挿入 21 } 22 23 // できたかな? 24 for ( auto item : val ) { 25 std::cout << item << std::endl; 26 } 27}

[別解] 正規表現使うと楽(オーバースペックかしら...)

C++

1#include <iostream> 2#include <regex> 3#include <string> 4#include <vector> 5 6int main() { 7 using namespace std; 8 9 vector<int> val; 10 11 string line; 12 getline(cin, line); 13 regex re("[^,\n]+"); // ,でも改行でもない文字のひとつ以上の連続 14 15 for ( sregex_iterator it(line.begin(), line.end(), re), end; it != end; ++it) { 16 val.push_back(stoi(it->str())); 17 } 18 19 for ( auto item : val ) { 20 cout << item << endl; 21 } 22}

投稿2021/08/15 02:48

編集2021/08/15 08:50
episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iwa28

2021/08/15 18:04

ありがとうございます!まだ理解が難しいですが写してみます!
guest

0

ベストアンサー

strtok_sはstrtokに似ていますが、単純な置き換えでは動きません。
Microsftのリファレンスに簡単なサンプルがありますが、質問者さんのコードを直すとすると、

c

1void main(){ 2 int i, j, val[10]; 3 char str[32], *ch; 4 char *next_token = NULL; /* 追加 */ 5 6 fgets(str, sizeof(str), stdin); 7 8 ch = strtok_s(str,"\n”,&next_token); 9 10 for (i = 0; i < 10; i++) { 11 if (ch == NULL) { 12 break; 13 } 14 else { 15 val[i] = atoi(ch); 16 } 17 ch = strtok_s(NULL, "\n",&next_token); 18 } 19 for (j = 0; j < i; j++) { 20 printf("%d\n", val[j]); 21 } 22 return; 23}

となります。

デリミタで分割されたトークンを受け取るポインタと、現在の分轄位置を保持するポインタは別の変数にしておかないと、正常に動作しません。
上記ソースはstrtokとstrtok_sを置き換えただけで意図した通りに動作するかまでは保証できませんので、デバッグは適宜行ってください。

投稿2021/08/14 17:52

編集2021/08/16 00:02
KoichiSugiyama

総合スコア3041

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iwa28

2021/08/15 18:07

非常にわかりやすくて助かりました!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問