2012-09-11 24 views
5

Programlama sınıfım için baş ve kuyruk komutlarını yeniden oluşturmaya çalışıyorum. C'yi kullanmaya başladık, böylece bellek ve işaretçileri ayırma fikrine yeniyim. Bunun neden işe yaramadığını merak ediyorum.C Temel Kafa Komutu

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc,char **argv){ 

    /* Checks if correct amount of arguements */ 

    if(argc != 2 || argc != 4){ 
     printf("Usage: %s head <file> \n Or: head <file> -n <number of characters>", argv[0]); 
     exit(-1); 
    } 

    if(strcmp(argv[1], "-n" != 0)){ 
     char fileName[strlen(argv[1])] = argv[1]; 
    } 
} 

//Compile error on char fileName[strlen(argv[1])] = argv[1]; 

Ek bir fikir de yardımcı olabilir.

+1

'dosyaAdı ', yalnızca onun kapalı bloğu içinde görünür, bu durumda" if "ifadesinin pozitif dalı. – gcbenison

+2

Sadece kullanım mesajını göreceksiniz, çünkü eğer argc '2'ye eşitse, 4'e eşit değildir ve eğer 4'e eşitse, 2'ye eşit değildir ve eğer ikisi de değildir. 2 ya da 4, sonra ... –

+0

GCC komut satırında '-std = c99 'belirttiniz mi? Derleyicinin bir VLA (değişken uzunluklu dizi) kabul etmesini sağlamak için bunu yapmanız gerekir. –

cevap

2

İlk bakışta, kullanımınız argüman denetiminizle uyuşmuyor. kullanıma göre, birini kullanmanız gerekir: argv[1]daima dosya adı, başka deyişle

head <filename> 
head <filename> -n <count> 

, argv[2] ikiden fazla bağımsız değişken varsa -n için ayarlanması gerekir biridir. En değiştirmek gerekmez

char *fileName = argv[1]; 

: Eğer VLAS (değişken uzunluk diziler) kullanmak istemiyorsanız

İkincisi, muhtemelen gibi bir şey ile dosya adı argümanı bir işaretçi kurmalıyım hepsi (muhtemelen fopen'a aktarırsınız), bu yüzden başka bir kopyasını yapmaya çalışan bir atık. Ayrıca, if ifademizin or numaralı hata mesajlaşma, yanı and olmalıdır. Her ikisi de aynı anda olamayacağı için argc'un 2 olmayacağı veya 4 olmayacağı garanti edilir.

char fileName[strlen(argv[1])+1]; 
strcpy(fileName, argv[1]); 

veya (eğer dizinin bir kopyasını yapmak için whant yoksa): Ben yazmak daha iyi olduğunu düşünüyorum

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

static int usage (void) { 
    printf ("Usage: head <file>\n"); 
    printf (" or: head <file> -n <number of characters>\n"); 
    return -1; 
} 

int main (int argc,char *argv[]) { 
    char *fileName; 
    int lineCount; 

    // Checks if correct arguments 

    if ((argc != 2) && (argc != 4)) return usage(); 

    if ((argc == 4) && (strcmp(argv[2], "-n" != 0)) return usage(); 

    // Get file spec and line count 

    fileName = argv[1]; 

    lineCount = (argc == 2) ? 10 : atoi (argv[3]); // or strtol for purists 
    if (linecount < 0) lineCount = 0; 

    // Now go ahead and implement the logic for head. 

} 
+0

ve bu yaklaşım ile 'fileName' _not_ argv [1] derin bir kopyası olduğunu unutmayın - sadece içeriğini argv [1] ile paylaşan bir işaretçi. Bu argv [] genellikle asla ayrılmamış olduğundan beri sorun değil. Diğer durumlarda, bu, C. – gcbenison

+2

"Genellikle" "genellikle" ayrılmamış? En azından "ana" geri dönüşüne kadar (ya da programınız başka bir şekilde çıkana kadar) "asla" derdim. – paxdiablo

3

:

Ben böyle bir şeyle başlayacağını

+2

Kopyalamayı değiştirmeyecekseniz argümanın bir kopyasını oluşturmanın gerçekten hiçbir anlamı yok, bu yüzden ikinci öneriniz çok daha mantıklı. –

+0

Bu duruma bağlı değil mi? Yazar bir nedenden dolayı bir kopyasını yapmaya çalıştı, bu nedenle, amaç ile yapılmış olabilir ve bu dizgeyi bir yerde değiştirmek isteyebilir ... – Tutankhamen

+0

"head" kodunda, dosya adı için en makul kullanım açık Bu ve bunun için, kopyaya (orijinal yapmalısınız) ihtiyacınız yok. Bazı durumlarda, adı kopyalayıp düzenlemeye ihtiyaç duyduğunuzda haklısınız. Örneğin, bir çeşit 'derleyici' varsa, çıktı dosyasını belirtmek için giriş dosyasının uzantısını değiştirmek isteyebilirsiniz.Öyleyse, tüm dizenin bir kopyasını almak ve kopyayı düzenlemek iyi bir fikir çünkü açık çağrı ve hata raporlaması gibi şeyler için giriş dosya adına da ihtiyacınız var. –