ubuntuusers.de

Codeblocks:gcc "Segmentation Fault

Status: Ungelöst | Ubuntu-Version: Ubuntu 10.10 (Maverick Meerkat)
Antworten |

vytic

Anmeldungsdatum:
11. Januar 2011

Beiträge: Zähle...

Gerade habe ich mir Codeblocks incl. gcc installiert und versucht ein kurzes Programm zu übersetzen, was soweit auch funktioniert hat, doch wenn ich es von Codeblocks ausführen lassen gibt das Terminal mir die Fehlermeldung "Segmentation Fault" zurück. Welche Ursachen kann das haben? Ist mir persönlich ein gänzlich fremder Fehler den's unter Windows nie gab.

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



int main(void)
{


    char buffer[256];
    int value = 0;
    FILE *src = fopen("test.txt","rb");

    fgets(buffer, sizeof(buffer), src);

    buffer[strlen(buffer)] = 0;
    for(int i = 0; i < strlen(buffer); i++)
    {
        value += (buffer[i]-48)*(strlen(buffer)-i);
    }
    printf("%i", value);

}
Code

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2505

Servus,

da du nicht prüfst, ob „fopen()“ auch erfolgreich war, wäre mal meine erste Idee: Er kann die Datei nicht öffnen. Wenn du jetzt sagst: „Die gibt es aber!“ Dann frage ich: „Auch in dem Verzeichnis, in dem dein Programm läuft?“ 😉

Desweiteren glaube ich nicht, dass du deinen String manuell null-terminieren musst (Zeile „buffer[strlen(buffer)] = 0;“ meine ich). „strlen()“ orientiert sich ohnehin am Null-Terminator, also bewirkt diese Zeile genau gar nichts, oder? Das dürfte zwar zu keinem Segfault führen, aber naja.

Was machst du eigentlich, wenn die Zeile mehr als 255 Zeichen enthält? Oder ist das ausgeschlossen? Finde da „getline()“ etwas entspannter:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
	FILE *fp;
	char *line = NULL;
	size_t len = 0;
	ssize_t read;
	int i, value;

	fp = fopen("test.txt", "r");
	if (fp == NULL)
	{
		fprintf(stderr, "Couldn't open file.\n");
		exit(EXIT_FAILURE);
	}

	while ((read = getline(&line, &len, fp)) != -1)
	{
		value = 0;
		for (i = 0; i < strlen(line); i++)
		{
			value += (line[i] - 48) * (strlen(line) - i);
		}
		printf("%d\n", value);
	}

	free(line);
	fclose(fp);

	exit(EXIT_SUCCESS);
}

(Baut auf dem Beispiel aus „man 3 getline“ auf.)

Vielleicht stehe ich auf dem Schlauch, aber was tut deine Berechnung da eigentlich? 😀

HTH. ☺

vytic

(Themenstarter)

Anmeldungsdatum:
11. Januar 2011

Beiträge: 12

Nehmen wir an du hast eine Textdatei in der, als Zeichenkette, eine Zahl steht - du willst den Wert aber als integer haben; also erschaffe ich einen Wert, der dem durch den String dargestellten entspricht.

Die Zeichenkette wird auf keinen Fall jemals länger als 255 sein.

Der Berechnungsterm ist noch falsch, wie ich gerade sehe - hatte ihn schonmal in korrekter Form, ist aber bei meiner Umpartitionierung verschwunden 😀

Was fopen angeht, das scheint der Fehler gewesen zu sein.

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2505

Ah, so ist das.

Suchst du im Endeffekt atoi oder strtol?

vytic

(Themenstarter)

Anmeldungsdatum:
11. Januar 2011

Beiträge: 12

Nein, etwas schnelleres.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

vytic schrieb:

Nein, etwas schnelleres.

Hu? Wie das?

vytic

(Themenstarter)

Anmeldungsdatum:
11. Januar 2011

Beiträge: 12

Na! ich hoffe einfach, dass mein Code am Ende eleganter ist .. womit ich nicht rechne, aber testen will ichs.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

vytic schrieb:

Na! ich hoffe einfach, dass mein Code am Ende eleganter ist .. womit ich nicht rechne, aber testen will ichs.

Frommer Wunsch denke ich mal 😉

Außerdem kapiere ich das Problem immer noch nicht zu 100%. Du hast in einer ASCII-Datei in den zeilen jeweils Ziffern stehen und willst die daraus resultierende Zahl als Integer im Programm formen? Ist das so richtig?

vytic

(Themenstarter)

Anmeldungsdatum:
11. Januar 2011

Beiträge: 12

Korrekt.

Ich arbeite an meiner privaten USB-Device Verschlüsselung, die im Wesentlichen alle Dateien in eine einzelne reinschreibt, sie codiert + verschlüsselt, die Ursprungsfiles löscht und dafür ein Textfile erstellt in dem steht in welchen Verzeichnissen sich die ursprünglichen Dateien befanden, wie sie hießen, welches Format sie hatten und wie groß sie waren - damit man sie auch zurück gewinnen kann. Und um die Dateigröße auszulesen will ich dann diese Funktion verwenden.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Dir ist schon klar, dass es eine Maximalgröße für Integer gibt? Insofern machen da 255 Bytes keinen Sinn, die Grenze dürfte abhängig vom System deutlich darunter liegen.

Was stört Dich an der atoi-Funktion?

Alternativ kannst Du eine der div. "strto*"-Funktionen nutzen: http://www.elook.org/programming/c/stdstring.html

Ansonsten bietet die glib auch wrapper für diese Funktionen: http://library.gnome.org/devel/glib/stable/glib-String-Utility-Functions.html#g-ascii-strtoll

Imho ist das alles besser, als da selber etwas hinzufrickeln. Zumal Dein Code - bei aller Vorsicht - nicht den Eindruck macht, als könntest Du das eleganter lösen, als C-Cracks, die die obigen Dinge implementiert haben.

Solltest Du - wieso auch immer - diese Libs nicht komplett einbinden wollen (wobei Du die Standardlib ja wohl eh komplett nutzt?), dann schau Dir wenigstens den Quellcode davon an und übernimm diesen in Dein Projekt.

vytic

(Themenstarter)

Anmeldungsdatum:
11. Januar 2011

Beiträge: 12

Berechtigte Einwände; meine Funktion ist jetzt augenscheinlich so schnell wie atoi.

255 war nur eine vorrübergehende Wahl.

    char buffer[32];   // Max Size 4 294 967 295
    memset(buffer, 0, sizeof(buffer));
    FILE *src = fopen("test.txt","rb");
    unsigned long value = 0;

    fgets(buffer, sizeof(buffer), src);

    for(int i = 0; i < strlen(buffer)-1; i++)
        value += (buffer[i]-48) * potenz(10, strlen(buffer)-i-1);
Antworten |