0

getswithの機能を模倣する最良の方法は何scanfですか?

これが私の現在の試みです

 int main()
 {
    char cvalue[20];   //char array to store input string
    int iloop=0;      //integer variable for loop

    for(iloop=0;iloop<20;iloop++)     // for loop to get the string char by char
    {
        scanf("%c",&cvalue[iloop]); //getting input
        if(cvalue[iloop]=='\n')    //if input is newline skip further looping
        break;
    }                    // end of loop

    cvalue[iloop]='\0';         //set end of the character for given input
    printf("%s",cvalue);        //printing the given string
    return 0;
}
4

3 に答える 3

2

scanfこの方法を使用して、次のように動作できますgets

scanf("%[^\n]",&a);
于 2013-06-14T14:54:58.180 に答える
0

の通常の危険性を観察する必要がありgets()ます。

使用する際の課題scanf()は、
1)\n消費されることを保証することです。 scanf("%[^\n]",...これはしません。
2) aのみが読み取られstrた場合に a が取得されるようにする。 3) EOF および I/O エラーを処理し、 を返します。 4) 先頭の空白がスキップされるように読み込まれるようにします。\0\n
0
strscanf("%s"

#include <stdio.h>
// On success, the gets() returns str.
// If EOF encountered, the eof indicator is set (feof).
// If this happens before any characters could be read, 
//    pointer returned is a null pointer.
//  If a read error occurs, the error (ferror) is set
//    and a null pointer is also returned.
char *gets_via_scanf( char * str ) {
  // Reads characters from stdin & saves them into str until \n or the end-of-file.
  // \n, if found, is not copied into str.
  int retval = scanf("%[^\n]",str);  // %[ does not skip leading whitespace
  if (retval == EOF) return 0;
  if (retval == 0) {
    *str = '\0';  // Happens when users only types in \n
  }
  char ch;
  scanf("%c",&ch); // Consume leftover \n, could be done with getc()
  return str;
}
于 2013-06-18T01:52:38.720 に答える
0

行末に到達するまで、提供されたバッファにバイトを入れ続けるだけなgets()ので、あなたの試みは本当に模倣していません。gets()それgets()は危険であり、避けるべきであることを認識する必要があります。バッファ オーバーフローからの保護は提供しません。したがって、それを模倣することにも問題があります。

それを考えると、あなたの試みにはいくつかの欠陥があります。まず、入力バッファーの完全なサイズまでループします。これにより、入力行が 20 バイト以上の場合、NUL ターミネータを格納する余地がなくなります。これは、配列境界の外側にある\0atを格納しようとする可能性があることを意味します。これは、ループを 1 つcvalue[20]短くすることで修正できます。for

    for(iloop=0;iloop<19;iloop++)     // for loop to get the string char by char

scanf()2 番目の欠点は、呼び出しが成功したかどうかを確認しないことです。失敗を検出した場合は、ループも終了する必要があります。

        if (scanf("%c",&cvalue[iloop]) != 1) { //getting input
            break;
        }

gets()以下は、 で実装された のより安全なバージョンを作成する私の試みでしたscanf()

char *getsn (char *s, size_t sz) {
    char c;
    char fmt[sizeof(sz) * CHAR_BIT + sizeof("[^\n]")];
    if (sz == 0) return 0;
    if (sz == 1) {
        s[0] = '\0';
        return s;
    }
    s[sz-2] = '\0';
    snprintf(fmt, sizeof(fmt), "%%%lu%s", (unsigned long)sz-1, "[^\n]");
    switch (scanf(fmt, s)) {
    case 0:  s[0] = '\0';
             scanf("%c", &c);
             return s;
    case 1:  scanf("%c", &c);
             if (s[sz-2] != '\0' && c != '\n') {
                 ungetc(c, stdin);
             }
             return s;
    default: break;
    }
    return 0;
}

より安全なバージョンsnprintf()では、scanf(). したがって、指定されたszパラメーターが 100 の場合、結果の書式文字列は"%99[^\n]". \n次に、実際に遭遇した場合にのみ、入力ストリームから を取り除くようにします。

于 2013-06-14T15:06:27.097 に答える