0

これは私がこれまでに持っているものです。

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

void main(int argc, char *argv[]){

  FILE *fp;
  char word[30];
  int k;
  for (k=1 ; k < argc ; k++)
    {
      fp = fopen(argv[k],"r");
      if (fp == NULL)
        fprintf(stdout,"Error with file: %s\n",argv[k]);
      else{
        while( !feof(fp) ){
           fscanf(fp,%s%*[^\n]",word);
           printf("word: %s\n",word);
           memset(word,0,sizeof(word));                       
        }
      }
    fclose(fp);
    }
}

私が持っているものが正しいかどうかはわかりません。また、ファイル内のすべての行の最初の単語を出力するために while ループの中に何を入れるべきかわかりません。ヘルプ/ヒントを事前にありがとうございます!

4

2 に答える 2

1

まず、次のものを置き換えることができます。

int k = 1;
for (k; k < argc; k++)

より「標準」で:

int k;
for (k = 1; k < argc; k++)

次に、その部分の内部elseに、最初の単語の文字のみを出力する単純なループとステートマシンがあります。文字ベースのステートマシンの利点は、行の長さに関係なく、バッファオーバーフローの可能性がないことです。

30文字のバッファを使用している場合、(たとえば)60文字のファイルで一度に1行ずつ処理しようとすると、問題が発生する可能性があります。

次の擬似コードが役立つ場合があります。

state = before_word
get character from input stream (see fgetc)
while character is not end-of-file:
    if character is newline:
        echo character (see putchar)
        state = before_word
    else
        if state is before_word:
            if character is not white space (see isblank/isspace):
                echo character
                state = in_word
            endif
        else
            if state is in_word:
                if character is white space:
                    state = past_word
                else
                    echo character
                endif
            endif
        endif
    endif
    get character from input stream (see fgetc)
endwhile

これは、状態(入力ストリームを介して入ってくるものに応じて状態がどのようになるか)を維持することによって機能します。

初期状態はbefore_word、ファイルの最初の行の前の架空の改行の直後であるためです。その状態では、すべての空白文字が破棄されます。最初の非空白文字は、in_wordその文字をエコーし​​た後、状態をに変更します。

状態はin_word、すべての文字が出力されます。その状態で最初に到着した空白文字は出力されず、状態がにシフトしpast_wordます。

状態ではpast_word、すべてのキャラクターが捨てられます。

どの状態でも(このifステートメントが最初です)、改行によって状態が強制的に。になりbefore_wordます。

その擬似コードをCコードに変換することは、特にこれが宿題である場合、あなたにとって良い練習になるでしょう。


宿題でない場合は、以下の解決策があります。SOは公開サイトであり、教育者はこのようなサイトで盗用をチェックしていると確信しているため、これを自分の作品として渡すことには注意してください。単純なグーグル検索echoAndChangeはほぼ確実にあなたに失敗点を与えるでしょう。

それで、それが宿題ではない、またはあなたがあなた自身の解決策をチェックするために何かが欲しいだけであるという仮定で、ここに行きます:

#include <stdio.h>
#include <ctype.h>

// States and utility function for echo and change state.

typedef enum {ST_PRE, ST_IN, ST_POST} tState;

tState echoAndChange (int chr, tState newState) {
    if (chr != EOF) putchar (chr);
    return newState;
}

int main (int argc, char *argv[]) {
    FILE *fp;
    int k, chr;
    tState state;

    // Process each file.

    for (k = 1; k < argc; k++) {
        fp = fopen (argv[1], "r");
        if (fp == NULL) {
            printf ("Error with file: %s\n", argv[1]);
        } else {
            // Initial state pre-word, then process every character.

            state = ST_PRE;
            while (1) {
                chr = fgetc (fp); if (chr == EOF) break;

                // Newline: output it and change to pre-word.

                if (chr == '\n') {
                    state = echoAndChange (chr, ST_PRE);
                    continue;
                }

                // Pre-word and nonspace: echo and change to in-word.

                if (state == ST_PRE) {
                    if (!isblank (chr))
                        state = echoAndChange (chr, ST_IN);
                    continue;
                }

                // In-word: change to post word if space, otherwise echo.

                if (state == ST_IN)
                    if (isblank (chr))
                        state = echoAndChange (EOF, ST_POST);
                    else
                        state = echoAndChange (chr, ST_IN);
            }
            fclose (fp);
        }
    }
    return 0;
}

有名な「Loremipsum」テキストでそのプログラムを実行する場合:

Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit
esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.

あなたはそれが実際に動いているのを見ることができます:

Lorem
sed
aliqua.
ullamco
Duis
esse
occaecat
deserunt

より短いプログラムが必要な場合は、次のように、ステートマシンの一部をステートメントが実行される順序に吸収できます(先頭のスペースについて心配する必要はありません)。

#include <stdio.h>
#include <ctype.h>

int main (int argc, char *argv[]) {
    FILE *fp;
    int echo, chr;

    if (argc < 2) {
        puts ("Usage: firstword <input-file>");
        return -1;
    }

    fp = fopen (argv[1], "r");
    if (fp == NULL) {
        printf ("Error with file: %s\n", argv[1]);
        return -1;
    }

    echo = 1;
    chr = fgetc (fp);
    while (chr != EOF) {
        if (chr == '\n') echo = 1;
        if (isblank (chr)) echo = 0;
        if (echo ) putchar (chr);
        chr = fgetc (fp);
    }
    fclose (fp);
    return 0;
}

ここでの基本的なルールは次のとおりです。

  • 初期状態はエコーです。
  • 次に、すべてのキャラクターについて:
    • 改行はエコーを強制します(改行は2行下にエコーします)。
    • 空白があるとエコーがオフになります。
    • エコーオンすると文字がエコーされます。
于 2012-10-25T03:59:33.223 に答える
1

これを行うにはいくつかの方法があります。1つの方法はgetline()、ファイルを1行ずつ読み取り、最初の空白文字まで文字を印刷することです。

#include <ctype.h>

char *line = NULL;
size_t siz = 0;
int i = 0;

while(-1 != getline(&line, &siz, fp)){
    for(i = 0; i < siz && !isspace(line[i]); i++){
        printf("%c", line[i]);
    }
}

これでも、いくつかのエッジケース(空白行など)を処理する必要がありますが、開始する必要があります。

于 2012-10-25T04:03:19.450 に答える