C Auslesen einer Datei

FlowRider007

Cadet 1st Year
Registriert
Juni 2017
Beiträge
10
Guten Tag liebes Forum!

Ich bin momentan dabei, ein C-Programm zu schreiben, bei dem ich eine .graph-Datei einlese und der Compiler mir die Datei in eine .tgf-Datei umschreibt! Leider bin ich langsam etwas verzweifelt. Und zwar:

Mit Netzwerken klappt alles wunderbar, aber bei Graphen tue ich mich leider schwer. Ich weiß nicht, welche Anweisung ich dem Compiler geben muss, damit er versteht, was ich von ihm will :confused_alt:

C:
    for( i = 1; i <= Knoten; i++ ) //Zeilenschleife
    {
        for( j = 1; j <= Knoten; j++ ) //Spaltenschleife
        {
            if ( AdjMatrix [ i ][ j ] > 0 && gewichtet == 1 )
            {
                fprintf( file_Schreiben, "%d %d %d\n", i, j, AdjMatrix [ i ][ j ] );
            }
            else
            {
            if ( AdjMatrix [ i ][ j ] > 0 && gerichtet == 1 )
                {
                    fprintf( file_Schreiben, "%d %d\n", i, j );
                }
            }
        }
    }

Ziel des Ganzen ist, dass er mir z.B. diesen Graphen: graph_1_0_10_22.graph

Code:
10
22
0
1 1 4
1 1 6
1 1 8
1 2 1
1 2 3
1 3 2
1 3 6
1 3 8
1 4 1
1 4 8
1 5 7
1 5 10
1 6 4
1 6 5
1 7 2
1 7 3
1 8 1
1 8 3
1 8 4
1 8 7
1 10 2
1 10 5

in jener Form ausgibt: graph_1_0_10_22.tgf

Code:
10
22
0
#
1 4
1 6
1 8
2 1
2 3
3 2
3 6
3 8
4 1
4 8
5 7
5 10
6 4
6 5
7 2
7 3
8 1
8 3
8 4
8 7
10 2
10 5

Könnt ihr mir dabei helfen?

MfG
 
Disclaimer: Ich kenne mich weder mit dem einen noch dem anderen Format aus, aber ausgehend von deinem Beispiel würde ich es wohl so machen:

1. Datei Zeilenweise einlesen
2. Zeilen 1-3 direkt so in die tgf Datei schreiben.
3. # Schreiben
4. Die verbleibenden Zeilen am ersten " " splitten und die zweite hälfte in die tgf Datei schreiben
 
  • Gefällt mir
Reaktionen: BAGZZlash
Ich würde die Zeilen lieber in Substrings/Chars (geteilt nach Leerzeichen) aufteilen und dann die gewünschten Strings/Chars über ne foreach ausgeben.
Habe aber auch keine Ahnung von diesen Formaten mit denen du arbeitest.
 
Ich verstehe deine Daten nicht du hasst edges mit nodes die es nicht gibt.
 
Ebrithil schrieb:
1. Datei Zeilenweise einlesen
2. Zeilen 1-3 direkt so in die tgf Datei schreiben.
3. # Schreiben
4. Die verbleibenden Zeilen am ersten " " splitten und die zweite hälfte in die tgf Datei schreiben
Sorry, konnte mir leider nicht verkneifen, das augenblicklich in Perl so zu machen ;) (kein Programm nötig, geht auf der Kommandozeile):
Perl:
 perl -lane 'shift @F if @F>2; print "#" if $.==4; print join " ",@F' graph_1_0_10_22.graph
Resultat:
10
22
0
#
1 4
1 6
1 8
2 1
2 3
3 2
3 6
3 8
4 1
4 8
5 7
5 10
6 4
6 5
7 2
7 3
8 1
8 3
8 4
8 7
10 2
10 5
Ergänzung ()

Multivac schrieb:
Ich verstehe deine Daten nicht du hast edges mit nodes die es nicht gibt.
Naja, ich nehme an, die Zahl "10" bedeutet, er hat nodes von 1 bis 10 und 22 edges dazwischen?
 
Zuletzt bearbeitet:
Dann musst du noch ein bisschen Arbeit in dein perl script stecken

Trivial Graph File Format
The Trivial Graph Format (TGF) is a simple text-based file format for describing graphs. A TGF file consists of a list of node definitions, that map the node IDs to labels, followed by a list of the edges. In this format it is only possible to have one label per node and one value per edge. Rocs interprets imported graphs as undirected graphs. Exported graphs will contain two edges per connection if connections are bidirectional.
Format Specification
  • The file starts with a list of nodes (one node per line), followed by a line with the only character "#", followed by a list of edges (one edge per line).
  • A node consists of an integer (identifier), followed by a space, followed by an arbitrary string.
  • An edge consists of two integers (identifiers) separated by a space, followed by a space, followed by an arbitrary string. It is assumed that the directed edge points from the first identifier to the second identifier.
Example
1 starting node
2 transmitter
3 sink
#
1 2 blue
2 1 red
2 3 green
 
  • Gefällt mir
Reaktionen: blöderidiot
Multivac schrieb:
Trivial Graph File Format
...
1 starting node
2 transmitter
3 sink
#
1 2 blue
2 1 red
2 3 green
OK, ich sehe schon ... Ich vermute mal, dass der OP das Format für was anderes/eigenes "missbraucht", das mit dem Original-TGF nicht viel zu tun hat aber noch so ähnlich aussieht.
 
Erstmal Dankeschön für eure zahlreichen Antworten!

Die Aufgabe ist es, diese .graph Datei umzuwandeln in eine .tgf Datei. NUR mithilfe von Schleifen. Auslesen soll er die Daten mit fscanf und ausgeben in die .tgf Datei soll er die Daten mit fprintf. Wie ich die Schleife aber schreiben muss, wird mir leider nicht klar!

Es soll alles automatisch passieren, ohne dass ich selbst an der Datei schraube.

PS: Der Quellcode oben ist nur ein Teil der gesamten Codes. Wenn es übersichtlicher ist , poste ich den gesamten Code.
 
FlowRider007 schrieb:
Die Aufgabe ist es, diese .graph Datei umzuwandeln in eine .tgf Datei. NUR mithilfe von Schleifen. Auslesen soll er die Daten mit fscanf und ausgeben in die .tgf Datei soll er die Daten mit fprintf.
Das - zusammen mit Deinem Eingangsposting - ergibt leider wenig Sinn. Woher kommt die Aufgabe? Ist das ein x-y-Problem? Was wäre nicht richtig am weiter oben geposteten einfachen:
perl -lane 'shift @F if @F>2; print "#" if $.==4; print join " ",@F' graph_1_0_10_22.graph
Hmmmm ...
Wie ich die Schleife aber schreiben muss, wird mir leider nicht klar!
WAS für eine Schleife? Und was hat das Codefragment im Eingansposting mit den beinahe identischen (gerichtet/gewichtet) if-Bedingungen damit zu tun?
Code:
...
if ( AdjMatrix [ i ][ j ] > 0 && gewichtet == 1 )   {
   ...
}
else  {
   if ( AdjMatrix [ i ][ j ] > 0 && gerichtet == 1 ) {
...
Sehr rätselhaft ...
Es soll alles automatisch passieren, ohne dass ich selbst an der Datei schraube.
Kannst Du den Prozess des "Schraubens" näher erläutern?
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: abcddcba
Ich verstehe die Schleifen am Anfang schon gar nicht:
C:
for( i = 1; i <= Knoten; i++ ) //Zeilenschleife
    {
        for( j = 1; j <= Knoten; j++ ) //Spaltenschleife

Was ist denn Knoten? Und warum sollten sowohl Anzahl der Zeilen als auch Spalten hier den Anzahl der Knoten? ensprechen? Das macht doch keinen Sinn.

Um nochmal auf das Eingabe Format einzugehen:
  • 1. Zeile ist die Anzahl der Knoten
  • 2. Zeile ist die Anzahl der Kanten
  • 3. Zeile - keine Ahnung ...

Du hast also 10 Knoten und 22 Kanten im Graph.

Also jede Kante ist
Gerichtet/Ungerichtet - Source - Target

Nicht dass du das Format mal erläutert hättest ...

Und du willst einfach nur die erste Spalte entfernen, korrekt? Wo ist jetzt das Problem? Die ersten 3 Zeilen sind wohl fix und beschreiben den Graph allgemein, daher weißt du auch die Zeilen und die Spalten.
Ich verstehe ehrlich gesagt nicht wo es grade hakt ... magst du deine Schleifen mal erklären, du musst dir ja dabei was gedacht haben? Warum jeweils den Zähler bis zu Knoten?

Mal abgesehen davon dass ich das ganze wohl auch mit Perl oder mit AWK machen würde ist die Aufgabe ja selbst in C mehr als trivial wenn man das Format eh kennt resp. auslesen kann.

Ohne das # wär das mit
Bash:
awk '{if (NF == 1) { print } else {print $2 " " $3}}' graph_1_0_10_22.graph > graph_1_0_10_22.tgf
quasi erledigt.
Das # kannst du dann noch einfügen, du kennst ja die Zeilennummer, entweder du machst es mit awk in dem du noch eine weitere if Bedingung hinzufügst, oder halt sed oder ...

Aber hier extra den C Compiler anwerfen, kann man vermeiden - sofern dass wirklich der ganze Task ist.
 
  • Gefällt mir
Reaktionen: blöderidiot
Zurück
Oben