[英]C upper case to lower case
我的小寫字母出現問題,被用作輸入。 因此,我的程序接受單詞並將其按字母順序排序,並刪除重復項。 但是我想將單詞大寫更改為小寫。
示例: Apple
更改為apple
我的輸入:
./a.out Orange apple banana Apple banana
我的輸出:
Apple
Orange
apple
banana
這是我想要達到的目標
輸出:
apple
banana
orange
這是我的代碼
#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;
}
您有一個單詞列表,想要將它們排序輸出,只有唯一的單詞。 您想以不區分大小寫的方式進行操作。
C沒有內置函數來將字符串小寫,但是它確實有一個將小寫字符: tolower 。 因此,我們編寫了一個函數,通過迭代整個字符串並小寫每個字符來小寫整個字符串。
void str_lower(char *str) {
for( ; str[0] != NULL; str++ ) {
str[0] = (char)to_lower(str[0]);
}
}
然后我們需要進行排序。 這由內置的qsort函數處理。 要使用它,您需要編寫一個比較兩個字符串並返回類似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 **
)的指針,因此它可以處理任何數據類型。 因此, a
和b
需要取消引用。 這就是為什么strcmp(*a, *b)
。
調用qsort
意味着告訴它要排序的數組,項目數,每個元素的大小以及比較函數。
qsort( strings, (size_t)num_strings, sizeof(char*), compare_strings );
習慣這種事情,您會經常使用它。 這就是在C中使用通用列表的方式。
最后一步是僅輸出唯一的字符串。 由於已對它們進行了排序,因此您只需檢查先前的字符串是否與當前字符串相同即可。 前面的字符串是strings[i-1]
但是請確保不要嘗試檢查strings[-1]
。 有兩種處理方法。 首先是僅在i < 1
進行比較。
for( int i = 0; i < num_strings; i++ ) {
if( i < 1 || strcmp( strings[i], strings[i-1] ) != 0 ) {
puts(strings[i]);
}
}
另一種方法是始終輸出第一個字符串,然后從第二個字符串開始循環。
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 ...
)` if( i > 0 && strcmp ...
了第一個循環的檢查。
您會注意到我不使用argv
...除了我。 strings
和num_strings
只是一些記賬,所以如果我想傳遞字符串數組,我不必總是記住以argv[1]
開頭或使用argv+1
。
char **strings = argv + 1;
int num_strings = argc-1;
這樣可以避免大量的一次性錯誤,並降低了復雜性。
我認為您可以從那里放在一起。
有一組標准函數用於檢查和更改ctype.h
的字符類型。 您感興趣的是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]);
}
}
愚蠢的我,在查看代碼后意識到能夠執行key[0] = tolower(key[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循環。 謝謝大家的貢獻。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.