質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

1474閲覧

ランダムにディレクトリを移動する.

RaitoN

総合スコア72

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/07/19 13:57

###ランダムにディレクトリを移動するプログラム
まず,ホームディレクトリに移動し,そのディレクトリ内部のファイルやディレクトリを検索.
'.'を含まないものはカレント,親ディレクトリでもなく,ファイルでもないので,strchr関数でd_nameに'.'を含まないものだけをピックアップし,randを使ってそのうちのどれかに移動(または移動しない)を繰り返すプログラムを書きました.
Macでは動作するのですが,windowsでは次のようにうまくいきません

###動作の詳細
HomePath関数でホームディレクトリのパスを取得し.chdir(home)で移動.

RandomChange関数の中のforループに入りCountFile関数で'.'を含まないものをカウント,このカウント数+1の値で乱数の割り算のあまりを求めてnumに代入.

numとfile数が一致するとき移動をやめる.それ以外のときはCountFile関数で検索したどれかのディレクトリに移動.これをforループで回すを繰り返す.

###Windowsでの動作
コンパイルは通りますが,エラーメッセージが出ずに動かないのでどうしたら良いかこまっています.

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <dirent.h> 5#include <time.h> 6#include <unistd.h> 7 8DIR *DirOpen(DIR **dp); 9//FILE *FileOpen(FILE **fp, const char *filename, const char *mode); 10void getPWD(size_t size); 11 12char pwd[1024]; 13int fcount = 0; 14 15void HomePath(char home[]) { 16 if ((getenv("HOMEPATH")) != NULL) { 17 strcpy(home, getenv("HOMEPATH")); 18 } else if ((getenv("HOME")) != NULL) { 19 strcpy(home, getenv("HOME")); 20 } else { 21 fprintf(stderr, "No Exist\n"); 22 exit(1); 23 } 24 return; 25} 26 27int GetRandom(int max) { 28 return rand() % (max + 1); 29} 30int CountFile(void) { 31 DIR *dp; 32 struct dirent *dir; 33 int cnt = 0; 34 DirOpen(&dp); 35 puts("\nFile list"); 36 while ((dir = readdir(dp)) != NULL) { 37 if (strchr(dir->d_name, '.') != NULL) continue; 38 printf("# %d\t%s\n", cnt, dir->d_name); 39 cnt++; 40 } 41 closedir(dp); 42 return cnt; 43} 44 45void ChangeDir(int num) { 46 DIR *dp; 47 struct dirent *dir; 48 char RelPath[256]; 49 int i = 0; 50 51 DirOpen(&dp); 52 while ((dir = readdir(dp)) != NULL) { 53 if (strchr(dir->d_name, '.') != NULL) continue; 54 if (i == num) { 55// strtok(dir->d_name, ":"); 56 sprintf(RelPath, "./%s", dir->d_name); 57 closedir(dp); 58 chdir(RelPath); 59 return; 60 } 61 i++; 62 } 63 closedir(dp); 64 return; 65} 66 67void RandomChange(void) { 68 char home[256]; 69 int i, num, file; 70 HomePath(home); 71 chdir(home); 72 getPWD(sizeof(pwd) - 1); 73 printf("Home directly path -> %s\n", pwd); 74 puts("Start move."); 75 for (i=0; i<32; i++) { 76 file = CountFile(); 77 if (!file) { 78 puts("None"); 79 exit(1); 80 } 81 num = GetRandom(file); 82 83 printf("num: %d\n", num); 84 85 if (num == file) { 86 puts("Stop moving"); 87 exit(1); 88 } 89 ChangeDir(num); 90 getPWD(sizeof(pwd) - 1); 91 printf("\nMove %2d\n", i + 1); 92 printf("pwd -> %s\n", pwd); 93 } 94 getPWD(sizeof(pwd) - 1); 95 96 return; 97} 98 99int main(int argc, const char *argv[], char *envp[]) { 100 srand((unsigned int)time(NULL)); 101 RandomChange(); 102 return 0; 103} 104 105DIR *DirOpen(DIR **dp) { 106 const char *path = "."; 107 if ((*dp = opendir(path)) == NULL) { 108 fprintf(stderr, "Directly open error.\n"); 109 exit(1); 110 } 111 return *dp; 112} 113/* 114FILE *FileOpen(FILE **fp, const char *filename, const char *mode) { 115 if ((*fp = fopen(filename, mode)) == NULL) { 116 fprintf(stderr, "Fileopen error %d\n", fcount); 117 exit(1); 118 } 119 fcount++; 120 return *fp; 121} 122 */ 123void getPWD(size_t size) { 124 char *p; 125 p = getcwd(pwd, size); 126 if (p == NULL) { 127 fprintf(stderr, "PWD error.\n"); 128 exit(1); 129 } 130 return; 131} 132

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2019/07/19 18:26

想定した動作をしないのなら, プログラムが間違っているか, データが想定外と言うことになると思います. コードはご提示頂いていますが, 実行対象となったディレクトリの情報がありません. どのようなファイル/ディレクトリがあるのかもご提示願えますか. また, readdir 直後に dir->d_name を表示するなどして確認されていましたら, その情報もお願いします.
guest

回答4

0

.を含むディレクトリ名とか、拡張子のないファイルとかがある場合、その判定法では破綻してるように見えますが。
アトリビュートを見るというのではダメなんでしょうか

投稿2019/07/19 14:10

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2019/07/19 14:12

バグで編集できないので、2行目をここに。 アトリビュートを見るというのではダメなんでしょうか
guest

0

コンパイルは通りますが,エラーメッセージが出ずに動かないのでどうしたら良いかこまっています.

所々で、取得したファイル数ととか、出力していますが、どこまで出力されているのでしょうか? その結果は一致してますか?
また、コンパイラとかの記載がないですが、どうなってるでしょうか?

既に指摘のあるように、"."の無いファイルとか、有るディレクトリに対応してないという問題は、考慮済みかと思います(想定内ですね?)が、
chdir, DIR とは、Windowsで動くのでょうか? (chdir の戻り値とは確認してますか?)

まずは気づいたところで。

投稿2019/07/20 01:12

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

'.'を含まないものはカレント,親ディレクトリでもなく,ファイルでもないので,strchr関数でd_nameに'.'を含まない

y_waiwaiさんも指摘されていますが、'.'を含むディレクトリや'.'を含まないファイルもあるでしょう?
d_name.を含まないかではなく、d_typeがDT_DIRかで判定するべきかと。

投稿2019/07/19 16:09

編集2019/07/19 16:10
SHOMI

総合スコア4079

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

direntの中にd_typeが存在しないのがエラーの原因でした.
ディレクトリの判定方法などのご指摘ありがとうございました.

投稿2019/07/23 05:22

RaitoN

総合スコア72

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問