マンガでよめる痔のこと・薬のこと

ランダム関数で数字を表示し、それをファイルに保存し、そのファイルの名を好きな文字で決めるというプログラムを作ったのですが、
一回目にランダム関数で数字を保存して、Aという名前のファイルに入れた後、二回目に同じ作業をして同じファイル名にしたら上書きされて、一回目とは違うランダムな数字が表示されてしまいました。
もうこの名前のファイルは存在します、という意味の部分を入れなければならないと思うのですが、どういった肯定を取り入れればファイルが存在していることがわかるのでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (4件)

★アドバイス


>同じ名前のファイルを作った場合に上書きしてしまうのですが、どうすれば上書きしないで保存できるのでしょうか?
・書き込むファイルの有無を調査することで防げます。
 単純な方法では、fopen を使って読み込みでオープンできなければ、ファイルが存在している
 可能性が高いです。でも、もっと安全にするには、ファイルを検索する関数などを使って検索
 出来なければ(見つからなければ)存在しないと判定します。
・C関数の標準では便利な関数がなかなかありませんので、Win32 API などを使うとファイルの
 有無をチェックできます。→Windows OS の場合はね。
・PathFileExists() API 関数で有無をチェックできます。
 使い方は
 
 if ( PathFileExists(filename) ){
  /* ファイルは既に存在します */
 }
 else{
  /* ファイルが無いため、新規作成します */
 }
 こんな感じで使います。
・なお、使うには #include <shlwapi.h> をインクルードして shlwapi.lib をインポートライブラリ
 として追加する必要があります。分かりますか?意味。
・OS やコンパイラの環境が全く分からないため、これ以上のアドバイスは出来ません。
・以上。参考に!

参考URL:http://nienie.com/~masapico/api_PathFileExists.h …
    • good
    • 0

環境が不明ですが...



#include <unistd.h>

int ret;

/* ファイルが存在するか調べる */
ret = access( "A", F_OK );
if( ret == 0 ){
/*
* ファイルが存在するときの処理
*/
}
else{
/*
* ファイルは存在しない。新規のファイルを作成する。
*/
}
    • good
    • 0

ANo.1です。

ファイルがロックされている場合はNULLを返す事があるので、その場合にはファイルが存在しない事にはならないですね。
正確に取得するには、OSと処理系を特定しないと難しそうです。
    • good
    • 0

fopen("A", "r") がNULL以外を返したら"A"は存在します。


すぐにfcloseしてください。
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qファイル出力の場所を指定

現在C++にてhtmlファイルを出力するプログラムを作っているのですが、出力場所を指定することはできるのでしょうか?(現在はそのプログラムソースが保存されている場所と同じファイル内に出力されますが、それをデスクトップに出力するなど。)
もし、方法がありましたら、教えてください。
ソースや参考HPのURLなどのせていただけたらありがたいです。
環境はVisualStudio.NET2003です。
よろしくお願いします。

Aベストアンサー

単にファイル名の前にパスを指定する。

絶対パス指定
fp=fopen("c:/temp/test.txt","w");

相対パス指定
fp=fopen("./hoge/test.txt","w");


デスクトップはOSやユーザによって場所が異なるので、少し面倒です。
XPの場合環境変数を利用してこんな感じで出来ると思います。

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

void main(void)
{
FILE *fp;
char fname[1024];
strcpy(fname,getenv("USERPROFILE"));
strcat(fname,"/デスクトップ/test.txt");
fp=fopen(fname,"w");
//処理
fclose(fp);
}

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Qファイル読み書き方法について(r+)

現在ファイルへのc言語でファイル書き換えを行おうとしているのですが
その部分だけ表すとこんな感じです。
※多少省いていますので括弧の数等の間違えがあっても見逃してください。
if((fp = fopen("aaa.txt", "r+")) == NULL)
;
else{
     while((ch = fgetc(fp)) != EOF){
       if(ch == '\n'){
         name[i] = '\0'
         i = 0;
         continue;
       }
       name[i] = ch;
       i++
       if(strcmp(name, name_a){
         fprintf(fp, "%s", coment);
       }
     }
}
ファイルを読み込んでいって、ある名称が見つかったらその後ろの
コメントを更新するというプログラムなのですが。
fprintfまで着ていることは確認できたのですが、なぜか値が書き換わりません。

c言語ではファイル書き換えはあまり一般的ではないということは聞いていて、
以前はすべて読み込んで、一部分を変えてすべて書き込む方法をとって
いましたが、効率が悪い気がしたのでこのやり方を試しています。

1 やり方、関数の使い方が間違っているならば正しい方法を教えてください。
2 そもそも"r+"の使い方がおかしい場合は元のやり方でやります。ただし
  "r+"の使い方が詳しく乗っているサイトが見つからなかったので、
  わかりやすいサイト等ありましたら、教えてください。
3 ファイル読み書きで検索するとf_seekなる言葉をよく見かけるのですが、
  あれを使わないとだめなんでしょうか?

1つでもいいので教えてください。

現在ファイルへのc言語でファイル書き換えを行おうとしているのですが
その部分だけ表すとこんな感じです。
※多少省いていますので括弧の数等の間違えがあっても見逃してください。
if((fp = fopen("aaa.txt", "r+")) == NULL)
;
else{
     while((ch = fgetc(fp)) != EOF){
       if(ch == '\n'){
         name[i] = '\0'
         i = 0;
         continue;
       }
       name[i] = ch;
       i++
       if(strcmp(...続きを読む

Aベストアンサー

# 検証していないので ...
     while((ch = fgetc(fp)) != EOF){
       if(ch == '\n'){
         name[i] = '\0'
         i = 0;
         continue;
       }
       name[i] = ch;
       i++
       if(strcmp(name, name_a){
         fprintf(fp, "%s", coment);
       }

     while((ch = fgetc(fp)) != EOF){
       if(ch == '\n'){
         name[i] = '\0'
         i = 0;
         continue;
       }
       name[i] = ch;
       i++
       if(strcmp(name, name_a){
         fseek( fp, 0, SEEK_CUR );
         fprintf(fp, "%s", coment);
         fseek( fp, 0, SEEK_CUR );
       }
といった具合にして fseekで挟んでみましょう

もしくは
ftelで現在位置を取得
ファイルの先頭へfseek
元位置にfseek
書き込み
ftelで現在位置を取得
ファイルの先頭へfseek
元位置にfseek
としたほうがいいのかも ...

VC++のヘルプでは
r+/w+での読み書きのモード変更時には fsetpo/fseek/rewindのいずれかを実行しなさい
と明記されていました

# 検証していないので ...
     while((ch = fgetc(fp)) != EOF){
       if(ch == '\n'){
         name[i] = '\0'
         i = 0;
         continue;
       }
       name[i] = ch;
       i++
       if(strcmp(name, name_a){
         fprintf(fp, "%s", coment);
       }

     while((ch = fgetc(fp)) != EOF){
       if(ch == '\n'){
         name[i] = '\0'
    ...続きを読む

Qfgetsなどのときのstdinのバッファを消すには?

こんにちは,今C(C++でない)を使用しています。
たとえば,
char str[20]
fgets(str,sizeof(str),stdin)
としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。

C++などでは
fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。

よろしくお願いします。

Aベストアンサー

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ.
末尾に'\n'が出るまで掃出せばいいんですよね.

fgets(str, sizeof(str), stdin);
if ( str[strlen(str)-1] != '\n' ){
while( getchar() != '\n' );
}

でいいんだ.失礼しました.

Qファイル名に日付の挿入

Webやここで検索していてもわかりませんでした。お願いします。
通常ファイル名の作成はfopen("ファイル名","wなど")ですが、目標としてはプログラムで今日の日付を取得し、「ファイル名050420」という風に付け加えたいのですがどうすればできますか?

Aベストアンサー

日付を含む文字列を作成するようにすればうまくいきます。

time_t t;
char fname[32];

t = time(NULL);
strftime(fname, sizeof(fname), "basename%y%m%d.log", localtime(&t));
で出来上がったfnameでfopen()してください。

QC言語で文字列をかえす正しい書き方が知りたいです?

C言語で次の警告が表示されます。
文字列を返したいのですが、正しい書き方はどのようにすれば良いのでしょうか?


jci.h(20) : warning C4172; ローカル変数またはテンポラリのアドレスを返します。


char *test(char *a, int b)
{
char str[BUFSIZ];
return str; <------

}

Aベストアンサー

再入可能にするかどうかで、回答は変わります。

A.2度呼び出した場合に前のデータを破壊してもよいケース(再入不可能)

char *test(...)
{
static char str[BUFSIZ]; // static指定でメモリは静的に確保されます。

...

return str;
}

B.2度呼び出した場合に前のデータを破壊しないケース(再入可能)
B-1.mallocを使ってもいいケース
char *test(...)
{
char *str;
str = malloc(BUFSIZ);
if(str == NULL) return NULL; // エラー

...

return str;
}
この場合は、呼び出し元でちゃんとfreeしましょう。

B-2.呼び出し元でメモリを確保するケース
(注意:同じアドレスを指定して複数回呼び出すと、メモリ内容は当然破壊されます)
char *test(char *str, ...)
{

...

return str;
}
これは#1の方の回答と同じです。

B-3.B-1/B-2の複合
(注意:NULL以外の同じアドレスを指定して複数回呼び出すと、メモリ内容は当然破壊されます)
char *test(char *str, ...)
{
if(str == NULL)
{
str = malloc(BUFSIZ);
if(str == NULL) return NULL; //エラー
}

...

return str;
}

こんなところですかね。

再入可能にするかどうかで、回答は変わります。

A.2度呼び出した場合に前のデータを破壊してもよいケース(再入不可能)

char *test(...)
{
static char str[BUFSIZ]; // static指定でメモリは静的に確保されます。

...

return str;
}

B.2度呼び出した場合に前のデータを破壊しないケース(再入可能)
B-1.mallocを使ってもいいケース
char *test(...)
{
char *str;
str = malloc(BUFSIZ);
if(str == NULL) return NULL; // エラー

...

return str;
}
この場合は、呼び...続きを読む

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

Q#defineの定数を文字列として読み込む

#define A "xxx"
#define B "yyy"
と定義しておいて

scanf("%s", str)
で読み込んだ文字列strが
"xxx"だった場合、"yyy"だった場合のように分岐したいのですが
このとき

if(str == "xxx")
のように中身を指定するのではなく

if(str == AA)
のように定数で分岐させることってできますか?

上記のままではできませんが、何か特別な関数とかでできるのでしょうか?

Aベストアンサー

こんにちは。

やりたいことの解釈ですが、(※勘違いの場合はすみません。)

1)マクロの名前(定義名)が文字列として格納された文字列 str があるとする。
 例)
   #define A "xxx"  //マクロ名=A
   char str[] = "A";   //"A"はマクロ名

2)上記の文字列 str を関数 func に渡す際に、マクロ名ではなくそのマクロで
  定義された文字列を渡したい。
 例)
   func( str );    //←この場合
    ↓
   func( "xxx" );  //←として展開される

ということで宜しいでしょうか?

だとした場合、少し回りくどいやり方かもしれませんが、以下のような文字列
変換用のマクロを定義してみては如何でしょうか?
※基本的には、他の回答者の方と同じように strcmp関数 を使用します。

■マクロ例
==============================
//文字列を定義したマクロ …※1
#define A "xxx"
#define B "yyy"

//引数を文字列として取得するマクロ
#define GETSTR(x) #x

//引数をマクロ名としてそのマクロで定義された文字列を取得するマクロ …※2
//注)<string.h>がインクルードされていることを前提とする
#define STR2MAC(str) \
!strcmp(str,GETSTR(A))? A : \
!strcmp(str,GETSTR(B))? B : str
==============================

上記マクロを使用して、関数 func にマクロ名が格納された文字列 str を
渡す場合は、
   func( STR2MAC( str ) );
のような記述になります。

前提として、※2のマクロ内でstrcmp関数を用いて文字列の照合を行って
いますので、<string.h>のインクルードが必要になります。

また、※1の文字列を定義するマクロの種類(パターン)を増やす場合、
※2のマクロの判定文もそれに合わせて増やす必要があります。

上記のマクロを使用したサンプルソースを下記に掲載致します。
注)エラー処理は行っていません。

■サンプルソース
==============================
#include <stdio.h>
#include <string.h>

//文字列を定義したマクロ
#define A "xxx"
#define B "yyy"

//引数を文字列として取得するマクロ
#define GETSTR(x) #x

//引数をマクロ名としてそのマクロで定義された文字列を取得するマクロ
//注)<string.h>がインクルードされていることを前提とする
#define STR2MAC(str) \
!strcmp(str,GETSTR(A))? A : \
!strcmp(str,GETSTR(B))? B : str

//プロトタイプ
void funcHoge( const char *str );

int main(void)
{
char sArg[128];

printf( "A or B ?>" );
scanf( "%s", sArg );

printf( "string1: %s\n", sArg );
funcHoge( STR2MAC(sArg) );

return 0;
}

void funcHoge( const char *str )
{
printf( "string2: %s\n", str );
}
==============================

■上記サンプルの実行結果
≫実行その1≪
A or B ?>A
string1: A
string2: xxx

≫実行その2≪
A or B ?>B
string1: B
string2: yyy

≫実行その3≪
A or B ?>hoge
string1: hoge
string2: hoge

以上です。

こんにちは。

やりたいことの解釈ですが、(※勘違いの場合はすみません。)

1)マクロの名前(定義名)が文字列として格納された文字列 str があるとする。
 例)
   #define A "xxx"  //マクロ名=A
   char str[] = "A";   //"A"はマクロ名

2)上記の文字列 str を関数 func に渡す際に、マクロ名ではなくそのマクロで
  定義された文字列を渡したい。
 例)
   func( str );    //←この場合
    ↓
   func( "xxx" );  //←として展開される

ということで宜しいでしょう...続きを読む

Qファイルの中身検索と表示

Cでの作成についてなんですが、
fopenでテキストファイルを開き、テキストの中身の
特定文字が含まれている行を新に作ったファイルの中に
書き込みたいんですが、テキストの中身の検索と
抽出方法がいろいろ試してみましたがわかりません。
よろしくお願いします。

Aベストアンサー

★文字列の検索関数を使えば良い。
・テキストの中身の検索は、行単位で文字列を取得(fgets)してから、この文字列内に
 検索文字列の有無をチェックします。この有無は文字列から文字列を検索する関数
 『strstr』関数を使うのが便利です。また、文字列から1文字の検索を行う場合は
 『strchr』関数を使います。質問では、特定の文字が含まれている行となっていますが
・検索するのは1文字、文字群、文字列のどれですか?
 これによっていろいろと代わりますよ。処理が…。
・とりあえず文字列から特定の文字列を含まれた行を抽出するサンプルを下に載せます。

サンプル:
char buff[ 256 ];
char *find = "検索文字列";
FILE *fp; ←読み込み用
FILE *fo; ←抽出用

省略(fopen×2つ)

while ( fgets(buff,sizeof(buff),fp) != NULL ){
 if ( strstr(buff,find) != NULL ){
  fputs( buff, fo );
 }
}

省略(fclose×2つ)

解説:
・上記のサンプルでは、行単位でテキストの中身を取得して、この文字列から検索文字列(find)が
 含まれるか『strstr()』関数でチェックしています。見つかると『NULL』以外を返します。
・そして、見つかったらば行単位で『fputs』関数で出力しています。
 これで見つかった行だけが、新たに作ったファイルに書き込まれていきます。→抽出です。
・また『strstr()』関数の部分を
 『if ( strchr(buff,'a') != NULL ){ … }』とすると『a』の文字が含まれる行のみを抽出します。
 『if ( strspn(buff,"+-*/") != 0 ){ … }』とすると『+-*/』の文字群が含まれる行のみを抽出します。
 検索する文字とは、1文字、文字群、文字列のどれですか?
・以上。おわり。→上記のを参考にして下さい。

参考URL:http://www9.plala.or.jp/sgwr-t/lib/strspn.html,http://www9.plala.or.jp/sgwr-t/c/sec17.html

★文字列の検索関数を使えば良い。
・テキストの中身の検索は、行単位で文字列を取得(fgets)してから、この文字列内に
 検索文字列の有無をチェックします。この有無は文字列から文字列を検索する関数
 『strstr』関数を使うのが便利です。また、文字列から1文字の検索を行う場合は
 『strchr』関数を使います。質問では、特定の文字が含まれている行となっていますが
・検索するのは1文字、文字群、文字列のどれですか?
 これによっていろいろと代わりますよ。処理が…。
・とりあえず文字列から特定...続きを読む


人気Q&Aランキング