Bir dosyada kelime çiftlerinin sıklığını belirleyen atamanızın amacının, system
numaralı çağrıya piped-string kabuk yardımcı programlarını sarmanızı sağlamak düşünülemez gibi görünüyor. Bu size C hakkında ne öğretir? Kabuk erişimine izin veren bir system
işlevi var mı? Eh, öyle, ve yapabildiğin ders, hiçbir şey öğrenilemez.
Size tek bir nesne içinde ilgili verilerin koleksiyonları tutmak için yapıların kullanımını anlamak için, ya da minimum dizinin en veya işaretçi indeksleme çiftleri için kontrol etmek için niyet olduğunu çok daha muhtemel görünüyor bir dosya içindeki bitişik sözcüklerde. 2 normal yaklaşımdan bir yapının veya indeks aritmetiğinin kullanılması, bir yapının kullanılması çok daha faydalıdır. Bir çift kelimeyi tutabilmek için basit bir şey ve eşin görüldüğü frekans tek ihtiyacınız olan şey. örneğin:.
enum { MAXC = 32, MAXP = 100 };
typedef struct {
char w1[MAXC];
char w2[MAXC];
size_t freq;
} wordpair;
(not, enum
basitçe aynı sona iki #define
ifadeleri kullanabilirsiniz kaydetmek için sabitleri MAXC
(32
) ve başına kelime maksimum karakterler için MAXP
(100
) ve maksimum çiftleri tanımlar)
bir çift veya kelimeleri w1
ve w2
ve kaç sefer o çifti freq
görülür yapacak wordpair
yapı dizisi bildirebilirsiniz. Yapının dizisi, sıralanan diğer diziler gibi ele alınabilir, vb ..
Dosyayı analiz etmek için, ilk kelimeyi ilk yapıda okumalı, ikinci kelimeye bir işaretçiyi kaydetmeli ve imlecin oluşturduğu çiftin ve okunan yeni sözcüğün var olup olmadığını (eğer görüldüğü takdirde sadece birkaç kez güncellendiyse) dosyada kalan her kalan kelimeyi okuyun ve eğer yoksa, yeni bir çift ekleyin. Okunacak yeni kelimeyi işaret eden işaretçi ve tekrarlayın. Aşağıda, komut satırında argümanlar olarak verilen tüm dosya adlarındaki sözcüklerin eşleşmesini kontrol eden kısa bir örnek verilmiştir (örneğin, ./progname file1 file2 ...
). Hiçbir dosya verilmediyse, kod stdin
'dan varsayılan olarak okunur.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXC = 32, MAXP = 100 };
typedef struct {
char w1[MAXC];
char w2[MAXC];
size_t freq;
} wordpair;
size_t get_pair_freq (wordpair *words, FILE *fp);
int compare (const void *a, const void *b);
int main (int argc, char **argv) {
/* initialize variables & open file or stdin for seening */
wordpair words[MAXP] = {{"", "", 0}};
size_t i, idx = 0;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
/* read from file given, or from stdin (default) */
idx = get_pair_freq (words, stdin);
/* read each remaining file given on command line */
for (i = 2; i < (size_t)argc; i++)
{ if (fp && fp != stdin) { fclose (fp); fp = NULL; }
/* open file for reading */
if (!(fp = fopen (argv[i], "r"))) {
fprintf (stderr, "error: file open failed '%s'.\n",
argv[i]);
continue;
}
/* check 'idx' against MAXP */
if ((idx += get_pair_freq (words, fp)) == MAXP)
break;
}
if (fp && fp != stdin) fclose (fp);
/* sort words alphabetically */
qsort (words, idx, sizeof *words, compare);
/* output the frequency of word pairs */
printf ("\nthe occurrence of words pairs are:\n\n");
for (i = 0; i < idx; i++) {
char pair[MAXC * 2] = "";
sprintf (pair, "%s:%s", words[i].w1, words[i].w2);
printf (" %-32s : %zu\n", pair, words[i].freq);
}
return 0;
}
size_t get_pair_freq (wordpair *pairs, FILE *fp)
{
char w1[MAXC] = "", w2[MAXC] = "";
char *fmt1 = " %32[^ ,.\t\n]%*c";
char *fmt2 = " %32[^ ,.\t\n]%*[^A-Za-z0-9]%32[^ ,.\t\n]%*c";
char *w1p;
int nw = 0;
size_t i, idx = 0;
/* read 1st 2 words into pair, update index 'idx' */
if (idx == 0) {
if ((nw = fscanf (fp, fmt2, w1, w2)) == 2) {
strcpy (pairs[idx].w1, w1);
strcpy (pairs[idx].w2, w2);
pairs[idx].freq++;
w1p = pairs[idx].w2; /* save pointer to w2 for next w1 */
idx++;
}
else {
if (!nw) fprintf (stderr, "error: file read error.\n");
return idx;
}
}
/* read each word in file into w2 */
while (fscanf (fp, fmt1, w2) == 1) {
/* check against all pairs in struct */
for (i = 0; i < idx; i++) {
/* check if pair already exists */
if (strcmp (pairs[i].w1, w1p) == 0 &&
strcmp (pairs[i].w2, w2) == 0) {
pairs[i].freq++; /* update frequency for pair */
goto skipdup; /* skip adding duplicate pair */
}
} /* add new pair, update pairs[*idx].freq */
strcpy (pairs[idx].w1, w1p);
strcpy (pairs[idx].w2, w2);
pairs[idx].freq++;
w1p = pairs[idx].w2;
idx++;
skipdup:
if (idx == MAXP) { /* check 'idx' against MAXP */
fprintf (stderr, "warning: MAXP words exceeded.\n");
break;
}
}
return idx;
}
/* qsort compare funciton */
int compare (const void *a, const void *b)
{
return (strcmp (((wordpair *)a)->w1, ((wordpair *)b)->w1));
}
kullanımı
"Hi how are you are you."
sizin, örneğin göz önüne alındığında, (sizin LOCALE
göre sıralanmış sırayla) istenen sonuçlar üretir/çıkış.
$ echo "Hi how are you are you." | ./bin/file_word_pairs
the occurrence of words pairs are:
Hi:how : 1
are:you : 2
how:are : 1
you:are : 1
(sonuçları sıralamak gereği yoktur, ancak daha uzun dosyalarla çok daha kolay arama/onay yapar) özgür olmakla birlikte
$ echo "Hi how are you are you." | ./bin/file_word_pairs
the occurrence of words pairs are:
Hi:how : 1
how:are : 1
are:you : 2
you:are : 1
Qsort Çıkarma system
sürümünüzü kullanmayı denemek için, neden C'deki soruna nasıl yaklaşacağınızı öğrenmek için zaman ayırmayın. Bir system
numaralı telefondan nasıl yapılacağını öğrenmek istiyorsanız,numaralı telefonu arayın. 210 dersi, bu şekilde yaptığınız gibi, C ile çok az şey yapar.
man sayfalarındaki man sayfalarındaki yeni işlevlere bakın ve daha sonra anlamadığınız herhangi bir şeyi sorun. .
Huh! "C" de mi? Neden bu komutu doğrudan yazmadın? –
@weather vane bunu düzenlemek – user3328381
Bu bir atama mı? Dış araçları aramak için 'system' kullanmanıza izin verildiğinden emin misiniz? Atamalar genellikle diğer programları çağırmadan gerçek işlevselliği uygulamanızı gerektirir. – kaylum