0

ユーザーから入力されたファイル名を読み取り、それを「名前」に保存し、後で入力されたファイル名が現在のディレクトリにあるかどうかを確認するプログラムを作成しようとしています。私が抱えている問題は、ユーザーがディレクトリに存在しないファイルのファイル名を入力すると、以前よりも長い名前のファイルが機能することですが、ユーザーが最初に存在しない長いファイル名を入力すると、存在する短いもの

stat(name, &check)<0

そして、それはうまくいきません。2番目のインスタンスの「名前」は正しいファイル名の配列ですが、入力された以前のより大きな間違った試行のサイズに合わせて「\ 0」を入力すると、ファイル名を比較することに関係があるのではないかと思います。fflush を使用せずに試行ごとに「名前」をクリアする方法はありますか?

char *filename(int *valid_input)
{

    /* Need to malloc name, dat and prefix if doing it this way. */
    int valid1, valid2, valid3, i, n;
    char c, *name;
    char dat[5], prefix[16];
    struct stat check;

    name = malloc(14*(sizeof(char)));

    if(name==NULL)
    {
        printf("Memory could not be allocated.");
        exit(EXIT_FAILURE);
    }

    printf("\nPlease enter a filename in the form 'yourfile.dat'.\nUse only lowercase letters a-z and numerals 0-9 in the prefix. \n The prefix should be 10 characters or less.\nIf you wish to quit enter 'q'.\n\nInput filename : ");

    *valid_input = 0;

    while(*valid_input == 0)
    {
        valid1=0; valid2=0; valid3=0;

         __fpurge(stdin);
        printf("hello1");

        while(valid1==0)  /* Checks input is at least 5 characters long, 14 maximum. */
        {
           printf("hello2");
            n = 0;
            valid1 = 1;

            __fpurge(stdin);

            while ((c=(char)getchar()) != '\n') /* Reads in input */
               {
                   printf("hello3");
                   if(n<14)
                   {
                       name[n]=c;
                       /*printf("%c",name[n]); */
                       if((name[n]=='\n')||(name[n]==EOF)||(name[n]=='\0')) break;
                   }
                   ++n;
               }

           /* printf("check"); */
            if(((n>=14)&&(name[14]!='t'))||(n<5)){printf("hello1");  valid1 = 0;} /* Checks input has a prefix and is less than                     14 characters total */

            if((name[0]=='q')&&(n==1)){printf("hello"); break;}

            if(valid1 > 0) break;

          /* printf("Length of name = %d n = %d ",strlen(name),n);*/
            printf("\nYour filename should contain a prefix of up to 10 characters. \nTo quit press 'q'.\n\nInput filename : ");
        }

        if((name[0]=='q')&&(n==1)) break;

        for (i=0;i<(n-4);i++)
        {

            prefix[i]=name[i];
            printf("\nprefixvalue = %c",prefix[i]);
            if(((prefix[i]>='a')&&(prefix[i]<='z'))||((prefix[i]>='0')&&(prefix[i]<='9'))){ valid3+=1;}
        }
        if(valid3!=n-4) valid3=0;
        else valid3=1;

        for (i=0;i<4;i++)
        {
            dat[i]=name[n-4+i];
            if((dat[0]='.')||(dat[1]='d')||(dat[2]='a')||(dat[3]='t')) valid2=1;
        }

        if((valid2==0)||(valid3==0)) printf("\nYour filename should be in the form 'yourfile.dat' with only lowercase letters or numbers in the prefix.\nTo quit press q.\n\nInput filename : ");

        *valid_input = valid1 && valid2 && valid3;

        if(*valid_input==1)
        {
            if(stat(name, &check)<0)
               {
                printf("\n File does not exist in the current directory.\n Check and re-enter filename.\n To quit press q.\n\nfilename : "); *valid_input=0;
               }
        }

    }

    return(name);
4

2 に答える 2

5

あなたが抱えている大きな問題は、 string を終了しないことですname

まず、ターミネータにもう 1 文字割り当てる必要があります。

name = malloc(15);  /* C specifies that `sizeof(char)` is always 1 */

次に、getcharループの後、文字列を終了する必要があります。

name[n] = '\0';
于 2012-10-19T10:31:00.823 に答える
1

Joachim によって発見されたバグに加えて、別のバグがあります。

if(((n>=14)&&(name[14]!='t'))||(n<5)){printf("hello1");  valid1 = 0;}

なぜname[14]!='t'特別な意味があるのか​​ わかりませんが、いずれにせよ、nこれまでに読み取られた文字数であるためn == 14name[14]15番目の文字である はまだ割り当てられておらず、このテストは予期しない動作をします。

于 2012-10-19T10:46:41.970 に答える