[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 2chのread.cgiへ]
Update time : 05/09 13:42 / Filesize : 213 KB / Number-of Response : 830
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

C言語なら俺に聞け(入門篇) Part 27



1 名前:デフォルトの名無しさん [2008/04/29(火) 09:44:57 ]
言語の入門者向け解説スレです。
・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 26
pc11.2ch.net/test/read.cgi/tech/1206196600/
過去スレ
makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000

教えて欲しいのではなく丸投げしたいならこちらへ
C/C++の宿題を片付けます 105代目
pc11.2ch.net/test/read.cgi/tech/1208268461/


528 名前:516 mailto:sage [2008/05/10(土) 08:23:53 ]
レス色々ありがとう。

自分はプログラミングはちょっとやったことありますが、C言語に
ついてはさっぱりです。プログラミング言語Cがあれば何もいらない、
って話を聞いたんですけど、ちょっと古い本だしどうなんだろうなぁと。

だけど、薄い本なんで、これでC言語が概観できるというなら欲しいと
思ってます。

>>523
こういうスレがあったんですね。ありがとうございます。

529 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 11:02:19 ]
ただの趣味だからって、効率悪くてもなるべく自作するようにしてる俺エドモンド本田

530 名前:デフォルトの名無しさん [2008/05/10(土) 16:04:28 ]
複数行文字列(100行以上)を標準出力に書き出す際、
\ で複数行まとめて書くとインデントが使えず見辛い。
別の方法を考えたところ

1) printfで一行ずつ
 printf("黒い0服\n");
 printf("お茶を1杯\n");

2) fputsで一行ずつ
 fputs("赤い2んじん\n", stdout);
 fputs("橙色の3かん\n", stdout);

3) 配列に格納してwhile puts
 char *memo[] = {
  "黄色い4んごう",
  "五月みどり",
  ""
 };
 char **memop = memo;
 while(**memop)
 puts(*memop++);


(1) や (2) は解かりやすいが、(3) の方が見やすい。
ただ (3) のままだと宣言初期化時しか格納できない。
 ・分岐後に文字列を格納したい。
 ・strcpy は使用を控えたい。

悔しいのでスマートな書き方教えてくれ。

531 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 16:07:53 ]
 printf("黒い0服\n"
     "お茶を1杯\n");
でいいよ

532 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 16:08:31 ]
別のテキストファイルにして読み込む
マジおすすめ

533 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 16:09:19 ]
あぁでもprintfに直接文字列は推奨されないよ
%入ってるとまずいからだけど

534 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 16:12:28 ]
putsでいいだろ

535 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 16:26:36 ]
そこでfputsですよ

536 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 16:37:01 ]
ABC &
上記の様にバックグラウンドプロセスABC に、パラメータを与えて実行させるのは
どの様にすればいいのですか?



537 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 16:43:21 ]
それはシェルの役目

538 名前:デフォルトの名無しさん [2008/05/10(土) 16:45:35 ]
>>531
あぁ , 無しで繋げられるのだっけか。
でも , をつけてしまいやすいので使い方だけ覚えとく。
>>532,533
メモっとく。
>>534
 puts("青6し");
 puts("むらさき7ぶ");

 puts(
  "むらさき7ぶ\n"
  "灰ヤー"
 );
のような感じか。

もう少し考えてみるわ、サンクス。

539 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 16:50:35 ]
本題より例文が気になって仕方がない。むらさきしちぶ?

540 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 16:54:17 ]
抵抗のカラーコードの語呂合わせだろ。
俺は「青二才のろくでなし」って覚えているんだけど。

541 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 18:44:45 ]
失礼しms。

ttp://www.uploda.org/uporg1415339.c.html

上記のようなコードを書いたのですが、
bの領域を解放するときに
”Windows によって aaaaa.exe でブレークポイントが発生しました。ヒープが壊れていることが原因として考えられます。aaaaa.exe または読み込まれた DLL にバグがあります。”
のようなエラーが出てしまいます・・・。。。

確保していない領域にアクセスし、それをフリーしようとしたときにおこるエラーみたいなことがググったら書いてあったのですが、
double** b; が確保されている領域と、callocで追加確保された領域が連続でないということでしょうか?
またそのせいでこのエラーがおこっているのでしょうか?

ご教授願います。よろしくお願いします。。。

542 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 18:50:19 ]
>>541
> memmove(b, a, sizeof(a[0])*sizeof(a[0][0]));
これのせいで同じ領域を二回 free している

543 名前:541 mailto:sage [2008/05/10(土) 20:38:45 ]
>>542
memmoveだとだめなのでしょうか?

544 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 20:42:06 ]
>>543
何がやりたいかによる
a[y][x] に格納されている double の値をコピーしたいのであれば

for(y=0;y<N;y++) memmove(b[y], a[y], N*sizeof(a[0][0]));

545 名前:541 mailto:sage [2008/05/10(土) 20:45:19 ]
やりたいことはその通りなのですが、今の状態だとポインタをコピーしてる状態ということでしょうか?

546 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 20:47:01 ]
>>545
  V /  / _,, ァ=ニニ:}       _
   .V  /,.ィ"f= <r'ニ三{        |_    ┐   _l_ l
    'vf^<''"  弋z.ミ'テtフ       |_ Х □_ 匚 L | У
    〉!ト _ i{ ´ ̄r' =|'
   ./ェ゙‐ェi.    、__`_ヤ     ( その通りでございます )
   ./iュ.Hヽ.、   ゙,ニ/
  -^ ー'-.、,i._`ヽ,.仁リ
  ー - .、     /、



547 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 20:50:49 ]
>>542,544,546
なるほどです。つながりました。ありがとうございました><


548 名前:デフォルトの名無しさん [2008/05/11(日) 01:50:19 ]
初心者です。すみませんがアドバイスお願いします。

char (*pacX)[3];

とした場合、pacXは3要素のchar配列へのポインタになると思いますが、
このような変数「の配列」を以下のように動的に確保するとします。

int iNum = 2;
char (*pacX)[3] = new (char)[iNum][3];

この場合、ポインタ変数が2つ(iNum分)確保されるのでしょうか。それとも、それらが指す3要素のchar配列2つ分のメモリまで確保されるのでしょうか?


549 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 01:52:50 ]
typedef して考えてみよう。

typedef char CharArray3[3];
CharArray3* pacX = new CharArray3[iNum];

550 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 01:56:23 ]
newてC++やん

551 名前:デフォルトの名無しさん [2008/05/11(日) 02:13:33 ]
>newてC++やん
すみません、確かにそうですね。

>>549
なるほど。。。元の質問で言えば後者の「それらが指す3要素のchar配列2つ分のメモリまで確保される」ということなのですね?
イメージ的には 「char aacX[2][3]」と同じ分のメモリが確保されて、さらにいえば
delete [] pacX;
とすることで開放されるということよろしいでしょうか?


552 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 02:24:13 ]
>>551
そういうこと。

553 名前:デフォルトの名無しさん [2008/05/11(日) 02:28:42 ]
>>552
ありがとうございました。

554 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 04:05:19 ]
>>548
その記述ちょっと気色悪い。一歩間違うと関数へのポインターと見間違えちゃうし。

int (*func)(int k); // 関数へのポインター

int a1(int k) { printf("%d¥n", k * 5); return k; }

int a2(int k) { printf("%d¥n", k / 5); return k; }

int main()
{
 func = &a1;
 func(k);

 func = &a2;
 func(k);
}

みたいな・・・

普通に char *a[3];  でいいと思うけど。

555 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 04:06:45 ]
>>554
内容が理解できない人は黙っておいた方がいいよ。

556 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 06:00:32 ]
char *a[3] ポインタの配列
char (*a)[3] 配列のポインタ



557 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 10:22:40 ]
CGIにC使ってる人ってあまり見かけないんだけど、CでCGIってダメダメなの?

558 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 10:33:06 ]
実行速度的には悪くないけど、LLに比べるとテキスト処理が面倒なのと、非セキュアになりやすい(バッファオーバーフローとか)からじゃないかねぇ。

559 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 10:40:20 ]
単にcコンパイラ使わせてくれる鯖が少ないからじゃないの?

560 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 10:43:33 ]
>>559
どの言語が用意されているかというのは、Web制作板的な視点じゃないか
プログラム板的には、どの言語で実装するのが適切かという話題だと思ってたが。

561 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 10:47:22 ]
>あまり見かけないんだけど
とあったからそれに沿うように答えただけなのだが。
性能的には何ら問題ないと思う、とつけたほうがよかったかな?

562 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 11:06:01 ]
なぜCコンパイラ使わせてくれる鯖が少ないか、
というところまで考え出すと、
結局 >>558 に行き着くんじゃないかと思う。

563 名前:デフォルトの名無しさん [2008/05/11(日) 11:41:06 ]
数列の最大値を計算するアルゴリズム 数列:0、3、1、4、7、2、8

お願いします。

564 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 11:45:28 ]
>>563
わかりました
消えてください

565 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 11:48:20 ]
宿題丸投げは宿題スレへ

566 名前:デフォルトの名無しさん [2008/05/11(日) 12:00:34 ]
><



567 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 12:22:18 ]
>>563
max(0, max(3, max(1, max(4, max(7, max(2, max(8)))))));
><

568 名前:デフォルトの名無しさん [2008/05/11(日) 14:42:42 ]
適当に数字を入力して
その数字をまたある数で割って割り切れたらその値を出力して
割り切れなかったら余りだけをまた別の小さい値で割りきれるか
って繰り返して最終的には割り切れるプログラムを作りたいんですが・・・
例えば1020を500で割ると2余り20で2が出力され
余り20を10で割って2が出力されるみたいな
ヒントでもいいんでお願いしますm(_ _)m


569 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 15:23:44 ]
その日本語を1行ずつCに翻訳していけばいいと思うよ

570 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 15:24:56 ]
ってある数で割るって何で割るんだよ
1020を1020で割って余り0で終了、じゃだめなの

571 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 15:25:52 ]
意味が分からん

ある数って何だよ
入力した値か?

572 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 15:28:12 ]
>>558
速度的にはアレなんじゃね?
スクリプト系のmod_*みたいな仕組みってCでは一般的でないし。
2chは、やってるみたいだけど。

573 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 16:10:07 ]
>>568
ユークリッドの互除法?


574 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 16:12:50 ]
568です
説明が下手ですいません
レジのおつりを渡す要領で
適当な値を入力して500、100、10、1で各々割って何が何枚必要か求めたいんです


575 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 16:14:36 ]
どこが分からないのかわからない。
それをそのままコードに落とせばいいだけだろ

576 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 16:19:33 ]
つりの硬貨の枚数が最小になるようにとか、なにがしかの条件がついてるけど、それが説明できてないんだろ?



577 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 16:19:49 ]
こうだろ
#include<stdio.h>
int main() {
static const int coin[] = {500,100,50,10,5,1,0};
int price, i;
printf("金額は?");
scanf("%d", &price);
for(i = 0; coin[i]; i ++) {
printf("%d円玉が%d枚\n", coin[i], price / coin[i]);
price %= coin[i];
}
}

578 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 16:19:57 ]
ちょっと自分でやってみます
迷惑かけてすいませんでした

579 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 16:20:39 ]
自己解決しました

580 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 16:31:40 ]
エロイ人教えてください!

エクセルで作成したファイルをスターファックスで
VBAなどで自動送信出来ませんか?
キーボードマクロなるフリーソフトを見つけましたが
自分ではうまく設定できません

イメージは以下の感じです
@送信ファイルをエクセルで作成
AVBAでスターファックスを起動
Bキーボードマクロ等で送信先を自動入力
Cエクセル画面に戻る

初心者丸出しですいませんが宜しくお願いします

581 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 16:31:49 ]
どうでもいいが、とってもありがちな課題だな。

582 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 16:58:37 ]
>>580
こんなソフト作ってくださいスレに行きやがれですぅ

583 名前:580 mailto:sage [2008/05/11(日) 18:05:44 ]
>>582
そんなスレあるんですか?
移動します スンマセン


584 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 18:17:49 ]
ある下記のような2つのcsvファイルの「商品コード」という項目を比較して
実績ファイルにある「商品コード」が、商品コードマスタに存在するかどうか
をチェックし、あったらその後の処理へ、なかったらエラーを出すといったプログラムを作りたいと考えてます。

(売上ファイル.csv)
顧客コード,商品コード,数量
10000,2544,2
12111,2566,5
12546,2354,8
(商品コードマスタ.csv)
商品コード,商品名,単価
2544,aaaaa,1000
2354,bbbbb,1500

このとき、c言語ではどういった関数を使って
どういった流れで考えるとよいでしょうか?
例えば下名はアクセスを使ったことあるので
アクセス(VB)でのテーブル同士の比較だったら、
if 商品コード(売上ファイルTBL)=商品コード (商品コードマスタTBL)
をレコードのEOFまで繰り返す、という処理でいいと思うのですが、
c言語の場合、しかもカンマ区切りcsvファイルの処理の場合、
どういった方向で考えたらいいのかということを知りたいです。

参考書を見たところ、ファイルポインタをつかう、fopen関数をつかうfgets関数で1行読み込む
といった機能を使うのかなと思いましたが、商品コード部分のみを取り出して比較するやりかたがわかりません。
(また、全てのデータの桁数は変わる可能性があります)

あつかましいですが、よろしければサンプルコードも提示して
いただけたらありがたいです。



585 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 18:28:17 ]
>>584
(っ´▽`)っ
char shohinCode[256];
char shohinName[256];
int tanka;
fscanf(fp, "%s,%s,%s", shohinCode, shohinName, &tanka);

586 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 19:25:26 ]
>>584
(っ´▽`)っ

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

int cmp(const void *elem1, const void *elem2);
int existInMaster(void);

typedef struct shohinM{
  char  shohinCode[256];
  char  shohinName[256];
  int    tanka;
} shohinMaster;

int main(void)
{
  int line;
  line = existInMaster();
  if(line == 0){
    printf("エラーはありません\n");
  }
  else{
    printf("%d行目にエラーがあります\n", line);
  }
  return 0;
}

(続く)



587 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 19:26:07 ]
>>586の続き

int existInMaster(void)
{
  int    returnCode = -1;
  FILE  *fp = NULL;
  char  line[1024];
  int    lineCount = 0;
  shohinMaster *sm = NULL;
  char  shohinCode[256];
  char  kokyakuCode[256];
  int    suryo;
  int    count = 0;
  int    i;

  fp = fopen("./商品コードマスタ.csv", "r");
  fgets(line, sizeof(line), fp);  /*1行目は見出し*/
  while(fgets(line, sizeof(line), fp) != NULL){
    sm = (shohinMaster *)realloc(sm, sizeof(sm[0]) * (count + 1));
    sscanf(line, "%[^,],%[^,],%d", sm[count].shohinCode, sm[count].shohinName, &(sm[count].tanka));
    count++;
  }
  fclose(fp);
  
  qsort(sm, count, sizeof(sm[0]), cmp);

(続く)

588 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 19:26:48 ]
>>587の続き

  fp = fopen("./売上ファイル.csv", "r");
  fgets(line, sizeof(line), fp);  /*1行目は見出し*/
  while(fgets(line, sizeof(line), fp) != NULL){
    lineCount++;
    sscanf(line, "%[^,],%[^,],%d", kokyakuCode, shohinCode, &suryo);
    for(i = 0; i < count; i++){
      if(strcmp(sm[i].shohinCode, shohinCode) == 0){
        break;
      }
      if(strcmp(sm[i].shohinCode, shohinCode) > 0){
        returnCode = lineCount;
        goto END;
      }
    }
    if(i == count){
      returnCode = lineCount;
      goto END;
    }
  }
END:
  return returnCode;
}

int cmp(const void *elem1, const void *elem2){
  return strcmp(((shohinMaster *)elem1)->shohinCode, ((shohinMaster *)elem2)->shohinCode);
}


589 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 19:35:31 ]
(っ´▽`)っ
さあ感謝しなさい☆
(っ´▽`)っの足を舐めなさい☆

590 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 20:03:04 ]
変なコテだけど、いいやつだな。

591 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 20:16:41 ]
無意味にコテつけてる時点で・・・

592 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 20:46:21 ]
(っ´▽`)っ
>>586-589には
リソース解放漏れがたくさんあるから注意してね☆

関数existInMasterのEND:の直後に
fclose(fp);
if(sm != NULL){
  free(sm);
}
を加えるんだ☆

593 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 20:48:10 ]
>>591
(っ´▽`)っ
無意味にコテ!?
(っ´▽`)っはコテつけるのが当たり前なの!
www.google.co.jp/search?lr=lang_ja&num=50&ie=utf-8&oe=utf-8&q=%22%E2%97%860351148456%22

594 名前:584 mailto:sage [2008/05/11(日) 21:03:04 ]
ご親切にありがとうございます。
ちなみにこのままコピペしてとりあえず実行してみようと思ったら
100個を超えるエラーが出たのですが、そのままではいけないのですかね?

とりあえず、解読動くかどうかより
解読して、流れを理解することをがんばります

595 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 21:05:25 ]
>>594
(っ´▽`)っ
インデントに全角スペース使ってるからね。
半角スペース、タブ文字は、2chでは表示されないの。
コピーしたら全角スペースを全て半角スペースに置換してね。

596 名前:584 mailto:sage [2008/05/11(日) 21:13:39 ]
>>595
了解しました。
なにからなにまでありがとうございます。



597 名前:584 mailto:sage [2008/05/11(日) 21:24:18 ]
>>595
すみません、もうひとつ。

今解読中なのですが、理解の手助けに
・処理の流れ
・このプログラムの入力と、出力値
など、簡単に教えていただけませんか?
本当の初心者ですみません。

598 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 21:26:57 ]
HTMLの使用も理解できない馬鹿がいる。

599 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 21:31:20 ]
>>598
それを言うならHTMLの仕様だろ、と。
まぁ、変数宣言の変数名を揃えようとする辺りでお察しだから。

600 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 21:34:46 ]
灯台や鏡台の先生からは sed の使い方とかは習わなかったんでしょうかね?

601 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 21:50:09 ]
>>597
自分がどういうプログラム要求したか覚えてる・・?
見ていくと何となく流れがつかめるでしょ
どこまで理解したか言わないと答え丸写しで理解した気になる子になるよ

初心者≠免罪符

602 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 22:39:49 ]
(っ´▽`)っ
/*
*戻り値:
*エラーなし:0
*エラーあり:エラーがある行番号(見出し行を除く)
*/
int existInMaster(void)
{
  int    returnCode = -1; /*戻り値*/
  FILE  *fp = NULL; /*ファイルポインタ*/
  char  line[1024]; /*ファイル読み込みバッファ*/
  int    lineCount = 0; /*行番号*/
  shohinMaster *sm = NULL; /*商品マスタ配列*/

  /*以下、売上ファイルレコード格納用変数*/
  char  shohinCode[256]; /*商品コード*/
  char  kokyakuCode[256]; /*顧客コード*/
  int    suryo; /*数量*/

  int    count = 0; /*商品マスタ配列サイズ*/
  int    i; /*ループカウンタ*/

  /*商品コードマスタを全て読み込み、商品マスタ配列に格納する*/
  fp = fopen("./商品コードマスタ.csv", "r");
  fgets(line, sizeof(line), fp);  /*1行目は見出し*/
  while(fgets(line, sizeof(line), fp) != NULL){
    sm = (shohinMaster *)realloc(sm, sizeof(sm[0]) * (count + 1));
    sscanf(line, "%[^,],%[^,],%d", sm[count].shohinCode, sm[count].shohinName, &(sm[count].tanka));
    count++;
  }
  fclose(fp);


603 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 22:40:30 ]
  /*商品マスタ配列を商品コードの昇順に並べる*/
  qsort(sm, count, sizeof(sm[0]), cmp);
  /*売上ファイルを1行ずつ読み込み、商品コードを商品マスタ配列と照合する*/
  fp = fopen("./売上ファイル.csv", "r");
  fgets(line, sizeof(line), fp);  /*1行目は見出し*/
  while(fgets(line, sizeof(line), fp) != NULL){
    lineCount++;
    sscanf(line, "%[^,],%[^,],%d", kokyakuCode, shohinCode, &suryo);
    for(i = 0; i < count; i++){
      if(strcmp(sm[i].shohinCode, shohinCode) == 0){
        break;
      }
      /*商品マスタ配列は商品コードの昇順に並べている*/
      if(strcmp(sm[i].shohinCode, shohinCode) > 0){
        returnCode = lineCount;
        goto END;
      }
    }
    /*商品マスタ配列にない場合、行番号を返す*/
    if(i == count){
      returnCode = lineCount;
      goto END;
    }
  }
END:
  return returnCode;
}
/*商品マスタ配列を並べる時、商品コードの昇順に並ぶようにする*/
int cmp(const void *elem1, const void *elem2){
  return strcmp(((shohinMaster *)elem1)->shohinCode, ((shohinMaster *)elem2)->shohinCode);
}


604 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 22:44:43 ]
>>597
(っ´▽`)っ>>602-603
これで満足か?

605 名前:側近中の側近 ◆0351148456 [2008/05/11(日) 22:52:56 ]
(っ´▽`)っ
売上ファイルも商品コードの昇順に並べると
もっといい感じになるかもね。

606 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 23:32:17 ]
次の様に、単語毎に空白で区切られた文字列があり、一単語ずつ取ってくる処理を
行いたいと考えてます。文字列の中に入っている単語数は不定とします。

char str_str[] = "str1 str2 ・・・・ strN";


今現在、次に書き込むソースの様な処理で、一つずつ単語を読み込んでいます。
ここで、質問なのですが、sscanf等を使用してもっと上手に処理することはできないでしょうか?
以下の様にダミー変数を利用する方法は考えたのですが、入っている単語数が不定
なため、どうも不恰好なソースになってしまいます。

sscanf(str_str,"%s %s %s %s %s",str1, str2, str3, dummy, dummy);

すいませんが、アドバイスよろしくお願いします。




607 名前:606 mailto:sage [2008/05/11(日) 23:33:02 ]
現在使っているソースコードは以下になります。
int main(void)
{
char src_str[]="str1 str2 str3 str4 str5";
char *next;
char *buff=src_str;

while((next=strsplit(buff, " "))!=NULL){
// 空白文字が2個以上続いた場合はbuffにはナル文字が入っている
if(buff[0] != '\0')
fprintf(stderr, "buff=%s, next=%s\n",buff, next);

buff=next;
}
return 0;
}

// 文字列をdelimstrを区切り文字列として分割し、区切後の文字列へのポインタを返す
char *strsplit(char* str,const char* delim_str)
{
char* delim_point = strstr(str,delim_str);
const size_t delim_len = strlen(delim_str);
size_t i;

if(delim_point == NULL) return NULL;
else {
*delim_point = '\0';
for(i=0;i<delim_len;i++) delim_point++;
}
return delim_point;
}


608 名前:606 mailto:sage [2008/05/11(日) 23:35:17 ]
すいません、書き込んだ後、インデントがされてないのに気がついつきました。同じソースですが
int main(void)
{
  char src_str[]="str1 str2 str3 str4 str5";
  char *next;
  char *buff=src_str;

  while((next=strsplit(buff, " "))!=NULL){
  // 空白文字が2個以上続いた場合はbuffにはナル文字が入っている
    if(buff[0] != '\0')
      fprintf(stderr, "buff=%s, next=%s\n",buff, next);

    buff=next;
  }

  return 0;
}

// 文字列をdelimstrを区切り文字列として分割し、区切後の文字列へのポインタを返す
char *strsplit(char* str,const char* delim_str)
{
  char* delim_point = strstr(str,delim_str);
  const size_t delim_len = strlen(delim_str);
  size_t i;

  if(delim_point == NULL) return NULL;
  else {
    *delim_point = '\0';
    for(i=0;i<delim_len;i++) delim_point++;
  }
  return delim_point;
}

609 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 23:38:06 ]
なんというstrtok

610 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 23:38:19 ]
>>608
sscanf(str, "%s%n", ...)

611 名前:606 mailto:sage [2008/05/11(日) 23:40:42 ]
 実際に処理をしている部分は冗長になってしまうため、以下のコードが
入っている部分で、処理を実施していると考えてください。

fprintf(stderr, "buff=%s, next=%s\n",buff, next);


 また、src_strの内容が変わってしまう点は仕様として、その様にしてます。
よろしくお願いします。

612 名前:606 mailto:sage [2008/05/11(日) 23:59:40 ]
>609
 確かに、この処理内容だと、strtokで十分ですね・・・。文字列群で区切るstrでは
不便な事が多く、strsplitという文字列パターンで区切る関数を作成しており、何も考えず
そのまま使用していました。ご指摘ありがとうございます。

>610
 すいません、その処理はダミー変数を利用する方法とは異なる方法なのでしょうか?
つまり、下記の様な処理とは別の処理ということなのでしょうか?

sscanf(str_str,"%s %s %s %s %s",str1, str2, str3, dummy, dummy);




613 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 00:39:57 ]
rand関数は合同乗算法ですか?

614 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 00:42:50 ]
仕様上特に決まってない。

最近は lagged Fibonacci なこともあるようだ。

615 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 00:45:03 ]
>>613
どういう方法でなければならないという規定はない。
現実には線形合同法がよく使われている。

616 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 00:48:45 ]
>>613
大概そうですよ



617 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 00:50:38 ]
>>614-615
レスありがとうございます。

c言語で書くと
a[i+1]=a[i]*j%10*10*10*10
で良いのですか?(a[i+1]=j*a[i] (mod10^4))

618 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 00:54:19 ]
数学板から飛んできたか
a[i+1]=a[i]*j%(10*10*10*10)
というか
a[i+1]=a[i]*j%10000
でいいんじゃないのか

619 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 00:55:54 ]
すみません質問を変えます。
0から1の範囲の乱数を合同乗算法で書くにはどのように書けばいいですか?

>>618 ばれたか・・・正直kingはウザイと思っています。

620 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 00:58:13 ]
数学板でも思ったんだが、前の質問に答えてもらってるのに、
それに何の反応もせずに「質問を変えます」はないだろ。社会常識的な意味で。

621 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 00:59:29 ]
>>620
すみません・・・

622 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 01:00:11 ]
整数の 0〜(n-1) の乱数を発生させて
double にキャストして n で割ればいいんじゃない

623 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 01:02:03 ]
>>622
レスありがとうございます
a=rand()/(RAND_MAX+1.0);
としてもいいのですが>>618さんの方法で書くことはできませんか?

624 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 01:04:35 ]
a[i+1]=a[i]*j%10000;
b[i+1]=a[i+1]/(10000.0);

625 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 01:32:58 ]
>>624 ありがとうございます
一応書いてみたのですがエラーが出てしまいます
どこがおかしいですか?ちなみに円周率を求めるプログラムです
#include <stdio.h>
int main(void)
{
double i,max;
double x,y,pi;
int a[1000],j;
double b;
double c=0,d=0;
max=100;
a[0]=9454;
j=9456;
for(i=0;i<=max;i++) {
a[i+1]=a[i]*j%10000;/*ここでエラーが出ます。*/
b[i+1]=a[i+1]/(10000.0);
if((b[i+1]*b[i+1]+b[i]*b[i])<=1.0) {
c+=1.0;

}
else{
d+=1;
}

}
pi=4*c/(c+d);

printf("%f\n",pi);

return 0;
}

626 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 01:36:24 ]
数字を渡したら曜日を表示する関数を作ったのですが、関数内に
char youbi[7][] = {"日曜日", "月曜日",....}
と書きました。
これだと関数が呼ばれるたびに変数を作って文字列を入れてることになりますよね?
頻繁に呼ぶ関数にこういうことすると速度などに悪い影響ありますか?



627 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 01:36:32 ]
double i

628 名前:626 mailto:sage [2008/05/12(月) 01:37:21 ]
すみません訂正します。
char youbi[][7] です。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<213KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef