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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

2293閲覧

ダブルクオーテーションを含む文字列をパースするコードの作成

ijuya_yika

総合スコア50

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/04/24 22:46

編集2018/04/25 00:20

前提・実現したいこと

ダブルクオーテーションを含む文字列をパースした後、文字列の配列に文字を格納するコードの作成

例: 
cmd = "aaa bbb " ccc \t\n ddd eee " "をパース後
args[0] = "aaa", parsedlist[1] = "bbb", parsedlist[2] = " ccc \t\n ddd eee "となるようにしたい

試したこと

cmdを一文字ずつ見ていき"が発見されるまではスペースで文字を区切り
"が発見された後は終端の"が発見されるまで"区切り、という感じで実装してみたのですが
17行目でseg fault 11 でエラー終了します

C

1#include <stdio.h> 2#include <string.h> 3 4int main(){ 5 6 char* cmd = "hello world \" and hello universe \" "; 7 char args[10][100]; 8 char* check; 9 char p; 10 int quotationFound = 0; 11 12 int i=0; 13 int j=0; 14 for(; cmd[i]!='\0'; ++i){ 15 p = cmd[i]; 16 if(p=='\"') !quotationFound; 17 args[i][j++] = p;//seg fault 18 if(p==' ' && !quotationFound){ i++; j=0; } 19 } 20 21 return 0; 22} 23

コメントを受けて訂正した所無事動かすことができましたm(_ _)m
修正後コード

C

1#include <stdio.h> 2#include <string.h> 3 4int main(){ 5 6 char* cmd = "hello world \" and hello universe \" "; 7 char args[10][100]; 8 char* check; 9 char p; 10 int quotationFound = 0; 11 12 int i=0; 13 int j=0; 14 int k=0; 15 for(; cmd[i]!='\0'; i++){ 16 p = cmd[i]; 17 if(p=='\"') 18 quotationFound = !quotationFound; 19 20 args[k][j++] = p; 21 22 printf("p is now : %c\n", p); 23 24 if(p==' ' && !quotationFound){ 25 k++; j=0; 26 } 27 } 28 29 printf("args[0] : %s\n", args[0]); 30 printf("args[1] : %s\n", args[1]); 31 printf("args[2] : %s\n", args[2]); 32 printf("args[3] : %s\n", args[3]); 33 34 return 0; 35} 36

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

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

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

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

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

guest

回答3

0

他に指摘があるように、以下は意味がありません。

if(p=='"') !quotationFound;

またcmdのカウンタとargsのカウンタ(変数i)を共用しているので、argsに正しく格納されません。

args[i][j++] = p;

もうひとつカウンタが必要になります。
cmd[カウンタ1]
args[カウンタ2][カウンタ3]

以上を踏まえて修正してみたのが下記です。
但し、ダブルクォーテーション前の文字列の区切りに空白が2文字以上あると正しく動かない問題があるので、そういう文字列が格納される可能性があるなら、修正が必要になります。

c

1#include <stdio.h> 2#include <string.h> 3 4int main(){ 5 6 char* cmd = "hello world \" and hello universe \" "; 7 char args[10][100]; 8 char* check; 9 char p; 10 int quotationFound = 0; 11 12 int i=0; 13 int j=0; 14 int k=0; 15 for(; cmd[i]!='\0'; ++i){ 16 p = cmd[i]; 17 if(p == '\"') quotationFound = !quotationFound; 18 if(p == ' ' && !quotationFound){ 19 args[j][k++] = '\0'; // NULL終端 20 j++; 21 k=0; 22 } else { 23 args[j][k++] = p; 24 } 25 } 26 // 確認 27 for(i = 0; i < 3; i++){ 28 printf("[%d]%s\n", i, args[i]); 29 } 30 return 0; 31}

投稿2018/04/25 00:21

ttyp03

総合スコア16996

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

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

ttyp03

2018/04/25 00:21

あれ解決済みになってしまった。 誰もカウンタ不足のことを指摘していないのに。。。
ijuya_yika

2018/04/25 00:34

詳細コメント&サンプルコードまで頂いてありがとうございますm(_ _)m ご指摘の通りカウンタが共有になってしまいp='h'のまま∞ループになってしまっていました(汗) コード参考にさせていただきます!! それからコメント拝見する前にすれ違いでベストアンサーを選んでしまい申し訳ありませんでした????
ttyp03

2018/04/25 00:39

修正後のコード見ました。 argsの方、文字列の最後にNULLを格納してないので、出力で文字化けしてますね。 あとダブルクォーテーション前の文字列に空白を含んでしまっているようです。 > それからコメント拝見する前にすれ違いでベストアンサーを選んでしまい申し訳ありませんでした???? ベストアンサーはあとからでも変更できるんやで(強要はしませんw)
guest

0

ベストアンサー

まず、目に付いた点を、

if(p=='"') !quotationFound;

このコードは何もしていません。

char* cmd = "hello world " and hello universe " ";
char args[10][100];

(中略)

for(; cmd[i]!='\0'; ++i){

(中略)

args[i][j++] = p;//seg fault

cmdを最後まで舐めたら、iはあきらかに10以上になります。

for(; cmd[i]!='\0'; ++i){

(中略)

if(p==' ' && !quotationFound){ i++; j=0; }

ループの中でさらにi++をするとcmd[i]=='\0'を読み飛ばす危険があります。

投稿2018/04/24 23:03

hichon

総合スコア5737

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

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

ijuya_yika

2018/04/25 00:21

ありがとうございます、お陰で無事動かすことができましたm(_ _)m
guest

0

if(p=='"') !quotationFound;

「"が見つかったら quotationFound を反転する」なら

if(p=='"') quotationFound = !quotationFound;

投稿2018/04/24 22:51

episteme

総合スコア16614

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

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

ijuya_yika

2018/04/25 00:21

ありがとうございます、すごく基本的なことを忘れていましたw 無事動かすことができましたm(_ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問