2016-11-22 25 views
0

入力として使用されている私の言葉を大文字小文字にする問題があります。ですから私のプログラムは言葉を取り、アルファベット順にソートして重複を取り除きます。しかし、私は大文字の単語を変更し、小文字の単語に等しくすることを望みます。C大文字から小文字へ

例:apple

私の入力にApple変更:

./a.out Orange apple banana Apple banana

私の出力:

Apple 
Orange 
apple 
banana 

ここでは、私が

出力を達成しようとしているものです。

apple 
banana 
orange 

はここでチェックし、ctype.h内の文字の種類を変更するための一連の標準機能があります

#include <stdio.h> 
#include <string.h> 

int main(int argc, char* argv[]) { 
    int i, j, k, size; 
    size = argc -1; 
    char *key; 
    char* a[argc-1]; 

    for (i = 2; i < argc; i++) { 
    key = argv[i]; 

    j = i-1; 
    while (j >= 1 && strcmp(argv[j], key) > 0) { 
     argv[j+1] = argv[j]; 
     j--; 
    } 

    argv[j+1] = key; 
    } 

    if (argc > 1){ 
     for (i = 1; i < argc;){ 
     puts(argv[i]); 

     while (argv[++i] != NULL && strcmp(argv[i - 1], argv[i]) == 0) 
      continue; 
     } 
    } 

    return 0; 
} 
+0

あなたは 'ctype.h'について知っていますか? –

+0

http://stackoverflow.com/questions/23618316/undefined-reference-to-strlwr – BLUEPIXY

+0

@MadPhysicist Nope。ちょうどC初心者。 –

答えて

0

私のコードです。あなたが興味を持っているのはtolower()です。あなたは#include<ctype.h>してからソートを行う前に、次のようにプリプロセスあなたargvのようなスニペットを追加することができます唯一の各単語の最初の文字の上に動作します

for(i = 1; i < argc; i++) { 
    argv[i][0] = tolower(argv[i][0]); 
} 

を。あなたは、単語全体正規化する必要がある場合:

for(i = 1; i < argc; i++) { 
    for(j = 0; argv[i][j]; j++) { 
     argv[i][j] = tolower(argv[i][j]); 
    } 
} 
2

をあなたは単語のリストを持っていて、それらを並べ替え、そして唯一のユニークなものを出力したいです。そして、大文字と小文字を区別しない方法でやりたい

  1. すべての文字列を同じ大文字にします。
  2. 文字列のリストをソートします。
  3. リピートを出力しません。

Cには、文字列を小文字に機能に組み込まれていないが、それはケースの文字を下げるものを持っているん:tolowerを。そこで、文字列全体を反復処理し、各文字を小文字にすることで、文字列全体を小文字にする関数を作成します。

void str_lower(char *str) { 
    for(; str[0] != NULL; str++) { 
     str[0] = (char)to_lower(str[0]); 
    } 
} 

その後、我々は、ソートする必要があります。これは組み込みのqsort関数によって処理されます。これを使用するには、2つの文字列を比較し、strcmpのように返す関数を記述する必要があります。実際には、あなたの比較関数はstrcmpのラッパーになり、qsortを満足させるでしょう。

int compare_strings(const void *_a, const void *_b) { 
    /* The arguments come in as void pointers to the strings 
     and must be cast. Best to do it early. */ 
    const char **a = (const char **)_a; 
    const char **b = (const char **)_b; 

    /* Then because they're pointers to strings, they must 
     be dereferenced before being used as strings. */ 
    return strcmp(*a, *b); 
} 

データ型を処理するために、比較関数はvoidポインタを取ります。彼らはcharポインタにキャストする必要があります。そしてそれは文字列(char *)に渡されません。これは文字列(char **)へのポインタを渡します。これにより、どのデータ型も扱うことができます。だからabを参照解除する必要があります。だからこそstrcmp(*a, *b)です。

qsortを呼び出すと、並べ替えたい配列、項目数、各要素の大きさ、および比較関数がわかります。

qsort(strings, (size_t)num_strings, sizeof(char*), compare_strings); 

この種のことに慣れば、あなたはそれを多く使用します。 Cでジェネリックリストを扱う方法です。


最後の部分はユニークな文字列だけを出力することです。ソートされているので、前の文字列が現在の文字列と同じかどうかを簡単に確認できます。前の文字列はstrings[i-1]ですが、strings[-1]をチェックしないようにしてください。それを処理するには2つの方法があります。まず、i < 1の場合のみ比較を行います。

for(int i = 0; i < num_strings; i++) { 
    if(i < 1 || strcmp(strings[i], strings[i-1]) != 0) { 
     puts(strings[i]); 
    } 
} 

もう1つの方法は、常に最初の文字列を出力し、2番目の文字列からループを開始することです。

puts(strings[0]); 
for(int i = 1; i < num_strings; i++) { 
    if(strcmp(strings[i], strings[i-1]) != 0) { 
     puts(strings[i]); 
    } 
} 

これはいくつかの繰り返しコードを意味しますが、ループロジックを簡素化します。このトレードオフは価値があり、複雑なループはバグを意味します。 `私は最初のループのチェックに自分自身でif(i > 0 && strcmp ...と書いて拒否しました)`。


あなたは私を除いて、私は... argvで作業していないよ気づくでしょう。 stringsnum_stringsは単なる簿記なので、文字列を渡したい場合は、必ずargv[1]から始めるか、argv+1を使用することを覚えておく必要はありませんでした。

char **strings = argv + 1; 
int num_strings = argc-1; 

これは、ホスト全体のオフ・エラーを回避し、複雑さを軽減します。


私はあなたがそこから一緒に作品を置くことができると思います。

0

愚かな私は、自分のコードを見て、私がkey[0] = tolower(key[0]);を行うことができることを認識した後、それを見つけ出すことができました。

for (i = 2; i < argc; i++) { 
    key = argv[i]; 
    key[0] = tolower(key[0]); 
    j = i-1; 
    while (j >= 1 && strcmp(argv[j], key) > 0) { 
     argv[j+1] = argv[j]; 
     j--; 
    } 

    argv[j+1] = key; 
    } 

最初の文字はどの小文字であるか。そして、もし私がすべての文字を小文字にしたければ、私はforループを使っていたでしょう。皆様、お寄せいただきありがとうございます。 :)

関連する問題