2

カンマで区切られたユーザーから名前を取得するプログラムを作成しています。このプログラムを使用すると、ユーザーはコンマの間に必要な数のスペースを入れることができます。したがって、たとえば:

私が次のようなものを入力する場合

Smith, John

また

Smith,John

印刷したい

John, Smith

私のプログラムは上記の例を適切に処理していませんが、問題はあります。入力が次のようなものであれば機能します

Smith , John

また

Smith ,John.

これが私のコードです:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define LINESIZE 128

int get_last_first(FILE *fp);

int main (void)
{
    get_last_first(stdin);
}

/*takes names in the format [LASTNAME],[FIRSTNAME]*/
int get_last_first(FILE *fp)
{
    char first[LINESIZE];
    char last[LINESIZE];
    char line[LINESIZE];
    size_t i;

    while(1)
    {
        printf("Enter your last name followed by a comma and your first name\n");

        /*if we cant read a line from stdin*/
        if(!fgets(line, LINESIZE, fp)) 
        {
            clearerr(stdin);
            break;   /*stop the loop*/
        }

        /*goes through the line array and checks for non-alphabetic characters*/        
        for(i = 0; i < strlen(line); i++)
        {
            if(!isalpha(line[i]))
            {
                /*if it sees a space hyphen or comma, it continues the program*/
                if((isspace(line[i]) || line[i] == ',') || line[i] == '-' )
                {
                    continue;
                }
                else
                {
                    return -1;
                }
            }

        }

        if(sscanf(line, "%s , %s", last, first))
        {
            printf("%s, %s", first, last);
            return 1;
        }

        return 0;   

    }
}

sscanfを適切に使用していないためですか?

4

2 に答える 2

2

sscanf()パターンマッチングは行いません。カンマは完全に有効な非空白文字列コンポーネントであるため、%s仕様に飲み込まれます。のようなものを使用%[^ \t,]して、空白またはコンマまでの一連の文字を一致させることができます。

于 2011-06-23T03:49:25.453 に答える
1

基本的な問題はgeekosaur答えに概説されています-はい、あなたは誤用してsscanf()います。

コードには他にも問題があります。

  • strlen()ループのテストには使用しないでください。毎回呼び出され、同じ答えが生成されます(文字列をハッキングしている場合を除く)。ループの前に一度呼び出して、保存した値を使用します。
  • 様式的には、次の条件で不要な括弧とスペースがあります(必要なスペースがありません)。

    if((isspace(line[i]) || line[i] == ',') || line[i] == '-' )
    
    if (isspace(line[i]) || line[i] == ',' || line[i] == '-')
    

    キーワードの後に​​スペースを入れる必要があります(標準を参照)。余分な括弧を使用して、3方向条件の対称性を破る必要はありません。最後の閉じ括弧の前にスペースは必要ありません。(または、それを主張する場合は、条件の開始括弧の後にバランスの取れたオープンスペースが必要です。ただし、それを主張しないでください。)

  • sscanf()2つの値を正常に変換したテストが必要です。0の値を変換しなかったことを確認するだけです。1を返す可能性があります。EOF(および0または2)を返す場合があります。

  • '無限ループ'はによって中断されますbreakが、関数は値を返しません。
  • main()プログラムは関数からの戻り値を無視するので、結局のところ戻り値を返す必要はありませんでした。
  • 様式的には、C99標準returnでは、の最後を省略できますがmain()、私はそこで見たいと思っています。main()(あなたは戻って来るという罪を犯しませんでしたvoid;ありがとう。)
  • 質問をフォーマットしたときに、コメントに埋め込まれているいくつかの漂遊コードを削除したことに気付いたかもしれません。デッドコードを残さないでください-そしてSOでそれを見せびらかさないでください。
  • 様式的には、との間にスペースを入れ#includeます<stdio.h>。繰り返しになりますが、C標準を見て、それらがどのように記述しているかに注目し#include <stdio.h>てください。

'stylistically'とタグ付けされたコメントは推奨事項です。コンパイラーは、スペースやスペースの不足をほとんど認識していません。それにもかかわらず、C標準では、行にスペースがあり、and#includeなどのキーワードの後に​​スペースがあるすべての例が示されています。KernighanとRitchieによるCの元の説明も同じであるため、従うべき確かな前例があります。一般に、標準の規則に従うと、他の人はあなたのコードを読みやすくするでしょう。中括弧の配置についてはもっと議論の余地がありますが、そこでK&Rをフォローすれば、間違いはありません(私はオールマンスタイルを好みますが)。forif

于 2011-06-23T04:12:38.950 に答える