0

テキストファイルに含まれる単語、行、文字の数を示すプログラムを作成しようとしましたが、関数fopen()がファイルを開くことができません。テキストファイルへの絶対パスと相対パスの両方を試しましたが、同じ出力が得られます。何が悪いのか教えていただけますか?

私のコンパイラはgccバージョン4.6.3(Linux)です

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 256

void tokenize(const char *filename)
{
    FILE *f=NULL;
    char line[N],*p;
    unsigned long int ch=0,wd=0,ln=0;
    int t;
    f=fopen(filename,"rt");
    if(f==NULL)
    {
        perror("The following error occurred");
        exit(1);
    }
    fgets(line,N,f);
    while(!feof(f))
    {
        ln++;
        p=strtok(line," ");
        while(p!=NULL)
        {
            wd++;
            t=strlen(p);
            ch+=t;
            printf("Word number %lu with length %d: %s\n",wd,t,p);
            p=strtok(NULL," ");
        }
        fgets(line,N,f);
    }
    printf("%lu lines, %lu words, %lu characters\n",ln,wd,ch);
    fclose(f);
}

int main(void)
{
    char filename[80];
    size_t slen;
    printf("Enter filename path:\n");
    fgets(filename,80,stdin);
    slen = strlen (filename);
    if ((slen > 0) && (filename[slen-1] == '\n'))
         filename[slen-1] = '\0';
    printf("You have entered the following path: %s\n",filename);
    tokenize(filename);
    return 0;
}

出力:

Enter filename path:
input.txt
You have entered the following path: input.txt

The following error occurred: No such file or directory
4

3 に答える 3

4

ファイル名の入力から改行文字を保持しました。出力にファイル名をエコーすると、これを確認できます。空白行に注意してください。

関数に渡す前に、この改行を取り除く必要があります。これを行うにはいくつかの方法があります。これが1つです。

size_t idx = strlen(filename);
if ((idx > 0) && filename[idx - 1] == '\n')
    filename[idx - 1] = '\0';
于 2012-08-21T04:15:44.160 に答える
2

次のように、文字列から末尾の改行文字を削除する必要があります。

size_t slen = strlen (filename);
if ((slen > 0) && (filename[slen-1] == '\n'))
    filename[slen-1] = '\0';

また、ユーザー入力に使用したことを称賛しますがfgets(バッファオーバーフローから保護できるため)、行が長すぎる場合やユーザーフラグが終了する場合など、考慮していないエッジケースがいくつかあります。入力)。より堅牢なソリューションについては、こちらをご覧ください。

于 2012-08-21T04:22:15.847 に答える
1

次のような関数を宣言できます。

void rmnewline(char *s)
{
int l=strlen(s);
if(l>0 && s[l-1]=='\n')
   s[l-1]='\0';
}

char配列を使用する前に呼び出します。

于 2013-01-30T19:01:29.313 に答える