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

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

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

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

Cygwin

Cygwinは、Unixのような環境を、Windows上で構築させるコマンドラインインターフェースです。

Q&A

解決済

5回答

17813閲覧

C言語でテキストファイルの行削除

chijan

総合スコア24

C

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

Cygwin

Cygwinは、Unixのような環境を、Windows上で構築させるコマンドラインインターフェースです。

0グッド

0クリップ

投稿2015/09/19 02:48

C言語でテキストファイルの指定した行の削除を行いたいです。
sample.txtが

giaaaaaaaa

hoge
fuga
piyo

となっているときに、>giの行を削除したいのです。

http://oshiete.goo.ne.jp/qa/7471896.html において、バナナが>giになったものと思い、
ここに書いてあるコードをcygwinでgccでコンパイル、実行し、>giと打ち込んでも
sh: -./a: No such file or directory
というエラーが出てしまいます。
>giなどとすると、エラーは出ないのですが、>giの行は削除されず、何も変化がありませんでした。

解決方法のご教示のほどよろしくお願いします。

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

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

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

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

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

guest

回答5

0

c

1 2/* header files */ 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6 7/* macros */ 8#define N (1024) 9 10/* main */ 11int main(void) { 12 FILE * fp; 13 char * filename = "sample.txt"; 14 char readline[N] = ""; 15 16 char pat[N] = ""; 17 printf("文字を入力してください\n"); 18 scanf("%s", pat); 19 20 /* ファイルのオープン */ 21 if ((fp = fopen(filename, "r")) == NULL) { 22 fprintf(stderr, "%sのオープンに失敗しました.\n", filename); 23 exit(EXIT_FAILURE); 24 } 25 26 /* ファイルの終端まで文字を読み取り表示する */ 27 while ( fgets(readline, N, fp) != NULL ) { 28 // pat をで始まらない行だけを出力する 29 if (strstr(readline, pat) != readline) { 30 printf("%s", readline); 31 } 32 } 33 34 /* ファイルのクローズ */ 35 fclose(fp); 36 37 return EXIT_SUCCESS; 38}

実行例:

$ gcc 1.c $ ./a.out 文字を入力してください >g hoge fuga piyo $ ./a.out 文字を入力してください hoge >giaaaaaaaa fuga piyo

参考情報:

投稿2015/09/19 12:29

katoy

総合スコア22322

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

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

chijan

2015/09/19 12:57

ご回答ありがとうございます。 実効例の通りにこちらでも動作を確認できました。 質問本文での説明不足だったのですが、1行削除がなされたテキストファイルoutput.txtも欲しいのですが、これはどうすればいいでしょうか? あらかじめFILE *fileにfopenでoutput.txtをいれておき、katoyさんの書いてくださったコードの/*ファイルの終端まで文字を読み取り実行する*/におけるprintfを、 fprintf(file,"%s",readline);とすればいいでしょうか?(当方はこれでうまくいったような気はします)
katoy

2015/09/19 13:04

はい、printf で stdout に出力するぁ割りに、 outout.txt を open しておいて、fprintf でファイルに出力して、最後にファイルを close すればよいと思います。 あるいは、プログラムを a.out sample.txt ">g" のように指定して動作するように書き換えて、 $ a.out sample.txt ">g" > output.txt として stdout への出力をリダイレクトでファイルに出力するようにするほうが簡単かもしれません。
katoy

2015/09/19 13:10

さらにいうなら $ a.put "<g" < sample.txt > outout.txt として動作するようにするのがよいです。 プログラムへの引数は 削除する行のパターンだけにし、stdin から行を読み込み、stdout に行を書き出すようにするのです。 そうするとプログラム中で open , close のことを気にする必要はなくなるし、他のプログラムと pipe 処理でつなげて利用することができるようになります。
chijan

2015/09/19 13:26

grepっぽくて使いやすいですねその方が。作るのはちょっと書き換えが多く必要そうですが……。
katoy

2015/09/19 13:47

この質問のプログラムの動作は、grep -v の動作と似ているのです。 参考: http://blog.mah-lab.com/2014/02/24/unix-philosophy/ > UNIX哲学 > ... 定理9:すべてのプログラムをフィルタにする .. そして grep は この哲学に沿っているプログラムなのです。
guest

0

フィルター形式のプログラムコードがすでに回答として示されていますが、
私のフィルター形式のプログラムを示します。
(本質的には他の回答と同じです。)

c

1// 2// 使い方: 3// $ a.put pattern 4// 標準入力を読み込み、pattern で始まる行以外を表示する。 5// 6// 使用例: 7// $ cat in.txt | ./a.out hoge 8// in.txt の hoge で始まっていない行を表示する。 9// 10// $ ./a.out hoge < in.txt > out.txt 11// in.txt の hoge で始まっていない行を out.txt に出力する。 12 13#include <stdio.h> 14#include <stdlib.h> 15#include <string.h> 16 17#define LINE_SIZE (1024) 18 19void usage_and_exit() { 20 fputs("パラメータ数が不正です。(pattern を1つ指定してください)\n", stderr); 21 exit(EXIT_FAILURE); 22} 23 24int main(int agc, char* agv[]) { 25 if (agc != 2) { 26 usage_and_exit(); 27 } 28 29 char line[LINE_SIZE] = ""; 30 while (fgets(line, LINE_SIZE, stdin)) { 31 if (strstr(line, agv[1]) != line) { 32 fputs(line, stdout); 33 } 34 } 35 return EXIT_SUCCESS; 36}

投稿2015/09/21 07:44

katoy

総合スコア22322

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

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

0

ベストアンサー

作るのはちょっと書き換えが多く必要そうですが……。

という事なので・・・サンプルd^^

C

1~/test >cat sample.txt 2>giaaaaaaaa 3hoge 4fuga 5piyo 6 7~/test >cat tst14.c 8#include <stdio.h> 9#include <string.h> 10 11int main( int agc, char *agv[]) 12{ 13 if( agc != 2 ){ 14 return 1; 15 } 16 char buf[256]; 17 // gets()は、スタック壊すのでfgets() 18 while( fgets(buf,sizeof buf,stdin)){ 19 // 1行読み込んで比較 20 if( strstr(buf,agv[1]) == NULL){ 21 fputs(buf,stdout); 22 } 23 } 24 // 25 return 0; 26} 27~/test >./a.out iy < sample.txt 28>giaaaaaaaa 29hoge 30fuga 31~/test >

投稿2015/09/20 07:05

編集2015/09/20 07:23
cateye

総合スコア6851

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

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

chijan

2015/09/21 03:13

なんとサンプルコードを……ありがとうございます!
guest

0

参照元のコードは、system() で、自分自身を起動してしまう様で、
実行すると、メモリーのある限り、プロセスを起動し続けてまいます。

元のコードには、悪意を感じます...

argius さんに言っている通り、コマンドでも実現できますが、
C言語で、やってみたいという事であれば、以下のコードはいかがでしょうか?


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

#define BUFSZ 256

void usage(char *cmd)
{
fprintf(stderr, "usage: %s <input-file>\n", cmd);
}

int main(int argc, char *argv[])
{
int ret = 1;
FILE *fp;
char buf[BUFSZ];
char rdbuf[BUFSZ];

if (argc == 2) { fp = fopen(argv[1], "r"); if (fp) { printf("文字を入力してください\n"); scanf("%s", buf); ret = 0; while (fgets(rdbuf, BUFSZ, fp)) { if (strstr(rdbuf, buf) == NULL) { printf("%s", rdbuf); } } fclose(fp); } else { fprintf(stderr, "error: fopen(%s, \"r\") is err %s\n", argv[1], strerror(errno)); } } else { usage(argv[0]); } return(ret);

}

投稿2015/09/19 09:28

ShinyaAnan

総合スコア241

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

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

chijan

2015/09/19 12:34 編集

ご回答ありがとうございます。 実行すると、 usage: ./a sample.txt とだけ表示され、scanfの文字入力受付もありませんでした……。
ShinyaAnan

2015/09/19 16:04

実行する時の引数に、テキストファイルを指定してください。
guest

0

そのサンプルコードは、system関数を使っているため、環境依存になっていて、
Cygwinでは正しく動作しない可能性があります。

これだったらC言語でなくても、grepコマンドを使えばできます。

fgrep -v '>gi' sample.txt > output.txt

練習としてC言語でやりたいのでしたら、
system関数でなくて、fgets,fputs関数を使った方が良いと思います。
fgets,fputs関数を使った例が見つからなかったので、必要なら例を書きます。

投稿2015/09/19 07:50

argius

総合スコア9388

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

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

chijan

2015/09/19 11:59

ご回答ありがとうございます。 UNIXコマンドという手がありましたか! でもせっかくなのでC言語で解きたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問