Avatar billede trp79 Nybegynder
23. oktober 2002 - 22:19 Der er 8 kommentarer og
3 løsninger

sprintf eller andet alternativ

Når jeg bruger følgende kode i C (linux) får jeg en segmentation fault i i linierne hvor jeg bruger sprintf. Hvordan løses denne fejl, og hvorfor opstår den?

int main()
{
...
start(1,login);
....
}

int start(int a, int login)
{
    char *product, *productNrFile, *transactionFile;
    int choice,size;

    if(a=1)
    {
          if (login=1)
        {
            printf("\n****************************************\n");
            printf("1: Køb varer\n");
            printf("2: Sælg varer\n");
            printf("3: Total Transaction\n");
            printf("4: Total Value\n");
            printf("5: Exit\n");
            printf("Make your choice chief: ");
            printf("\n****************************************\n\n");
            scanf("%d",&choice);
            switch(choice)
            {
            case 1:
                printf("Indtast varenummer:");
                scanf("%s",product);
                printf("Indtast antal:");
                scanf("%d",&size);

                sprintf(productNrFile,"%s.txt",product);
                sprintf(transactionFile,"%st.txt",product);

                buy(product,transactionFile,productNrFile, size, login);
                again();
                break;

            case 2:
                printf("Indtast varenummer:");
                scanf("%s",product);
                printf("Indtast antal:");
                scanf("%d",&size);

                sprintf(productNrFile,"%s.txt", product);  //HER DRILLER DEN!!!!!!!!!!!
                //sprintf(transactionFile,"%st.txt",product);

                //printf("\nproductNrfile: %s\n",&productNrFile);
                //printf("transactionfi: %s\n",transactionFile);
                printf("product: %s\n",product);
                printf("antal:  %d\n",size);
                //sale(product,transactionFile,productNrFile, size, login);
                //again();
                exit(0);
                break;

            case 3: printf("\n");
                totalTransaction(login);
                again();
                break;

            case 4: printf("\n");
                totalValue(login);
                again();
                break;

            case 5: exit(0);

            default:
                printf("Tast et gyldigt nummer!\n");
                again();
            }
        }
        else
        {
            printf("\n****************************************\n");
            printf("1: Køb varer\n");
            printf("2: Sælg varer\n");
            printf("3: Exit\n");
            printf("Make your choice worker: ");
            printf("\n****************************************\n\n");
            scanf("%d",&choice);
            switch(choice)
            {
            case 1:
                printf("Indtast varenummer:");
                scanf("%s",&product);
                printf("Indtast antal:");
                scanf("%d",&size);

                sprintf(productNrFile,"%s.txt",product);
                sprintf(transactionFile,"%st.txt",product);

                buy(product,transactionFile,productNrFile, size, login);
                again();
                break;

            case 2:
                printf("Indtast varenummer:");
                scanf("%s",&product);
                printf("Indtast antal:");
                scanf("%d",&size);

                sprintf(productNrFile,"%s.txt",product);
                sprintf(transactionFile,"%st.txt",product);
                sale(product,transactionFile,productNrFile, size, login);
                again();
                break;

            case 3: exit(0);

            default:
                printf("Tast et gyldigt nummer!\n");
                again();
            }
        }
    }
    else
    exit(0);
}
Avatar billede erikjacobsen Ekspert
23. oktober 2002 - 22:21 #1
sprintf(productNrFile,"%s.txt",produ

Du skal allokere plads til productNrFile først
Avatar billede jespernaur Nybegynder
23. oktober 2002 - 22:31 #2
Fx ved at skrive

char productNrFile[100];

(skaffer 100 bytes) i stedet for

char *productNrFile;
Avatar billede soreno Praktikant
23. oktober 2002 - 22:35 #3
du kan også gøre det dynamisk, hvis nu du ikke ved hvor meget plads du har brug for..
productNrFile = (char*) malloc (100);

så skal du bare huske at frigive hukommelsen igen, det sker med:
free (productNrFile);
Avatar billede cms Nybegynder
23. oktober 2002 - 23:38 #4
soreno -> Nå er det den rigtige måde at allokere hukommelse på? Jeg gættede ellers bare :)
Avatar billede soreno Praktikant
23. oktober 2002 - 23:41 #5
du kan læse om malloc her http://www.cplusplus.com/ref/cstdlib/malloc.html
iøvrigt kan http://www.cplusplus.com/ref/indexr.html anbefales at tilføje til bookmarks i browseren.. :-)
Avatar billede trp79 Nybegynder
24. oktober 2002 - 08:01 #6
Det virker ikke når man bytter:
"char *productNrFile;" ud med "char productNrFile[100];"

Hvad mener i med at man skal allokere plads til productNrFile først? gør man ikke netop det ved "char *productNrFile;" ?
Avatar billede trp79 Nybegynder
24. oktober 2002 - 09:31 #7
Jeg har fundet ud af det. Det er åbenbart umuligt at bruge "char *". Man skal selv definere en størrelse. Men jeg fatter ikke hvorfor... anyone?
Avatar billede cms Nybegynder
24. oktober 2002 - 14:25 #8
Ved at skrive "char *" deklarerer du en pointer til et char. Du skal jo også allokere memory til den. Det gøres vhja. malloc som soreno beskrev
Avatar billede ricelius Nybegynder
29. oktober 2002 - 04:27 #9
En char* er en kun en adresse. Det eneste en char* kan holde er adressen på en anden variabel i memory. Hvis ikke du allokerer memory, vil sprintf bare skrive et tilfældigt sted, hvilket ikke er helt godt. Hvis du skriver char[100] deklarerer du 100 chars, et såkaldt array. En char* kan holde adressen på et element i dette array - men den kan ikke holde et tegn (det kan den faktisk godt med lidt tweaking, men det ser vi bort fra her ;)) En af de mest forvirrende ting ved C er pointers; men bare rolig, du skal nok komme til at forstå det på et tidspunkt! ;)
Avatar billede soepro Nybegynder
29. oktober 2002 - 11:49 #10
En char* afsætter ikke automatisk nogen plads til de tegn du vil gemme. og adskiller sig derfor fra f.eks. en int variabel. char* er bare en "pegepind" til et eller andet sted i programmets hukommelse, hvor der ER plads til at gemme tegnene. Denne plads kan man få afsat på flere måder:

char productNrFile[100]; /* Pladsen afsættes af compileren ved oversættelse af programmet, og pladsen bliver først frigivet når programmet afsluttes. */

char *productNrFile = (char *)malloc(100); /* Sætter også plads af til 100 tegn - men først på kørselstidpunktet, og du skal selv frigive den igen. */
free(productNrFile);

char *productNrFile = new char[100]; /* Samme som d.o. i C++ */
delete productNrFile;

Hvis du vil holde din kode i ren C, vil jeg klart foreslåp dig at bruge den første måde, dvs. 'char productNrFile[100]', sog så sørge for at alle dine kopieringer ikke overskriver længden af variablen ved at bruge length-modifier i dine sprintf():

sprintf(productNrFile, "%.*s.txt", sizeof(productNrFile)-1, product);

Den lille '.*' krølle inden i '%s' formatter strengen, betyder at der maksimalt flyttes det antal tegn som '*' bvariablen angiver, altså sizeof()-1. (product skal selvfølgelig OGSÅ defineres.)
Avatar billede trp79 Nybegynder
31. oktober 2002 - 08:29 #11
Lækkert med noget forklaring :o) Jeg takker!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester