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


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

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



1 名前:デフォルトの名無しさん mailto:sage [2009/10/06(火) 20:41:54 ]
C言語の*入門者*向け解説スレッドです。
初心者、初級者の方は他の質問スレのほうが良いかもしれません。

教えて欲しいのではなく宿題を丸投げしたいだけなら
↓宿題スレ↓へ行ってください。
C/C++の宿題片付けます 130代目
pc12.2ch.net/test/read.cgi/tech/1250204272/

・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
  # 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること
  # サイズが大きい場合は宿題スレのアップローダ等を利用してください
・開発環境や動作環境も晒すと答えが早いかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 53
pc12.2ch.net/test/read.cgi/tech/1253110182/

過去スレ
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

855 名前:デフォルトの名無しさん [2009/10/27(火) 05:54:01 ]
皆様よろしく。
Cを独学し始めたばかりの初心者です。目的はVBAで書いたコードをCに書き直すこと
です。VBAも独学なので冗長な表現や不要な処理が多々あると思われますが、
とりあえず動いているのでよしとしています。

と、ここからが本題なのですが、とりあえずVBAコードをまとまりのある
ブロックに分けてCに書き直し、コンパイル→実行して意図通りに動いているか
確かめています。すでに4,5個分はチェックできました。
使っているエディタ?は「C言語を始めよう!」というフリーのものですが、
今引っかかっているブロックでは「問題が発生したため、block3.exe を終了します。
ご不便をおかけして申し訳ありません。エラー報告する しない云々・・」という
おなじみの表示が出てしまって、実行できません。
BCCを使っているみたいで、コンパイルエラーは出ないのですが実行できないのです。

これはコードの問題なのか、エディタもしくはそれ以外の問題なのかが目下の悩みです。
この「C言語を始めよう!」は、コード書く→コンパイル→実行という
とてもシンプルで使いやすいのですが、他の「統合開発環境」と名の付くソフト
(たとえばWildStudioなど)はビルドやらプロジェクトやら、意味が分からんことばかりで
使い方を学ぶまで時間がかかりそうで尻込みしています。

コードがまずいのだろうと思われますが、それを確かめるためにも、初心者やさしいエディタ
(開発環境)があれば、教えてください。ただしフリーのもので。






856 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 05:58:00 ]
メモ帳

857 名前:855 mailto:sage [2009/10/27(火) 06:12:06 ]
メモ帳にコード書いて・・そのあとが分かりません。コンパイル、実行は
どうやってするの?

858 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 06:37:47 ]
>>856は意地悪なようだが>>855が教えてくれと言ったこと(だけ)にはちゃんと答えている。

859 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 06:43:29 ]
それこそが彼が意地悪たる所以である

860 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 06:59:56 ]
いや、メモ帳はフリーではないだろう。


861 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 07:00:47 ]
チラシの裏
ttp://yuukiremix.s33.xrea.com/chirashi/
これならフリーソフトだよ。


862 名前:849 mailto:sage [2009/10/27(火) 07:21:53 ]
色々ためしたけどやはりよく分かりません
setlocaleもやってみましたが全く変化ありません
どうすればwchar_tのn番目の要素とL""の比較ができるんでしょうか?
デバッグ中は期待通りの文字列が見えるのに、一文字だけ取り出そうとするとint型になってしまいます

コマンド引数に/Zc:wchar_tを指定しても変わりありませんでした
(VC++では規定で有効らしいので当たり前ですが)

863 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 07:24:46 ]
>>862
できるわけないだろ…。



864 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 07:27:38 ]
/D_UNICODE

865 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 07:48:32 ]
const wchar_t* str = L"あいうえお";
const wchar_t comp = L'う'; // == L"う"[0]
if (str[2] == comp) {}

866 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 08:04:52 ]
>865
それだとif文で左辺がint型、右辺がconst wchar_t*型でエラーが出ます
Unicodeを調べて両辺int型でやればなんとかうまくいくようです
wchar_t型の文字のUnicodeを求める関数などはあるのでしょうか?

867 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 08:43:52 ]
ある

868 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 08:44:54 ]
>>866
>右辺がconst wchar_t*型で

???

869 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 08:50:47 ]
>>866
うん。明らかに君の使っているコンパイラは標準に合致してない。
別のコンパイラに変えるしかないよ。
そのコンパイラではどうやってもwchar_t同士の比較はできない。

870 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 09:39:44 ]
>>866
wchar_t が unsigned なのかも

871 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 10:50:58 ]
>>855
アドバイスするとしたら
わざわざC言語使わなくてもVBAでいいんじゃない?
ってことくらいかな。
あと、異常終了するのはまず間違いなくコンパイラやエディタのせいではない
と思っていい。

872 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 10:51:53 ]
ヘッダで
#define wchar_t int
とかやってたりしてな。

873 名前:855 mailto:sage [2009/10/27(火) 12:25:42 ]
>>871
>わざわざC言語使わなくてもVBAでいいんじゃない?
プログラムをLinuxで走らせたいのです。

>異常終了するのはまず間違いなくコンパイラやエディタのせいではない
やはり、コードですかね。問題は。
もうちょっとがんばってみます。 ありがとうございました。



874 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 12:36:59 ]
>>873
スクリプト系言語にしたら?
LinuxならRubyでもPythonでも選り取り緑でしょ。

875 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 12:42:06 ]
C言語を始めよう!はwindowsじゃないの?

876 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 13:06:26 ]
>>873
Linuxで動かすつもりなら、Linuxで開発したほうが楽だと思うけどね。
Windowsと違うところ結構あるし。
あと、まさかWindows特有の機能使おうとはしてないよね?

877 名前:855 mailto:sage [2009/10/27(火) 13:16:49 ]
>>875
>>876
あの〜、この辺まったく知らないんですが、Windows上で動くcプログラムでも
Linuxで動かないってことあるんですか?あ、もちろんWindows特有の機能ってのは
使わない上での話ですが。
「Linuxで走らせる」っていうのも先の目標でして、実際はKnoppixのデスクトップ画面
を、自身のPCで見たことがある程度の者です。

878 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 13:23:29 ]
>>877
> Windows上で動くcプログラムでも
> Linuxで動かないってことあるんですか?
あるねぇ。

> あ、もちろんWindows特有の機能ってのは
> 使わない上での話ですが。
あなたのレベルでは、Windows特有の機能かどうかの判断は難しいと思う。

879 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 13:40:23 ]
>>877
自分のLinux上で動くcプログラムが
他人のLinuxで動かないってこともある

880 名前:855 mailto:sage [2009/10/27(火) 13:44:25 ]
>>879
ほんとですかw。どーゆーこと?って感じですね。

881 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 13:52:13 ]
理由がわからん香具師はおとなしくスクリプトつかっとけ
Windows の VB に相当するのは Python だ


882 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 13:54:20 ]
標準ライブラリからちょっとでも逸脱しなければ大抵大丈夫だと思うが

883 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:05:01 ]
>>794
引数に配列名を持ってくるときは自動的に配列の1番目の要素のアドレスを表すので&は不要ということはわかりましたが
そこを直してもやはりダメでした
というかunsigned charに対するフォーマット指定子は%sでよいのでしょうか?
もちろん文字列入力を行うということなのですが・・・



884 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:11:01 ]
問題はI/O。標準ライブラリでのI/Oって、stdin, stdout, stderrとfopen系のストリームくらい。
ディレクトリ操作すら標準化されてない。GUIなど無論。

885 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:12:13 ]
>>883
"%s"は試したの?

886 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:13:27 ]
どうダメだったの?
scanf("%s", tripkey);
これでダメなら原因は別のとこにある。

887 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:36:11 ]
>>885
試しましたがダメでした

>>886
同じようにコアを吐きます

とりあえずソース全部です・・・
この部分だけでなく他にもおかしいところが多々あって見苦しいとは思いますが・・・
ttp://ccfa.info/cgi-bin/up/src/up1812.txt

888 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:44:20 ]
>>887
crypt()周辺がおかしいんで内科医?
crypt()の仕様はどうなってんのよ。
つーか、手元にcrypt()がないからコメントアウトしたら、実行しても少なくともコアは吐かないんだが。

889 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:47:29 ]
>>877
C言語を始めよう!ってなんじゃろうと思って調べたら統合開発環境だた

890 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:47:45 ]
いろいろ間違ってるが、crypt(tripkey, salt);のように*をはずしたら最後までいったな

891 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:52:14 ]
>>887
cryptの呼び出しは
strcpy(trip_f, crypt(tripkey, salt));
こんな感じ?

892 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 15:56:14 ]
>>887
printf("トリップキーを入力:");
scanf("%u", &tripkey);

printf("トリップキー入力"); ←これが表示されずにコアを吐く
fflush(stdout); ←これを追加したら↑これ出ないかな

893 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 16:33:35 ]
>891
本来ならそんな感じで呼び出すはずだけど

僕の環境では
/usr/include/unistd.h:1073:extern char *crypt (__const char *__key, __const char *__salt)
/usr/lib/i386-redhat-linux4E/include/unistd.h:1019:extern char *crypt (__const char *__key, __const char *__salt)
となっていたから

diff
96c96
< *trip_f = crypt(*tripkey, *salt);
---
> strcpy(trip_f, crypt(tripkey, salt));

結果
./up1812
トリップキーを入力:foo
トリップキー入力トリップキー前処理salt作成1回目:OK2回目:OK3回目:OK4回目:OK5回目:OK◆yaoo



894 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 20:59:52 ]
typedef struct data{
___char mozi[100]; //文字列格納用
_______int year[100];//点数格納用
}Data;

Data data[100];構造体を100個用意

data[0].mozi="aaaaaaaa";←*1

printf("%s",data[0].mozi);

これでコンパイルすると*1の部分が「左辺値が必要」といわれてしまいます。
どうやったら文字列を格納できるのでしょうか?

895 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 21:10:43 ]
strcpy

896 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 21:12:36 ]
strcpy(data[0].mozi,"aaaaaaaa");

897 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 21:14:53 ]
>>895-896
ありがとうございます。
配列=配列ができないのと同じ原理なんですね。

898 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 22:46:47 ]
char *a[8];
char (*b)[8];

この違いを教えてください。

899 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 22:47:50 ]
Cってカンタンだよね。
すぐにUSB接続デバイスとか
作れそう。

900 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 22:54:26 ]
>>899
DDK次第

901 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 22:55:55 ]
道路の交通量調査などに使われてる(?)紅白で野鳥の会の人が使ってる(?)
カウンターの様な機械をC言語で作ってみたいと思っています。

コマンドプロンプト上で、Enterを押せば数字が増えていくというモノです。

Enterの入力があれば用意した変数に1を足して出力 とするプログラムはすぐに書けると思うのですが、
C:\>counter.exe
Enterの入力回数:1
Enterの入力回数:2
Enterの入力回数:3
・・・・
Enterの入力回数:100
の様な感じになると思います。
C:\>counter.exe
Enterの入力回数:XXX として、Enterを押せばXXXの部分の数字だけを書き換える
という事は出来るのでしょうか?

説明が下手なのですが、内容を察して教えて下さい。
もしよろしければコーディングまでよろしくお願いします。

902 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 22:58:31 ]
CLSして再描画する?

903 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:03:20 ]
#include <stdio.h>
int main(void)
{
  int counter=0;
  while(1){
    int c = getchar();
    if(c=='\n'){
      counter++;
    }
    system("clear");
    printf("counter:%d\n", counter);
  }
  return 0;
}

※windowsならsystem("cls");



904 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:05:15 ]
>>901
非標準な事をすれば可能
環境を書いてくれないと無理

905 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:11:20 ]
>>901 conio.h があるなら
#include<stdio.h>
#include<conio.h>

#define KEY_ENTER 0x0d
#define KEY_ESCAPE 0x1b

int main(void){
int count=0, key;

while(1){
key=getch();
if(key==KEY_ENTER) printf("\rEnterの入力回数:%d ", ++count);
if(key==KEY_ESCAPE) break;
}
return 0;
}

906 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:11:30 ]
>>901
本当はこうなってるんじゃないの?

C:\>counter.exe

Enterの入力回数:1
Enterの入力回数:2
Enterの入力回数:3
・・・・
Enterの入力回数:100

表示が本当に >>901 の通りなら入力にエコーが無いから
単に改行しなければ良いだけだろ


907 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:12:57 ]
int counter=0;

これってCだと必須なんだ。
変数を宣言しないと
つかえないから。

908 名前:894 mailto:sage [2009/10/27(火) 23:17:53 ]
/**おまじない省略**/
struct suji{
char moji[100];//文字列格納
int su[100];//数字格納用
};

int main(void)
{
____struct suji score[100];//100の構造体を用意
____FILE *fp;
____char *tp;
____char str[256];//ファイルの行を格納する配列
____int i=0,k=0;

____ if((fp= fopen("input.txt", "r")) == NULL)exit(1);
____________while( fgets(str,256,fp) != NULL)//ファイルの中身がなくなるまで
____________{;
/************文字列格納******************************/
________________tp=strtok(str,","); //文字列格納 tp=ポインタ
________________strcpy(score[i].moji , tp); //文字列コピー
________________printf("%s\n" , score[i].moji); //テスト表示
________________i++;//構造体を一つ進める
/***************数字格納******************************/
____________________while(tp!=NULL){//一行読みきるまで
____________________________score[i-1].su[k] = atoi(strtok(NULL , "," ));//i-1は上でi++してるため無効化する作業
____________________________printf("%d\n" , score[i-1].su[k] ); //テスト表示
____________________________k++;
____________________}
_____________}
___________fclose(fp);
___________return 0;
}

909 名前:894 mailto:sage [2009/10/27(火) 23:18:57 ]
上のプログラムはCSVファイルを一行ごとに構造体配列に格納するプログラムを目指してます。
input.txtには、文字列,数字1,数字2・・・,数字n(文字列は行の先頭に一つだが、数字はいくつでも可能)といった形式で入っています。

このプログラム、コンパイルは正常にできますが実行するとエラーで強制終了となります。
何がおかしいかご教授ください。

CSVファイルが
aiueo,10,23,53,55,60
kakikukeko,22,33 
の2行だったら格納後、適当なメンバを参照すると
score[0].enzan=aiueo
score[0].su[0]=1
score[0].su[1]=2
score[1].enzan=kakikukeko
score[1].su[1]=33
という具合になる予定です。



910 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:20:25 ]
score[0].su[0]=10
score[0].su[1]=23
の間違いです。

911 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:23:32 ]
>>898
全然違う。後者に使い道はない。

912 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:28:16 ]
今、大学の課題を考え中なのですが、
「定義域 -1.5<=x<=1.5の時
 関数 y=3x^3-0.2x^2+0.3x-0.7
 の値を出力するプログラムを作れ。
 なお、xは-1.5から0.1刻みで増やすこと」

という問題なのですが、
↓のようなプログラムを実行させると
なぜか、x=1.5のときだけ出力されません・・・


913 名前:つづき mailto:sage [2009/10/27(火) 23:28:59 ]
#include <stdio.h>

main()
{
float x, y, step;
x=-1.5;
step=0.1;
y=0.0;

while(x>=-1.5 && x<=1.5){
y=3.0*x*x*x-0.2*x*x+0.3*x-0.7;
printf("%4.1f %9.5f\n", x, y);
x = x + step;
}


}

ちなみに、
whileの中の条件式を
x>=-1.5 && x<1.6 (右の不等式のイコールをとって、1.6にしてみた)
とか
x>=-1.5 && x<=1.51
とかにかえると正しい結果が得られました。

どこで間違ってるのでしょう??

どなたかご教授願います
m(_ _)m




914 名前:デフォルトの名無しさん [2009/10/27(火) 23:40:45 ]
>>911
使い道はある
(単純な二次元配列でも使うし固定長配列へのポインタを関数の引数にする場合にも使う)

>>898
>char *a[8];
char *a; が8個
char *a[8] = {"abcd", "ef", "gh", "ijkl", "mnopq", "rst", "uv", "wxyz"};

>char (*b)[8];
char [8]へのポインタb または char [8]がn個 の配列
char (*b)[8] = {"abcdefg", "1234567", "zyxwvut"};


915 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:41:31 ]
浮動少数は厳密なものじゃなく近似値だから
ピッタリでは判定できないことが多いよ。


916 名前:デフォルトの名無しさん [2009/10/27(火) 23:46:56 ]
while(!((x+1.5)<0.0 || (x-1.5)>0.0)){


917 名前:デフォルトの名無しさん mailto:sage [2009/10/27(火) 23:49:58 ]
>>913
0.1を正確に表せないから。

step=0.1;
としても、0.1よりちょっとずれた値になるので、何度も足してると誤差が蓄積する。
誤差少なくするなら、
double x;
int n;
for(n = 0; n <= 30; n++){
x = -1.5 + n*0.1;
...
}
みたいな。

918 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 00:16:08 ]
>>917

へぇ〜
そんな話、聞いたことありませんでした!!
ありがとうございました!!

ところで、
どうして、その1次関数で
誤差を少なくすることができるのでしょうか??

何度も何度も聞いてしまってスイマセン・・・
m(_ _)m

919 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 00:27:33 ]
>898

型が違う。

aはcharを指すポインタの配列(要素数は8)
bはcharの配列(要素数8)を指すポインタ

aに+1するとsizeof(char*)増加(32ビット環境なら通常4)
bに+1するとsizeof(char[8])増加(8)


920 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 00:30:01 ]
>897

>配列=配列ができないのと同じ原理なんですね。
というか、文字列リテラル("aaaaaaaa")の型はconst charの配列
なので、問題の箇所は「配列=配列」そのもの。

921 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 00:35:35 ]
>911

>>898
>全然違う。後者に使い道はない。


いやいや、普通にあるでしょ。
char a[N][8];
を引数にとる関数の仮引数の型がそう。



922 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 01:10:00 ]
ならなんで
char *(b[8]);
じゃないの?

923 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 01:28:14 ]
fclose() が NULL を受け付けないおかげで
fclose(func(fopen(fname,"r")));
みたいに出来ないから困る。
free(func(malloc(s)));
ならできるのにな。




924 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 01:36:53 ]
char (*b)[8];について、
演算子の優先順位で覚えればいいと言いたい所だけど、
*は、演算子では無くポインタ宣言子なわけで、
(ついでに言うと、[]もここでは演算子でないのよ、優先順位は、高 () > [] > * 低)
でも、間接参照するときは、(*b)[i]のようにしないと演算子の優先順位があって、
いや、何というかね

char *(b[8]);は、bに[]が付いているから、bは配列、それに*が付いているから、ポインタの、型はcharである。
つまり、bは、char型のポインタの配列と解釈されるわけで。b is array[8] of pointer to char.優先順位の高い方から低い方へ。
まぁ、『Cの強化書』とか『エキスパートCプログラミング』でも読めばいいよ。

925 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 01:43:12 ]
NULLを受け付けるようなfcloseを自分で作るとか一瞬だけ思ったんだが駄目かな

int myfclose(FILE *stream)
{
 if(NULL == stream)
  return 0;
 else
  return fclose( stream );
}

926 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 01:47:22 ]
素直にwrapper作ればよくないか
標準関数を直呼びすることはあまり無くなった
int safe_fclose(FILE *f) {
 if ( f == NULL ) {
  return 1;
 }
 return fclose(f);
}
戻り値を何にするかちょっと悩んだ。

927 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 01:57:14 ]
#include <stdio.h>
#include <time.h>
#include <Windows.h>
int main(void){
time_t timer;
struct tm *t_st;
while(1){
time(&timer);
printf("現在時刻: %.24s\r", ctime(&timer));
Sleep(1000);
}
}
このプログラムで、Ctrl+Cの強制終了ではなく、Escapeなどできれいにプログラムを終了させるには
どうしたら良いでしょうか?

928 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 01:59:43 ]
>char *(b[8]);は、bに[]が付いているから、bは配列、それに*が付いているから、ポインタの、型はcharである。

doubt

929 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:01:57 ]
windowsみたいだから
getchでESC押されたか判定して抜けると良いんじゃない

930 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:03:00 ]
>>927
escapeがきれいだとは思わない

931 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:04:04 ]
どうしてそんなにsleepしたがるのだ。
OSに大麻イベントをセットしてWM_TIMERで読んでもらえばいいじゃないか。
え?ミリ秒単位で制御したいの?

どっかのスレで誰かが副作用で暴れてたなぁ。

932 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:13:11 ]
>>927
#include <stdio.h>
#include <time.h>
#include <Windows.h>
#include <conio.h>

int main(void){
time_t timer;
struct tm *t_st;
while(1){
time(&timer);
printf("現在時刻: %.24s\r", ctime(&timer));
Sleep(1000);
while(kbhit()){
if(getch()==0x1b)break;
}
}
}


933 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:14:19 ]
ごめん間違えた。



934 名前:927 mailto:sage [2009/10/28(水) 02:17:14 ]
>>929
#define KEY_ESCAPE 0x1b
int key;
while()1{
key=getch();
if(key==KEY_ESCAPE) break;
・・・・・
}
としてみたのですが、何かキーを押さないと時刻を更新しなくなります。

>>930
そうですよね。


強制終了ではなく、キー入力でwhileから抜けて処理終了を「きれい」と言っていました。

>>931
全く知識がないので、sleep使えば手っ取り早くできるかなと思いまして・・・・

935 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:19:18 ]
#include <stdio.h>
#include <time.h>
#include <Windows.h>
int main(void){
time_t timer;
struct tm *t_st;
while(1){
while(!_kbhit()){
time(&timer);
printf("現在時刻: %.24s\r", ctime(&timer));
Sleep(1000);
}
if(_getch()==0x1b)break;
}
}


936 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:23:55 ]
エレガントじゃないな。

#include <stdio.h>
#include <time.h>
#include <Windows.h>
#include <conio.h>
int main(void){
time_t timer;
struct tm *t_st;
do{
while(!_kbhit()){
time(&timer);
printf("現在時刻: %.24s\r", ctime(&timer));
Sleep(1000);
}
}while(_getch()!=0x1b);
return 0;
}

こうだろ。

937 名前:927 mailto:sage [2009/10/28(水) 02:37:30 ]
kbhit()なんてものがあったんですね。

もしお時間があれば、>>931さんの言うタイマーイベントを使ったプログラムのサンプルをお願いします。

私の環境はWinVista
コンパイラ:Borland C++ 5.5.1
です。

よろしくお願いします。

938 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:43:07 ]
ボーランドのコンパイラなら

_kbhit() → kbhit()
_getch() → getch()

に置き換えだな。
MicroSoft は非標準には '_' を付けてる。

939 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:44:59 ]
Windows のタイマーイベントはウィンドウメッセージだから、
それを受け取るウィンドウが必要だぞ。

940 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:48:35 ]
つ select

941 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 02:49:22 ]
宿題スレでもC++対応でそこに誘導している以上
このスレもC++拒否じゃなくて、無保証対応で
良くね?

942 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 03:09:06 ]
>>937
#include <stdio.h>
#include <time.h>
#include <Windows.h>

VOID CALLBACK tp(HWND hwnd, UINT u, UINT_PTR p, DWORD dw){
time_t timer;
struct tm *t_st;
time(&timer);
printf("現在時刻: %.24s\r", ctime(&timer));
}

int main(void){
SetTimer(0,0,1000,tp);
while(getch()!=0x1b);
return 0;
}


943 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 04:53:52 ]
>>924
その本には char (*b)[8]がポインタの配列であると書いてるの?
そうなら子供の落書き帳にでもしちゃいなよ



944 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 04:55:35 ]
うあ?
途中から char *(b[8])の話になってる。すまんこ。

945 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 08:04:04 ]
select

946 名前:デフォルトの名無しさん [2009/10/28(水) 23:03:47 ]
>>924
> () > []

アホ

947 名前:デフォルトの名無しさん mailto:sage [2009/10/28(水) 23:38:34 ]
>>946
なんとなくカンテーレ

948 名前:921=919 mailto:sage [2009/10/29(木) 00:24:38 ]
>922

なんか、違う人間が同じ問にレスしてわけわかになっていますな。

>ならなんで
>char *(b[8]);


宣言子においては*と[]では[]の方が結びつきが強いので
char *b[8];

char *(b[8]);
は同じ。

かえって混乱するかもしれないけど『関数の仮引数の宣言部では』
void func(char b[N][8]);
void func(char b[][8]);
void func(char (*b)[8]);
は全て同等。

ついでに上のbと下のcは別物。下の宣言同士は全て同等
void g(char *c[N]);
void g(char *c[]);
void g(char **c);


>924さんはもちろん理解していると思うけど、
>間接参照するときは、(*b)[i]のようにしないと
いやそこは普通はb[0][i]になるよね。

949 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 00:56:38 ]
>>908-909
ざっと見て2つほど明らかなバグがあるけど面倒なので詳細は説明しない。
・2つ目のwhileの条件
・k

デバッガの使い方を覚えて1行ずつトレースしてみるのいいと思うよ。


950 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 02:19:12 ]
>>948
> >間接参照するときは、(*b)[i]のようにしないと
> いやそこは普通はb[0][i]になるよね。
ケースバイケースじゃないか?

951 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 11:05:30 ]
C言語を学び始めたのですが文字列の扱いで詰まってしまいました。
ある文字列について、任意のn番目の文字からx文字だけ参照したいときにはどんな関数を使えばよいのでしょうか?
strcpyやstrncpyでは先頭からしか見ることができないので困っています。

//////////////////////////////
char STR[]
char Buf[]

sprintf( Buf ,"123,456\0");
//////////////////////////////

このようなコードがあるときにSTRにBufの5文字目から7文字目まで(456)だけ
コピーするにはどうすれば…

任意のトークンで区切れるstrtokも状況によっては使えそうなのですが
挙動が分からずNullエラーになってしまったりして安定しません…

952 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 11:10:07 ]
>>951
sprintf(Buf, "123,456\0"+4);

953 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 11:12:24 ]
char Buf[10];
char *str = "123,456\0";
int start = 5;
int end = 7;
sprintf(Buf, "%.*s", end - start + 1, str + start - 1);



954 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 11:24:15 ]
速やか過ぎる返信ありがとうございます。

>>952のも>>953のもどちらも実行結果は正しいのですが
肝心の何故こうなるのかが理解できてません。ダメジャンorz

>>952の方のはsprintf関数の挙動を調べればなんとなく分かりそうなのですが(文字列操作に+4って何事?状態)
>>953のお方のは正直何が起こっているのかさっぱりです。ポイン・・・タ・・・?

とにかくとっかかりは掴めたのでもう少し調べてみようと思います。ありがとうございました

955 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 11:27:00 ]
Buf+4 は &Buf[4] と同じ・・・ と言ってもわからないだろうか?
正直、ポインタの理解なしに文字列操作は厳しいと思う

956 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 11:32:45 ]
>>955
>Buf+4 は &Buf[4] と同じ
だということを今知ったレベルでした。
ポインタはなんとなーく概念的にはつかんでいるものの使いこなすには至らず逃げてばかりだったので…
ネットワーク間でデータをやりとりしたいため文字列操作に手を出さざるを得なくなったのですが
ポインタの基礎から把握していないと駄目っぽいですね…

957 名前:953 mailto:sage [2009/10/29(木) 11:37:57 ]
こう書けば読めたりするだろうか。

char str[10];
strcpy(str, "123,456");
sprintf(Buf, "%.3s", str[5-1]); /* 5文字目の添え字は4 */

958 名前:951 mailto:sage [2009/10/29(木) 11:47:59 ]
>>957
お恥ずかしながらフォーマット指定子で .[整数] ってなんだっけ…レベルです。
そして%sでstr[4]を指定すると何故5文字目以降が参照されるのかもしっかり把握していません。

後者は
sprintf(Buf,"%s",str);
は str[0]から\0にぶつかるまで参照していたということなのでしょうか。

とにかく、今やってみたおかげで>>957に類するコードを入力したら
何故かは知らないけどこうなる!というのが分かる状態になりました…
がそんなんでは使いものになりませんよね

959 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 11:52:29 ]
>>958
プログラムは向いていない。

960 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 11:53:18 ]
そもそも"123,456\0"と言う風に'\0'を文字列リテラルに入れている時点で文字列操作を理解していないことが判るじゃないか。

961 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 12:02:16 ]
悔しいけども正論過ぎて泣いた。

本なりサイトなりで勉強し直すのが一番早そうですね。
丁寧に教えて下さった方、ありがとうございました。

\0を手動で入れていたのは、
ネットワークから送り込まれてくるデータがバッファに際限なく溜まっていってしまうため
区切りとして入れたのですがきっとそんなことになってしまう時点で何かがおかしいんですねわかります。

962 名前:953 mailto:sage [2009/10/29(木) 12:08:20 ]
>>958
%[整数1].[整数2]s
と書くと、最低でも[整数1]幅、最大でも[整数2]幅という指定になる
最低幅に足りない場合は先頭にスペースが埋められ、最大幅を超えた部分は切り捨てられる。

ネットワーク間でのデータやりとりだと、最大幅に足りない場合は後ろにスペースを埋めたいという
ニーズもあるかと思う。
その場合は
%-[整数1].[整数2]s
とすればいい。

そのうち慣れるからがんばれ。

963 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 12:15:15 ]
>>961
ネットワークから流れてくるものは文字列ではない。あれは只のバイト列だ。
と言う意識がないといつまでもカスみたいなコードしか書けないよ。
# 某SIerのプロパーがまさしくそれなんだが……
神経質な人は、文字列で扱うときはcharでバイト列として扱うときは(unsigned charをtypedefした)BYTEにしているくらいだ。
# それはそれで、文字列系の標準関数を使うたびにキャストする必要があるので時としてあれだけど。



964 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 12:18:29 ]
>>961
?
バッファに際限なくたまるというのは確かにそうなってる時点でなんか変だと思う。
recv近辺のコードを上げてくれたらなんか分かるかも。

965 名前:951 mailto:sage [2009/10/29(木) 12:27:47 ]
>>963
なるほど、覚えておくと見やすくなるだけでなく色々活用できるんですねえ…

>>963
今まで平気で文字列として扱ってきたのですがバイトだったのですか!
…それを知ったところで今すぐ何かが変わるわけじゃないのが不勉強なところですが
保存したレスをいつか発掘したら意味がちゃんと分かるようになってるといいなあ…

>>964
相談したいのは山々なのですが
ネットワーク周りはDXライブラリの関数を使用しているので
ここだとスレ違いな気がするのです。

966 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 12:40:43 ]
>>965
念の為に捕捉。
>963は、ナル文字で終端されていることがはっきりしている場合を文字列と言っている。
終端されていないものにはstrlen()やstrcpy()などの関数が使えないから、意識しておかないとね。
だからと言って、受信バッファより多めにメモリを確保して事前にクリアするなんてのは下策。
尚sprintf()の場合は、>962にあるようにサイズ制限ができるからバイト列に対しても使えなくはない。

967 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 12:46:22 ]
>>966
> >>963は、ナル文字で終端されていることがはっきりしている場合を文字列と言っている。
別に>>963がどうとかじゃないよね。
Cにおける文字列の定義の話でしょ。

968 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 13:02:58 ]
>>967
異論避け。それほど他意はない。

969 名前:デフォルトの名無しさん [2009/10/29(木) 14:38:26 ]
1から40までの数のなかで、3がつく数字とさんの倍数をすべて表示するプログラムを教えてください。

970 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 14:43:03 ]
>>969
puts("3 6 9 12 13 15 18 21 23 24 27 30 31 32 33 34 35 36 37 38 39");

971 名前:デフォルトの名無しさん [2009/10/29(木) 14:44:44 ]
>>969
#include <stdio.h>
#include <string.h>
int main(void) {
  int i;
  char buf[32];
  for(i = 1; i <= 40; i++) {
    sprintf(buf, "%d", i);
    if (i % 3 == 0 || strchr(buf, '3') != NULL) {
      printf("%d\n", i);
    }
  }
  return 0;
}

972 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 15:59:09 ]
#define _XOPEN_SOURCE
#include <stdio.h>
#include <unistd.h>
int main()
{
char a[100];

*a = crypt("hogehoge", "EV");
printf("%s", a);

return 0;
}
crypt関数について調べようと思ってこんなん作ったんだけどaに何も入らないのはなぜ?
crypt関数自体がアレなのかなと思って
int main()
{
char a[100];

  printf("%s", crypt("hogehoge", "EV"));

return 0;
}
を試しに実行してみたけどこれはまともに動いた。

973 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 16:12:20 ]
gcc -Wall



974 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 16:19:50 ]
>>972
char a[100]; の時、a は &a[0] と同じ
つまり、*a はa[0]と同じ
a[0] = crypt・・・
が変なのはわかるだろ。
strcpy使え。

975 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 16:22:14 ]
*a = crypt("hogehoge", "EV");

a[0] = (char)crypt("hogehoge", "EV");
と同じ

976 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 16:49:46 ]
C言語学びはじめてもうすぐ半年になるが、いつになったらタッチタイピングできるようになるんだ

977 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 16:57:47 ]
>>976
英語配列に変えてみた、、がまだ慣れない。

978 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 17:53:51 ]
>>976
プログラミングとタッチタイピングを同時に学ぼうと言うのがそもそも間違い。
プログラミングは、基本的にキー入力速度が速い必要はないからね。

979 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 18:11:08 ]
どうせなら C でタイピング練習ゲーム作ったらどうか。

980 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:11:55 ]
ビット演算について質問です
char aの上位4バイトに 64以下の整数char bを代入したい場合、
(a & 0b00001111) +  (b << 4)
でできるのはわかるのですが、
もっと単純な表記方法はあるでしょうか?

981 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:14:17 ]
ゲームセンターにあるタイピングオブザデッドに憧れてタイピング練習しはじめて
ローマ字覚える前にタッチタイピングマスターしちまったなぁ
最近出た第二弾はわからんがタイピング覚える気ならゾンビ打マジおすすめ
本当の意味でゲーム感覚で覚えられるタイピングソフト
他にもいろいろタイピングソフトやってみたがまともなのはこれしかなかった
スレチごめんね

982 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:17:20 ]
環境によっては
union {struct {unsigned ah:4; unsigned al:4} s; char c} a;
として
a.s.ah = b;
と書ける。
或いは、
a = (a % 16) + (b * 16);
とも書ける。
いずれの場合も、bが16以上の場合は破綻する。

983 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:18:43 ]
>>980
>char aの上位4バイトに 64以下の整数char bを代入したい場合、
char aの上位4ビットに 15以下の整数char bを代入したい場合、

の書き間違いかな?



984 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 20:19:17 ]
>>980
charの上位4バイトってなんだよpgr

985 名前:980 mailto:sage [2009/10/29(木) 20:19:56 ]
>982
どうも
4ビットって64じゃなくて16でしたね…
こんなんでビット演算とかやらない方が安全か

986 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 21:11:02 BE:284013465-DIA(352353)]
次スレ立てました
C言語なら俺に聞け(入門篇) Part 55
pc12.2ch.net/test/read.cgi/tech/1256818218/

987 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 22:10:01 ]
>>985

「こんなんで・・・」はないと思うぞ。
1ビットでも必要な時はビット演算をする。

そもそも何のためにやるのかだよね。

988 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:37:27 ]
>>957


989 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:47:58 ]
屁こくな

990 名前:デフォルトの名無しさん mailto:sage [2009/10/29(木) 23:52:11 ]
間違いの指摘するならちゃんと教えてやれよ。
まあ、うっかりミスだろうから指摘するまでもないが。

991 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 00:56:33 ]
>>982
そのunionの使い方って厳密には保証されないんじゃないっけ?

992 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 00:58:54 ]
俺にはその間違い探し難しすぎるぜ

993 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 08:44:31 ]
>>991
上下どちらのビットから割り付けるかは処理系定義なので
移植性はないけどもどっちかに決まっているはず。



994 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 09:46:08 ]
ume

995 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 09:50:06 ]
>>991
処理系によっては、妙な割り付け方をするかもしれないね。

996 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:02:19 ]
ume

997 名前:デフォルトの名無しさん [2009/10/30(金) 10:04:35 ]
age

998 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:18:54 ]
>>992
>957のことなら、& str[5 - 1]だ。

999 名前:デフォルトの名無しさん mailto:sage [2009/10/30(金) 10:18:59 ]
ume

1000 名前:デフォルトの名無しさん [2009/10/30(金) 10:21:41 ]
03e8

1001 名前:1001 [Over 1000 Thread]
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

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

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