Parçalama arızası (çekirdek döküldü)

Başlatan linux4eva, 06 Eylül 2014 - 22:23:15

« önceki - sonraki »

0 Üyeler ve 3 Ziyaretçi konuyu incelemekte.

linux4eva

      Merhaba arkadaşlar. C öğrenmeye başlayalı yaklaşık bir hafta oldu ve ben de basit bir hesap makinesi yapayım dedim. Programı derledikten sonra açmaya çalışınca "Parçalama arızası (çekirdek döküldü)" diye bir hata ile karşılaştım.

  • Bu hata nereden kaynaklanmış  olabilir?
  • Bunu çözmek için ne yapmalıyım?
Programın kaynak kodunu aşağıda verdim. Yardım ederseniz çok büyük bir iyilik yapmış olursunuz  :D.

calculate.c


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

#define NUMBER '0'
#define OPR '1'
#define MAXINPUT 100
double input[MAXINPUT];
int iotype, i, there_is_an_opr = 0;
int oprtype;

int isopr(char *testchr);
void showusage(char *message);
void error(char *errmsg);

main(int argc, char **argv)
{
extern int oprtype;
if(argc > 2) // argv[0] is "./calculate" command and argv[1] is the first number.
{
for(i = 1; i < argc && i <= MAXINPUT; ++i) // Starts scaning at argv[1], the first number.
{
if(isdigit(argv[i]))
iotype = NUMBER;

else if(isalpha(argv[i]) && isopr(argv[i]))
iotype = OPR;

switch(iotype)
{
case NUMBER:
if(there_is_an_opr)
{
switch(oprtype)
{
case 1:
input[i] -= input[i-1];
there_is_an_opr = 0;
break;
case 2:
input[i] += input[i-1];
there_is_an_opr = 0;
break;
case 3:
input[i] *= input[i-1];
there_is_an_opr = 0;
break;
case 4:
input[i] /= input[i-1];
there_is_an_opr = 0;
break;
default:
error("Bult-in error");
}
}
else
input[i-1] = atoi(argv[i]);
break;

case OPR:
there_is_an_opr = 1;
break;
default:
error("Built-in error");
}
}
printf("Result is %6.4lf .\n", input[i]);
return 0;
}
else
showusage("Wrong input format");
return 0;
}

int isopr(char *testchr)
{
int opr;
extern int oprtype;

if(testchr == "+"){oprtype  = 2; opr = 1;}
else if(testchr == "-"){oprtype = 1; opr = 1;}
else if(testchr == "*"){oprtype = 3; opr = 1;}
else if(testchr == "/"){oprtype = 4; opr = 1;}
else{opr = 0;}

return opr;
}

void showusage(char *message)
{
printf("\n=========================================================\n\tError : %s\n\nUsage:\n\n\tcalculate <num> <opr> <num> <opr> ...\n\t<num> MUST be decimal.\n\t<opr> MUST be one of (+) (-) (*) (/) .\n", message);
}

void error(char *errmsg)
{
printf("\n----------------------------------------------------------\n An error occured : %s.\n", errmsg);
}

linux4eva

Lütfen biri yardım edebilir mi sorun acil.

ekremsenturk

Sorun sanırım doğru söz (rakam) girişinden kaynaklanıyor. Ancak rakamların nasıl girileceğini (sırasını ve düzenini) çözemedim.

linux4eva

Kullanımı şöyle, terminalden  "./calculate 5 + 3" diye komut girince çıktı olarak "8"  vermesi gerekiyor. Eğer "./calculate" dersem direk showusage() fonksiyonu çalışıyor fakat herhangi bir karakterle beraber girersem "Parçalama arızası (çekirdek döküldü)" hatası alıyorum.

ekremsenturk

#4
Örneği nerden buldun ?

Nasıl girersen gir, hata veriyor. Örneği yazan kişi sanırım kendisi hiç denememiş.

linux4eva


ekremsenturk

Girdileri parantezler içinde girince sözdizimi hatası veriyor. Sorun "input" (case bölümleri) ile ilgili olmalı.

linux4eva

Yanıt için teşekkür ederim. Peki nasıl düzeltebilirim, bir fikriniz var mı?

ekremsenturk

C bilmediğim için yardımcı olamayacağım. İf satırlarından kaynaklanma ihtimalide olableceğini düşünüyorum. İşlemlerin sıralamansıın doğru oldıuğundan emin olmalısın. Deneme yanılma yolu ile hatanın nedenini kendin bulmalısın.

if

gcc -g -o  cikti kaynak.c komutunu kullanarak kaynak dosyasını "debug" seçeneğiyle derleyin.
gdb cikti komutu ile uygulamayı "debugger" ile açın. run komutunu verin.

linux4eva

Öncelikle yanıt için teşekkür ederim. Verdiğiniz komutları çalıştırdıktan sonra komut satırı argümanı girilmediği için ( argc > 2 olması gerek ) kaynak dosyasında belirtilen
else
showusage("Wrong input format");
return 0;

komutları çalışıyor. Fakat
(gdb) run 5 - 3
Yazarak komut satırı argümanları verirsem de "Result is 0.0000 ." diye çıktı veriyor.
Sanırım @ekremsenturk'ün de dediği gibi if satırlarında sorun var. Yine de yardımlarınız için teşekkür ederim.

Reverser

Başlangıç için hesap makinesi kodunuz gereksiz şekilde karışık olmuş

XFCE ROCKS !
Powered by Thunar & XFWM4



sem

* kod içerisinde neden extern tanımlarına ihtiyaç duydunuz, birden fazla kaynak dosya ya da kütüphane kullanıyor musunuz?
* define makrosu için karşılık neyse onu yazılır, ayrıca string ya da char tırnakları kullanmanıza gerek yok:
  #define NUMBER'0'
#define OPR'1'
burada örneğin NUMBER'ı daha sonra int bir değere atamışsınız bu nedenle
#define NUMBER 0 yazmanız yeterli. Önişlemci komutlarını tekrar gözden geçirmenizi tavsiye ederim.
* switch(oprtype) Bu aşamada ilgili değilken değişken değeri anlaşılmıyor, exter'i bu nedenle bu şekilde tanımladıysanız eğer, main fonksiyonundan önce;
int oprtype şeklinde tanımlamışsınız zaten, ek olarak ispr fonksiyonu içerisinde ya da main fonskiyonunda tekrardan bu değişkeni tanımlamanıza gerek yok, main'den önce tanımladığınızda zaten global değişken oluyor,
istediğiniz her yerden erişebilirsiniz, bu dosya içerisinde.
'
* input[ i ] -= input[i-1];
  there_is_an_opr = 0;
  Bu kod ile yaptığnız varsayım şu; örneğin: 5 + 3 gönderildiğinde, önce 5 i görüyorsunuz, operatör olmadığı için es geçiliyor. Sonra +'yı alıyorsunuz daha sonra 3 geliyor tekrardan i - 1 ile işlem yapıyorsunuz böylece
  atladığınız 5 operandına erişiyorsunuz. Çok gereksiz karmaşık olmuş gerçekten;

void main(){
....
...
  operand1 = argv[1];
  operator = argv[2]
  operand2 = argv[3]
...
...
}


yapıp validasyonları yapsanız tamam olacal aslında. İyi çalışmalar.

Başlarda bu kadar zorlamayın kendinizi =), sıkılmayın sonra =)
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

blackwidow

Alıntı yapılan: linux4eva - 10 Eylül 2014 - 10:39:36
Öncelikle yanıt için teşekkür ederim. Verdiğiniz komutları çalıştırdıktan sonra komut satırı argümanı girilmediği için ( argc > 2 olması gerek ) kaynak dosyasında belirtilen
else
showusage("Wrong input format");
return 0;

komutları çalışıyor. Fakat
(gdb) run 5 - 3
Yazarak komut satırı argümanları verirsem de "Result is 0.0000 ." diye çıktı veriyor.
Sanırım @ekremsenturk'ün de dediği gibi if satırlarında sorun var. Yine de yardımlarınız için teşekkür ederim.

Eğer hala aktifse düzeltirim kodu.

Reverser

konunun üstünden çok geçmiş ama olsun, hemen basitçe yazdım bulunsun burada.


/*
*
* Hesap makinesi
* Reverser
*
*/


#include <stdio.h>
#include <stdlib.h>
#define MAX 256

//Prototip
float topla(float x, float y);
float cikar(float x, float y);
float carp(float x, float y);
float bol(float x, float y);

typedef struct elemanlar { float x; float y; int secenek; } elemanlar;

char kullanim[MAX] = "1 = topla\n2 = cikar\n3 = carp\n4 = bol\n";

int main(int argc, char *argv[])
{
    elemanlar elemanlar;
    printf(kullanim);
    scanf("%d",&elemanlar.secenek);

    if(elemanlar.secenek == 1)
    {
        scanf("%f",&elemanlar.x);
        scanf("%f",&elemanlar.y);
        printf("%.2f",topla(elemanlar.x,elemanlar.y));
    }
    else if(elemanlar.secenek == 2)
    {
        scanf("%f",&elemanlar.x);
        scanf("%f",&elemanlar.y);
        printf("%.2f",cikar(elemanlar.x,elemanlar.y));
    }
    else if(elemanlar.secenek == 3)
    {
        scanf("%f",&elemanlar.x);
        scanf("%f",&elemanlar.y);
        printf("%.2f",carp(elemanlar.x,elemanlar.y));

    }
    else if(elemanlar.secenek == 4)
    {
        scanf("%f",&elemanlar.x);
        scanf("%f",&elemanlar.y);
        printf("%.2f",bol(elemanlar.x,elemanlar.y));
    }
    else
    {
        printf("Hatali secim !\nBir tusa basip devam edin....");
        getchar();
    }
    return 0;
}

float topla(float x, float y)
{
    return x + y;
}

float cikar(float x, float y)
{
    return x - y;
}

float carp(float x, float y)
{
    return x * y;
}

float bol(float x, float y)
{
    return x / y;
}

XFCE ROCKS !
Powered by Thunar & XFWM4



sem

Öneri;

Yardım konularında doğrudan paylaşmama, kişiyi destekleyerek kendisine yaptırabilme taraftarıyım. Bu şekilde sor soran kişiye daha fazla faydası olur.

Fakat üzerinden zaman geçmiş ve giderilmemiş bu şekilde konular için kod paylaşarak, kişilere yardımcı olmak istediğimizde ise, kodlar arasına notlar ve yorumlar düşerek, acemi arkadaşlarımıza yine daha fazla yol gösterelim.

Bu şekilde yaparsak, herkese faydalı olacağını düşünüyorum. Sadece bir öneri tabi ki bu.

Kodları denemedim ama çözüm için yine ayrıca teşekkürler elbette. Verdiğiniz emek için.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

Reverser

@sem, kod arasına not düşmek kafa karıştırabilir. Onun yerine anlaşılmayan yerin mesajla sorulması ardından açıklama yapılması daha doğru olur gibi geliyor bana.

XFCE ROCKS !
Powered by Thunar & XFWM4



Sh4oTT

Alıntı yapılan: linux4eva - 06 Eylül 2014 - 22:23:15
      Merhaba arkadaşlar. C öğrenmeye başlayalı yaklaşık bir hafta oldu ve ben de basit bir hesap makinesi yapayım dedim. Programı derledikten sonra açmaya çalışınca "Parçalama arızası (çekirdek döküldü)" diye bir hata ile karşılaştım.

  • Bu hata nereden kaynaklanmış  olabilir?
  • Bunu çözmek için ne yapmalıyım?
Programın kaynak kodunu aşağıda verdim. Yardım ederseniz çok büyük bir iyilik yapmış olursunuz  :D.

calculate.c


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

#define NUMBER '0'
#define OPR '1'
#define MAXINPUT 100
double input[MAXINPUT];
int iotype, i, there_is_an_opr = 0;
int oprtype;

int isopr(char *testchr);
void showusage(char *message);
void error(char *errmsg);

main(int argc, char **argv)
{
extern int oprtype;
if(argc > 2) // argv[0] is "./calculate" command and argv[1] is the first number.
{
for(i = 1; i < argc && i <= MAXINPUT; ++i) // Starts scaning at argv[1], the first number.
{
if(isdigit(argv[i]))
iotype = NUMBER;

else if(isalpha(argv[i]) && isopr(argv[i]))
iotype = OPR;

switch(iotype)
{
case NUMBER:
if(there_is_an_opr)
{
switch(oprtype)
{
case 1:
input[i] -= input[i-1];
there_is_an_opr = 0;
break;
case 2:
input[i] += input[i-1];
there_is_an_opr = 0;
break;
case 3:
input[i] *= input[i-1];
there_is_an_opr = 0;
break;
case 4:
input[i] /= input[i-1];
there_is_an_opr = 0;
break;
default:
error("Bult-in error");
}
}
else
input[i-1] = atoi(argv[i]);
break;

case OPR:
there_is_an_opr = 1;
break;
default:
error("Built-in error");
}
}
printf("Result is %6.4lf .\n", input[i]);
return 0;
}
else
showusage("Wrong input format");
return 0;
}

int isopr(char *testchr)
{
int opr;
extern int oprtype;

if(testchr == "+"){oprtype  = 2; opr = 1;}
else if(testchr == "-"){oprtype = 1; opr = 1;}
else if(testchr == "*"){oprtype = 3; opr = 1;}
else if(testchr == "/"){oprtype = 4; opr = 1;}
else{opr = 0;}

return opr;
}

void showusage(char *message)
{
printf("\n=========================================================\n\tError : %s\n\nUsage:\n\n\tcalculate <num> <opr> <num> <opr> ...\n\t<num> MUST be decimal.\n\t<opr> MUST be one of (+) (-) (*) (/) .\n", message);
}

void error(char *errmsg)
{
printf("\n----------------------------------------------------------\n An error occured : %s.\n", errmsg);
}


Arkadas 1 haftada bu kadar nasıl ılerledın C de ben 3 aydır calısıyorum www.volkankilic.com adresindeki 43 dersi yeni bitirdim sayılır. Ben mi cok yavas ılerlıyorum yoksa sen cokmu hızlısın moralım bozuldu :( :/