アプリ版:「スタンプのみでお礼する」機能のリリースについて

C言語の初心者です。
コマンドプロンプトで「./a.out <text.txt」とうつと、text.txtのデータを取得し、表示するプログラムをつくろうと思っています。
試行錯誤の結果
#include <stdio.h>
main(){
char abc;
scanf("%s",&abc);
printf("%c",abc);
}
だとエラーもなくコンパイルできるのですが、肝心のファイルの中身が一文字までしか表示されません。
これはchar abcでabcを一文字だけの変数にしているからみたいですが、調べてみたのですがどうもここから先に進めません。
どこをどのように変えれば良いですか?お願いします。

A 回答 (10件)

配列は既に学習済みですか?


配列を使わず、scanfとprintfを使って書くならこんな感じ。
#include <stdio.h>
int main() {
char abc;
while (scanf("%c", &abc) != EOF) {
printf("%c", abc);
}
}
配列が使えるならscanfじゃなくてfgetsを使うかな。
あと、mainの型(int)はちゃんと書く癖をつけましょう。

この回答への補足

回答ありがとうございます。
配列はおおまかにわかります。元々他のプログラミング言語は幾つかやったことがあってC言語は今回が初めてです。
いただいたものはコンパイルではエラーが出ず、実行してみると、一番最後の文字だけ表示されました。

補足日時:2011/12/24 21:54
    • good
    • 1

僕のおすすめは 1行ずつリストをつなげていく方法ですね。



ヒントは fgets, strdup, realloc, strcat かな?

fgetsのファイルポインタには stdinを渡してあげていください。
リダイレクトは標準入力として読み取るので。。
#include <stdio.h>にはいっています

コンパイルも何もしていないけれどイメージはこんな感じ
typedef struct tagLINES
{
char *line;
struct tagLINES next;
} LINES;

char buf[BUSIZ];
LINES top = { NULL, NULL } ;
LINES next = top.next;
while( fgets(buf, sizeof(buf), stdin) != NULL )
{
next = calloc( 1, LINES );
next->line = strdup( buf );
next = next->next;
}

fgets は 読み切れなかったとき改行とかが含まれないので
行が継続しているかどうかはフラグを作って制御してください。

行が継続したところにstrdupは使えないので
char *wkP = (char*)realloc( next->line, BUFSIZ*times+strlen(buf)+1);
next->line = wkP みたいな感じで拡張してあげてください。
    • good
    • 0

おっと、このままだとwindowsじゃなかったらダメでした。


その時についてはいってください。

あと、上の
void test(
をコピペしてチョロっと書きなおした際
void main(){
にしてしまいましたが、

実際には
int main(void)
とか
int main(int argc, char *argv[])
ぐらいが、大抵そのまま移植して通用する理想形だったはずです。

そこは訂正しておきます。
    • good
    • 0

にゃるほど、そういう御用件でしたか。



では、ちょいと変則(?)的な方法をw
ご質問のコードの
「printfでの"%c"」を意地でも使ってみよう

という謎の意気込みのコードです(笑)


#include <windows.h>
#include <stdio.h>

void test( const char* const fn ){

FILE* fp;
long filesize;
char* data;
int i;

if ( fopen_s( &fp, fn, "rb" ) ) return;

fseek( fp, 0, SEEK_END );
filesize = ftell( fp );

fseek( fp, 0, SEEK_SET );

data = (char*)malloc( filesize );

if ( !data ){ fclose(fp); return; }

fread( data, 1, (size_t)filesize, fp );
fclose( fp );

for ( i=0; i<filesize ;++i ) printf( "%c", data[i] );

free( data );

}

void main(){

char c[100];
scanf_s( "%s", c, 100 );
test( c ); Sleep(2000);

}


解説は敢えて一つも書かないので、分からない箇所がありましたら調べてみてください。
    • good
    • 0

ついでに言うと。


単に1文字入力なら
fgetc,getc,getchar 等
1文字出力なら
fputc,putc,putchar 等
を使うのが、よいでしょう。
scanf,printfによる「書式変換」など必要無いのですから。
    • good
    • 1

いろいろ回答が…。


私が書いている間にも増えていたようで。


配列を使う。
というのが一般的ではありますが、今回のリダイレクトの場合入力されるデータのサイズは予め知る事ができません。
# 特に、コンパイル実行時に知る事ができません。


250mlのコップ(char型変数1個)でダメなら、もっと大きい入れ物にするぜっ!!
# 配列の場合、そういう考え方ではないのですが…
ということで18リットルのポリタンク(char型変数72個分)を用意して…お風呂の水を投入!!
あふれました……。
だったら、もっとデカく競泳用プールを確保!!(char型変数10000000000個分)
おお、余裕でお風呂の水が入りました。
……無駄な場所がいっぱいありますが。
そもそも、10坪の土地に競泳用プールは作れません。
# ローカル変数はスタック領域に作成されるコトが多いですが、そのスタック領域は通常そんなに大きくありません。


ループでぐるぐる回す方法がありますが…
コップ1個で…というのは。
 1)コップに風呂の水を入れる。(EOFだったら掬い終わり)
 2)中身を出力。(使い終わったのでコップの中身を捨てる)
 3)1)に戻る。
を繰り返しています。

sanf()の書式で、%sでも取り込みサイズを指定できるはずです。
scabf("%100s", abc)でchar abc[100]に受け取れます。
上のコップの例がポリタンクに変わるイメージになります。
# ループで回さなければ最初の1回だけ。
サイズ指定しないでscabf("%s", abc)の場合は、ポリタンクいっぱいになっても注ぎ続けて周りが水浸し。
という状況です。
    • good
    • 0

>char abc;


は1バイトの領域を確保するのみです。
配列にすれば可能と思います。

>char abc;

char abc[100];
    • good
    • 0

そもそも…


>char abc;
>scanf("%s",&abc);
char型変数1個に文字列受け取ろうとすることが間違いです。

250mlのコップ(char型変数1個)にお風呂の水(数百リットル)を全部納められますか?

char型変数なので、
>printf("%s",abc);
も間違いです。
abcに格納された「値」を「文字列への先頭アドレス」として解釈して、
0x00000000~0x000000ffのどこかからアクセスしますから…
たいていはその後吹っ飛びます。
# ライブラリによっては0x00000000の時に"(null)"という文字列を返す場合はありますが…。


>どこをどのように変えれば良いですか?

「標準入力から1文字読み込んで(標準出力へ?)出力する」というのをEOFが入力されるまで繰り返す。
ということになるかと。
そんなサンプルはふつ~に転がっているでしょうからキーワードで検索して下さい。
    • good
    • 0

単にこういうことではないでしょうか?



#include <stdio.h>
main(){
char abc[128]; //終端文字含め128文字までならOK
scanf("%s",abc);
printf("%s",abc);
}

この回答への補足

回答ありがとうございます。
その方法だと無事コンパイル出来ました。
しかし、実際にプログラムを実行してみると一文字(または一行目の改行の一つ前の文字まで?)しか表示されません。
text.txtは一文字ごとに改行されているファイルです。

目的としては一行ごとに配列に収める方法でも大丈夫です。

補足日時:2011/12/24 21:52
    • good
    • 0

printf("%c",abc);



printf("%s",abc);

この回答への補足

ありがとうございます。
その記述でコンパイルすると
a.c: In function ‘main’:
a.c:7: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
a.c:7: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
とエラー?が出てしまいます。

補足日時:2011/12/24 16:56
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!