-1

这是其中一项任务,我想知道为什么在某个地方没有一个名为 namesafe( char *in) 的基本 C99 函数来完成这项工作。这在一个完美的世界里会很好,对于用 UTF-8 希伯来语或希腊语写的名字完全没用。但是,假设我被七位 ascii 卡住了,那么我尝试了以下操作:

  /* We may even go so far as to ensure that any apostrophe, or hyphen
   * or period may only appear as single entities and not as two or three
   * in a row.  This does not, however, protect us from total non-sense
   * such as D'Archy Mc'Clo.u. d.
   *
   * walk the first_name string and throw away everything that is 
   * not in the range A-Z or a-z, with the exception of space char which
   * we keep. Also a single hyphen is allowed. 
   * 
   * This all seems smart but we are not protected from stupidity such
   * As a name with spaces and dashes or hypens intermixed with letters
   * or from the artist formally known as 'Prince'. 
   */
    char buffer[256];
    j = 0;
    for ( k=0; k<strlen(first_name); k++ ) {

        /* Accept anything in the a - z letters */
        if ( ( first_name[k] >= 'a' ) && ( first_name[k] <= 'z' ) )
            buffer[j++] = first_name[k];

        /* Accept anything in the A - Z letters */
        if ( ( first_name[k] >= 'A' ) && ( first_name[k] <= 'Z' ) )
            buffer[j++] = first_name[k];

        /* reduce double dashes or hyphens to a single hyphen */
        while (( first_name[k] == '-' ) && ( first_name[k+1] == '-' ))
            k++;
        if ( first_name[k] == '-' )  /* do I need this ? */
            buffer[j++] = first_name[k];

        /* reduce double spaces to a single space */
        while (( first_name[k] == ' ' ) && ( first_name[k+1] == ' ' ))
            k++;
        if ( first_name[k] == ' ' )   /* do I also need this ? */
            buffer[j++] = first_name[k];

    }
    /* we may still yet have terminating spaces or hyphens on buffer */
    while ( ( j > 1 ) && (( buffer[j-1] == ' ' ) || ( buffer[j-1] == '-' )) )
        j--;
    buffer[j] = '\0';

    /* Accept this new cleaner First Name */
    strcpy ( first_name, buffer );

只要输入名称缓冲区的长度不超过 255 个字符,似乎就可以很好地工作。但是,在第一次通过时,我想知道如何摆脱前导空格和噪音,例如破折号和连字符以及可能的撇号的混合?

所以问题是......如何让它变得更好,而且,我是否需要那些我询问是否( first_name[k] == '-' )的行并且对于空格也是如此?我只是在缓冲区上走一走,寻找重复项,应该落在连字符或单个空格上。正确的?

4

1 回答 1

1

纯粹将其视为如何清理代码的抽象编程问题,您可以使用它isalpha()来确保缓冲区仅包含字母、单个连字符和单个空格:

for (k = 0; k < strlen(first_name); k++) {

   if (isalpha (first_name[k])
       buffer [j++] = first_name[k++];

   else if (( first_name[k] == '-' ) && (isalpha (first_name [k+1])))
       buffer [j++] = first_name[k++];

   else if (( first_name[k] == ' ' ) && (isalpha (first_name [k+1])))
       buffer [j++] = first_name[k++];

   else
       k++;
}

这只是一个草稿。我还没有真正尝试过,所以不能保证。此外,这不会处理像“John - Paul”这样的名字在连字符前后用空格正确写出的情况;你最终会得到一个空格而不是一个连字符。如果您想捕捉这种边缘情况,您可能可以添加几个额外的“else”子句。

也就是说,作为一个具体的现实世界解决方案,我同意将名称与输入的名称完全相同。我自己有一个不寻常的名字,我厌倦了不得不向人们解释是的,这确实是我的名字,不,你不能改变它以适应你对可接受名字的想法。

于 2013-08-07T00:56:28.900 回答