C言語関係掲示板

過去ログ

No.1049 ファイル名を入力して開きたい

[戻る] [ホームページ]
No.13645

ファイル名を入力して開きたい
投稿者---なおぞう(2004/04/19 21:51:18)


test.txtというファイルがあります。
そのファイルの文中に1行付け加えて同じファイル名で保存する方法を教わりました。
それはうまくいったんですが、これだと他のファイル名の物では動きません。
ファイル名の違う複数のファイル(内容はほぼ一緒)に対して行えるようにするにはどのようにしたらいいでしょうか。
とっても困ってます。よろしくお願いします。

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

#define IN_FILE "a:\\test.txt"    ←ここを全てのテキストファイルが開けるか手入力で指定できるようにしたいんです。
#define OUT_FILE "a:\\test2.txt"

FILE *fileOpen(char *,char *);
void stringSeparate(char *,char,char *);

int main(void)
{
FILE *in_fp;
FILE *out_fp;
char line[256];
char leftString[256];

in_fp = fileOpen(IN_FILE,"r");
out_fp = fileOpen(OUT_FILE,"w");

while(fgets(line,256,in_fp) != NULL){
if(memcmp(line,"name-No",14) == 0){
stringSeparate(line,'-',leftString);

fprintf(out_fp,"%s-No\n!\nテスト\n",leftString);
}
else{
fprintf(out_fp,"%s",line);
}
}

fclose(in_fp);
fclose(out_fp);

remove(IN_FILE);

rename(OUT_FILE,IN_FILE);

return 0;
}

FILE *fileOpen(char *p_filename,char *p_mode)
{
FILE *fp;

fp = fopen(p_filename,p_mode);
if(fp == NULL){
fprintf(stderr,"ファイル[%s]を開く事ができません。\n",p_filename);
exit(1);
}

return fp;
}


void stringSeparate(char *p_line,char kugiriMoji,char *p_leftString)
{
char tempLeftString[256];
int i=0;

while(*p_line != '\0'){
if(*p_line != kugiriMoji){
tempLeftString[i] = *p_line;
p_line++;
i++;
}
else{
strcpy(p_leftString,tempLeftString);
p_leftString[i] = '\0';

return;

}
}
}


No.13646

Re:ファイル名を入力して開きたい
投稿者---goo(2004/04/19 22:13:50)


何がわからないのかわかりませんが

char buf[256];
FILE *f;
gets(buf);
f=fopen(buf,"r");

で済んでしまう話ではないのですか?

No.13649

Re:ファイル名を入力して開きたい
投稿者---RAPT(2004/04/20 00:20:04)


> char buf[256];
> FILE *f;
> gets(buf);
> f=fopen(buf,"r");
安全性を考えると、
fgets(buff, 255); のほうがいいかと。


No.13659

Re:ファイル名を入力して開きたい
投稿者---なおぞう(2004/04/20 11:25:00)


みなさま、返答ありがとうざいます。
ホントに恥かしいほど分からないもので。
多分今の自分にはかなり高度な事をやろうとしてるのですが
基本はこれからでとりあえずこういったものを作ろうとしてる訳で。。。
もうしばらくお付き合い頂けると幸いです。

>何がわからないのかわかりませんが
>
>char buf[256];
>FILE *f;
>gets(buf);
>f=fopen(buf,"r");
>
>で済んでしまう話ではないのですか?

↑これは最初に試したのですがそうすると
挿入したい文字1行が9行入ってしまうんです。
それで困ってしまって。


No.13650

Re:ファイル名を入力して開きたい
投稿者---NykR(2004/04/20 08:45:16)


投稿するときは【掲示板ご利用上の注意】を読みましょう。

* ソースを添付する際には「HTML変換ツール」で字下げしてください。 
* なるべく詳しく環境などの情報をお書きください。 



そのファイルの文中に1行付け加えて同じファイル名で保存する方法を教わりました。
手入力で指定できるようにしたいんです。

教える順番が間違ってるような。。。



char    format_str[64];
char    file_name[256];

sprintf(format_str, "%%zus", sizeof(file_name));
scanf(format_str, file_name);


べた書きなんでテストはしてませんけど。
# getsは file_nameの範囲を超えて(file_nameに)書き込んでしまうので、fgetsか、上記の書き方のほうがより安全です。
# fgetsの場合は改行文字まで書き込んでしまいますけど。

No.13651

Re:ファイル名を入力して開きたい
投稿者---YuO(2004/04/20 09:15:13)


sprintf(format_str, "%%zus", sizeof(file_name));

%256sという文字列を生成するのだから,
sprintf(format_str, "%%%zus", sizeof(file_name));

ではないかと。

No.13652

書式指定文字列について教えてください
投稿者---Cマニア(2004/04/20 10:08:53)


>%256sという文字列を生成するのだから,
>
sprintf(format_str, "%%%zus", sizeof(file_name));

>ではないかと。

 これはformat_strに"%256s"を格納するということですよね?
 %%は%、sはsとはわかりますが、%zuがわかりません。
 %zuはどういうものなのか宜しければ教えてください。

 それから↓を実行してみたのですが、format_strには
 "%256s"が格納されておらず、やはりわかりません。
 私は何か勘違いしているのでしょうか???宜しくお願いしますm(_ _)m


#include<stdio.h>

int main(void)
{
    char    format_str[64];
    char    file_name[256];

    sprintf(format_str, "%%%zus", sizeof(file_name));
    scanf(format_str, file_name);

    printf("file_name : %s\n", file_name);
    printf("format_str : %s\n", format_str);

    return 0;
}

実行結果
abcdefg    ← 入力 
file_name :
format_str : %%zus



No.13653

Re:書式指定文字列について教えてください
投稿者---REE(2004/04/20 10:30:18)


> これはformat_strに"%256s"を格納するということですよね?
> %%は%、sはsとはわかりますが、%zuがわかりません。
> %zuはどういうものなのか宜しければ教えてください。
>
> それから↓を実行してみたのですが、format_strには
> "%256s"が格納されておらず、やはりわかりません。
> 私は何か勘違いしているのでしょうか???宜しくお願いしますm(_ _)m
>

私にも分かりません。
zを削除して下記のようにするといいでしょう。
"%%%us",

No.13656

Re:書式指定文字列について教えてください
投稿者---Cマニア(2004/04/20 10:50:15)


>私にも分かりません。
>zを削除して下記のようにするといいでしょう。
>"%%%us",

 なるほど、ただの%uでしたか。%zuなんて初めて見るので
 びっくりしました。ありがとうございましたm(_ _)m

No.13657

Re:書式指定文字列について教えてください
投稿者---Cマニア(2004/04/20 10:52:00)


> なるほど、ただの%uでしたか。%zuなんて初めて見るので
> びっくりしました。ありがとうございましたm(_ _)m

 と思ったらあったのですね・・・(-_-;)
 YuOさんありがとうございます。

No.13654

Re:書式指定文字列について教えてください
投稿者---YuO(2004/04/20 10:48:15)


> %zuはどういうものなのか宜しければ教えてください。

zはsize_tを扱うためのlength modifierです。

hh [C99]
signed char / unsigned char / signed char * (n)
h
short int / unsigned short int / short int * (n)
l
long int / unsigned long int / long int * (n) wint_t [C95] / wchar_t * (s) [C95] / ignore (aAeEfFgG) [C99]
ll [C99]
long long int / unsigned long long int / long long int * (n)
j [C99]
intmax_t / uintmax_t / intmax_t * (n)
z [C99]
size_t / size_t * (n)
t [C99]
ptrdiff_t / ptrdiff_t * (n)
L
long double (aAeEfFgG)


[]内は定められた規格,()内は利用可能な変換指定子。
変換指定子を明示していない場合はd, i, o, u, x, Xで利用可能。


> それから↓を実行してみたのですが、format_strには
> "%256s"が格納されておらず、やはりわかりません。

標準Cに非対応のコンパイラを使っているのでしょう。
#ISOやJISといった規格は最新の物が有効なので,標準CとはC99を指す。

%zuを%uにして,sizeof(file_name)を(unsigned)sizeof(file_name)に変更すれば,
たぶん問題なく動くと思います。


No.13667

Re:書式指定文字列について教えてください 【Eratta Only】
投稿者---YuO(2004/04/20 17:52:55)


細かい修正をば。

l
long int / unsigned long int / long int * (n) wint_t [C95] / wchar_t * (s) [C95] / ignore (aAeEfFgG) [C99]

l
long int / unsigned long int / long int * (n) / wint_t [C95] / wchar_t * (s) [C95] / ignore (aAeEfFgG) [C99]

区切りの/が抜けていました。

L
long double (aAeEfFgG)

L
long double (eEfgG) / long double (aAeEfFgG) [C99]

C90/C95では,a, A, Fの変換指定子は存在しないので。

No.13679

Re:書式指定文字列について教えてください
投稿者---請小心(2004/04/21 15:21:00)


>#ISOやJISといった規格は最新の物が有効なので,標準CとはC99を指す。

コメントにコメントつけるのもどうかと思いましたが、この「最新の物が有効」は嘘です。
標準化団体は最新のものを頒布していますが、最新ではないものも有効です。
特にCの場合、C99は壊れていますので、これが普及することはないでしょう。
最新ではないものがいつまで有効なのかといえば、それは“de facto”に拠ることになります。

# 事実上の標準CはC89

No.13680

Re:書式指定文字列について教えてください
投稿者---YuO(2004/04/21 18:28:27)


>>#ISOやJISといった規格は最新の物が有効なので,標準CとはC99を指す。
>コメントにコメントつけるのもどうかと思いましたが、この「最新の物が有効」は嘘です。
>標準化団体は最新のものを頒布していますが、最新ではないものも有効です。

最低でも,ISO/IEC 9899に関して,ISO/IEC 9899:1990は取り消され,
ISO/IEC 9899:1999に置き換えられています。
ISO/IEC 9899:1999のForeword部分に,

The second edition cancels and replaces the first edition, ISO/IEC 9899:1990, as amended and corrected by ISO/IEC 9899/COR 1:1994, ISO/IEC 9899/AMD 1:1995, and ISO/IEC 9899/COR 2:1996.


とあります。もちろん,Forewordは規格の規定に含まれませんが,
規格自体の取り扱いはこれ以外に従うものはないと思います。
#ISO/IEC 2022:1994でもISO/IEC 2022:1986を取り消して置き換えています。

ちなみに,旧規格が有効でない例として,
JIS X 0208:1997の附属書2,RFC1468符号化表現というものがあります。
RFC 1468自体は1/11 2/4 4/0で切り替えられる符号化文字集合として,
JIS X 0208-1978と規定しています。
しかし,JIS X 0208:1997の附属書2では,
JIS X 0208:1997の文字を入れ替えた物として定めています。
JIS X 0208-1978(C 6226-1978)は旧規格であり,JISとしては既に無効な規格であるから,
JIS X 0208-1978を参照するようなことはできなかったことが伺えます。
#附属書2に関する部分はネット上で調べた結果ですが。


>最新ではないものがいつまで有効なのかといえば、それは“de facto”に拠ることになります。
># 事実上の標準CはC89

規格としてISO/IEC 9899:1990(その追補や訂正を含む)は過去の物であり,
ISO/IEC 9899:1990に適合したからと言ってそれはISO規格に適合していることを意味しません。

また,JIS規格やISO規格が存在する以上,
それに適合していることが「標準」たる条件ではないでしょうか。
2002年までであれば,日本国内に限りますが,
JIS X 3010-1996をもって「標準」と言い張ることはできたでしょうが,
JIS X 3010は2003年に改正されているので,C95をもって「標準」と言うのは無理があります。
#C90は論外。ISO規格は1995年に,JIS規格は1996年に,それぞれ改正された。


No.13681

Re:書式指定文字列について教えてください
投稿者---monkey(2004/04/21 19:02:32)


横から失礼します。
C99での拡張機能に対応した処理系がまだ普及していないのは事実だと思います。
しかし、そのことによってC99が有効でないと言うのであれば、それは技術の進歩や規格化の意義を認めないことに等しいのではないでしょうか。
規格は製品の品質を保証するためにあるものと理解しています。
そして、C99は1企業や特定団体が提案したものでなく、既にISO、JISでオーソライズされた規格です。
趣味のプログラミングならともかく、職業としてプログラムを製造するならば、規格外でも良いということはあり得ないと考える次第です。
ただし、

> C99は壊れていますので、これが普及することはないでしょう。

が事実だとすれば(ワタシには確認するような能力はありません)、ISOやJISの大失策ということになります。
是非、関係者にどこをどう直すべきなのかを教えてあげてください。
また、一般のCプログラマのために、この場でもC99の問題点を解説していただければ幸いです。

No.13658

Re:ファイル名を入力して開きたい
投稿者---NykR(2004/04/20 11:11:36)


%256sという文字列を生成するのだから,
sprintf(format_str, "%%%zus", sizeof(file_name));
ではないかと。


あ゙、そうですね。
元のやり方だとformat_strに"%zus"が格納されて、scanfで、型が違うという警告がでます。

No.13655

Re:ファイル名を入力して開きたい
投稿者---マルチポスト×(2004/04/20 10:49:59)


http://www-cc.ee.tokushima-u.ac.jp/cgi-bin/cboard.cgi?log=&v=739&e=msg&lp=739&st=0