C言語の初心者です。
コマンドプロンプトで「./a.out <text.txt」とうつと、text.txtのデータを取得し、表示するプログラムをつくろうと思っています。
試行錯誤の結果
#include <stdio.h>
main(){
char abc;
scanf("%s",&abc);
printf("%c",abc);
}
だとエラーもなくコンパイルできるのですが、肝心のファイルの中身が一文字までしか表示されません。
これはchar abcでabcを一文字だけの変数にしているからみたいですが、調べてみたのですがどうもここから先に進めません。
どこをどのように変えれば良いですか?お願いします。
No.3ベストアンサー
- 回答日時:
配列は既に学習済みですか?
配列を使わず、scanfとprintfを使って書くならこんな感じ。
#include <stdio.h>
int main() {
char abc;
while (scanf("%c", &abc) != EOF) {
printf("%c", abc);
}
}
配列が使えるならscanfじゃなくてfgetsを使うかな。
あと、mainの型(int)はちゃんと書く癖をつけましょう。
この回答への補足
回答ありがとうございます。
配列はおおまかにわかります。元々他のプログラミング言語は幾つかやったことがあってC言語は今回が初めてです。
いただいたものはコンパイルではエラーが出ず、実行してみると、一番最後の文字だけ表示されました。
No.10
- 回答日時:
僕のおすすめは 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 みたいな感じで拡張してあげてください。
No.9
- 回答日時:
おっと、このままだとwindowsじゃなかったらダメでした。
その時についてはいってください。
あと、上の
void test(
をコピペしてチョロっと書きなおした際
void main(){
にしてしまいましたが、
実際には
int main(void)
とか
int main(int argc, char *argv[])
ぐらいが、大抵そのまま移植して通用する理想形だったはずです。
そこは訂正しておきます。
No.8
- 回答日時:
にゃるほど、そういう御用件でしたか。
では、ちょいと変則(?)的な方法を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);
}
解説は敢えて一つも書かないので、分からない箇所がありましたら調べてみてください。
No.7
- 回答日時:
ついでに言うと。
単に1文字入力なら
fgetc,getc,getchar 等
1文字出力なら
fputc,putc,putchar 等
を使うのが、よいでしょう。
scanf,printfによる「書式変換」など必要無いのですから。
No.6
- 回答日時:
いろいろ回答が…。
私が書いている間にも増えていたようで。
配列を使う。
というのが一般的ではありますが、今回のリダイレクトの場合入力されるデータのサイズは予め知る事ができません。
# 特に、コンパイル実行時に知る事ができません。
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)の場合は、ポリタンクいっぱいになっても注ぎ続けて周りが水浸し。
という状況です。
No.4
- 回答日時:
そもそも…
>char abc;
>scanf("%s",&abc);
char型変数1個に文字列受け取ろうとすることが間違いです。
250mlのコップ(char型変数1個)にお風呂の水(数百リットル)を全部納められますか?
char型変数なので、
>printf("%s",abc);
も間違いです。
abcに格納された「値」を「文字列への先頭アドレス」として解釈して、
0x00000000~0x000000ffのどこかからアクセスしますから…
たいていはその後吹っ飛びます。
# ライブラリによっては0x00000000の時に"(null)"という文字列を返す場合はありますが…。
>どこをどのように変えれば良いですか?
「標準入力から1文字読み込んで(標準出力へ?)出力する」というのをEOFが入力されるまで繰り返す。
ということになるかと。
そんなサンプルはふつ~に転がっているでしょうからキーワードで検索して下さい。
No.2
- 回答日時:
単にこういうことではないでしょうか?
#include <stdio.h>
main(){
char abc[128]; //終端文字含め128文字までならOK
scanf("%s",abc);
printf("%s",abc);
}
この回答への補足
回答ありがとうございます。
その方法だと無事コンパイル出来ました。
しかし、実際にプログラムを実行してみると一文字(または一行目の改行の一つ前の文字まで?)しか表示されません。
text.txtは一文字ごとに改行されているファイルです。
目的としては一行ごとに配列に収める方法でも大丈夫です。
No.1
- 回答日時:
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’
とエラー?が出てしまいます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- Excel(エクセル) エクセルの数式で教えてください。 2 2023/03/09 10:07
- Excel(エクセル) エクセルの数式で教えてください。 1 2023/02/08 09:05
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- Excel(エクセル) Excelの関数で実現可能か知りたいです 5 2023/08/06 08:58
- その他(開発・運用・管理) 【至急】.htaccessによるディレクトリ単位でのリダイレクト 2 2023/08/10 13:46
- Excel(エクセル) エクセルの数式で教えてください。 2 2023/03/09 08:37
- Excel(エクセル) EXCELで同一セル内で自動的に改行されてしまう(難問) 6 2023/04/16 00:51
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
str系関数を使わずに二つの文字...
-
配列をnビットシフトする
-
Win32APIでのエディットボック...
-
型変換
-
全角文字を含んだ文字の並びを...
-
c言語です。
-
下記のプログラムがコンパイラ...
-
c言語の問題の説明、各所ごとに
-
strlen関数と同じ働きをする関...
-
C言語で、入力された、文字列を...
-
double型の値をchar配列に変換...
-
C言語の入力した文字を反転させ...
-
enumの記述について。
-
c言語でソーベルフィルタが作り...
-
宣言による処理の重さ
-
文字列の中から必要なデータを...
-
CStringをwchar_tに変換したい
-
間接操作のレベルとは
-
'const char *' 型は 'char *' ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
charでの計算?
-
C言語のfor文です。 繰り返しの...
-
charからLPTSTRへの変換方法
-
文字列から空白を取り除きたい...
-
C言語の入力した文字を反転させ...
-
'const char *' 型は 'char *' ...
-
配列をnビットシフトする
-
str系関数を使わずに二つの文字...
-
int main()の・・・
-
atoi( ) の反対をやりたい
-
c++ 文字列を入力して、一文字...
-
CStringをwchar_tに変換したい
-
switch文で文字を比較すること...
-
干支のプログラム
-
絶対パスからのファイル名の切...
-
3桁区切(コンマ)記号をつけ...
-
間接操作のレベルとは
-
間接参照のレベルが異なっています
-
【C言語】文字型と整数型の違い
おすすめ情報