Guten Tag liebe Gemeinde,
bin ganz neu hier im Forum und auch mit C erst seit Anfang April am werkeln. Das Ganze findet im Rahmen eines Wahlpflichtmoduls meines Biochemiestudiums statt, entsprechend dünn ist das Fundament an Kenntnissen und Erfahrungen.
Aufgabe:
Es gilt ein Programm zu schreiben, das die Torsionswinkel zwischen den Atomen in Nukleinsäuren berechnet, wobei dynamische Speicheralloziierung stattfinden soll. Die Rohdaten dafür werden auch aus PDB-files bezogen, wobei es sich im Grunde nur um Textdateinen handelt (siehe Anhang).
Umstand:
Erst ab Zeile 315 beginnt die relevante Auflistung von den, an der Struktur beteiligten, Atomen. Das sieht dann folgendermaßen aus:
ATOM 1 O5' G A 1 40.972 8.748 5.279 1.00 29.42 O
ATOM 2 C5' G A 1 42.038 7.963 5.819 1.00 25.67 C
ATOM 3 C4' G A 1 41.482 6.699 6.422 1.00 24.13 C
ATOM 4 O4' G A 1 40.978 6.977 7.756 1.00 23.86 O
ATOM 5 C3' G A 1 40.286 6.109 5.685 1.00 21.93 C
ATOM 6 O3' G A 1 40.700 5.292 4.598 1.00 19.64 O
ATOM 7 C2' G A 1 39.606 5.296 6.780 1.00 22.18 C
ATOM 8 O2' G A 1 40.213 4.045 7.016 1.00 22.19 O
ATOM 9 C1' G A 1 39.814 6.197 7.997 1.00 21.83 C
ATOM 10 N9 G A 1 38.695 7.104 8.209 1.00 18.54 N
ATOM 11 C8 G A 1 38.707 8.473 8.103 1.00 17.96 C
ATOM 12 N7 G A 1 37.551 9.017 8.364 1.00 18.23 N
ATOM 13 C5 G A 1 36.724 7.941 8.655 1.00 17.17 C
ATOM 14 C6 G A 1 35.362 7.912 9.019 1.00 15.25 C
ATOM 15 O6 G A 1 34.602 8.855 9.166 1.00 15.04 O
ATOM 16 N1 G A 1 34.909 6.609 9.225 1.00 15.08 N
ATOM 17 C2 G A 1 35.681 5.478 9.105 1.00 16.78 C
ATOM 18 N2 G A 1 35.070 4.308 9.370 1.00 14.87 N
ATOM 19 N3 G A 1 36.961 5.496 8.760 1.00 16.30 N
ATOM 20 C4 G A 1 37.415 6.753 8.556 1.00 17.87 C
ATOM 21 P U A 2 39.955 5.413 3.180 1.00 19.59 P
ATOM 22 OP1 U A 2 40.555 4.430 2.256 1.00 20.04 O
ATOM 23 OP2 U A 2 39.887 6.839 2.784 1.00 20.94 O
ATOM 24 O5' U A 2 38.472 4.919 3.478 1.00 19.95 O
.
.
.
(Die fett markierten Einträge sind für das Lösen der Aufgabe erforderlich)
Ziel:
Erstes großes Ziel wäre die selektive Formatierung der Daten in eine übergeordnete Struktur, indem quasi folgende sprachlich formulierte Aussage C-kryptisch umgesetzt wird:
Falls das erste Wort einer Zeile "ATOM" lautet, sollen die Einträge 2-9 dieser Zeile in die spezifischen Einträge der Struktur "Molecule" geschrieben werden...
Ansatz:
... dazu dachte ich wäre fscanf erstmal sehr nützlich. Das Ganze habe ich mit zwei unendlichen While-Schleifen verknüpft, wobei die erste nur dazu dient "numcount" zu bestimmen. Das wäre dann die Anzahl an ATOM-Zeilen, die dann für die erste For-Schleife wichitg wäre. Diese befindet sich in der zweiten While-Schleife.
Den Kot den man bis jetzt produziert hat sieht so aus:
Problem:
Auf Compilerisch:
warning: writing into constant object (argument 3) [-Wformat=]
fscanf(fpin, "%s","%d","%s","%s","%s","%d","%d","%d","%d", (*mol).ATOM, &(*mol).serialnum, (*mol).
^
warning: too many arguments for format [-Wformat-extra-args]
fscanf(fpin, "%s","%d","%s","%s","%s","%d","%d","%d","%d", (*mol).ATOM, &(*mol).serialnum, (*mol).
--> Wobei es bereits schön wäre wenn das Programm in seiner Ausführung soweit kommen würde, denn es hängt in der ersten While - Schleife fest, was man mit dem printf (line 54) prüfte.
Erkenntnisse:
Wie es so ist; während man das Problem erklärt fällt einem Einiges auf:
--> line 48-53:
wird nicht ausgeführt, sonst wäre numcount nicht 0 && der break müsste stattfinden.
Jetzt lese ich gerade, dass es an dem Unterschied zwischen String ("ATOM") und Char (buff) liegen könnte. Des Weiteren funktioniert der break in der while Schleife nicht, "return 0" hingegen schon, was mich dann halt nur aus der ganzen Funktion wirft, was natürlich zu vermeiden wäre.
--> Da Kette A und B in der PDB-Datei durch eine TER-Zeile (ln 482) getrennt sind könnte das bestimmt Probleme mit fscanf in der While - Schleife geben, da diese Schleife den ATOM-Block ja wie eine kontinuierliche Liste behandeln sollte.
An Euch:
Für jede Art von Hilfe, Inspiration, Tipps oder Erfahrungsaustausch wäre ich sehr dankbar, da ich mit meinem Latein adhuc am Ende bin.
Herzliche Grüße,
JuK
bin ganz neu hier im Forum und auch mit C erst seit Anfang April am werkeln. Das Ganze findet im Rahmen eines Wahlpflichtmoduls meines Biochemiestudiums statt, entsprechend dünn ist das Fundament an Kenntnissen und Erfahrungen.
Aufgabe:
Es gilt ein Programm zu schreiben, das die Torsionswinkel zwischen den Atomen in Nukleinsäuren berechnet, wobei dynamische Speicheralloziierung stattfinden soll. Die Rohdaten dafür werden auch aus PDB-files bezogen, wobei es sich im Grunde nur um Textdateinen handelt (siehe Anhang).
Umstand:
Erst ab Zeile 315 beginnt die relevante Auflistung von den, an der Struktur beteiligten, Atomen. Das sieht dann folgendermaßen aus:
ATOM 1 O5' G A 1 40.972 8.748 5.279 1.00 29.42 O
ATOM 2 C5' G A 1 42.038 7.963 5.819 1.00 25.67 C
ATOM 3 C4' G A 1 41.482 6.699 6.422 1.00 24.13 C
ATOM 4 O4' G A 1 40.978 6.977 7.756 1.00 23.86 O
ATOM 5 C3' G A 1 40.286 6.109 5.685 1.00 21.93 C
ATOM 6 O3' G A 1 40.700 5.292 4.598 1.00 19.64 O
ATOM 7 C2' G A 1 39.606 5.296 6.780 1.00 22.18 C
ATOM 8 O2' G A 1 40.213 4.045 7.016 1.00 22.19 O
ATOM 9 C1' G A 1 39.814 6.197 7.997 1.00 21.83 C
ATOM 10 N9 G A 1 38.695 7.104 8.209 1.00 18.54 N
ATOM 11 C8 G A 1 38.707 8.473 8.103 1.00 17.96 C
ATOM 12 N7 G A 1 37.551 9.017 8.364 1.00 18.23 N
ATOM 13 C5 G A 1 36.724 7.941 8.655 1.00 17.17 C
ATOM 14 C6 G A 1 35.362 7.912 9.019 1.00 15.25 C
ATOM 15 O6 G A 1 34.602 8.855 9.166 1.00 15.04 O
ATOM 16 N1 G A 1 34.909 6.609 9.225 1.00 15.08 N
ATOM 17 C2 G A 1 35.681 5.478 9.105 1.00 16.78 C
ATOM 18 N2 G A 1 35.070 4.308 9.370 1.00 14.87 N
ATOM 19 N3 G A 1 36.961 5.496 8.760 1.00 16.30 N
ATOM 20 C4 G A 1 37.415 6.753 8.556 1.00 17.87 C
ATOM 21 P U A 2 39.955 5.413 3.180 1.00 19.59 P
ATOM 22 OP1 U A 2 40.555 4.430 2.256 1.00 20.04 O
ATOM 23 OP2 U A 2 39.887 6.839 2.784 1.00 20.94 O
ATOM 24 O5' U A 2 38.472 4.919 3.478 1.00 19.95 O
.
.
.
(Die fett markierten Einträge sind für das Lösen der Aufgabe erforderlich)
Ziel:
Erstes großes Ziel wäre die selektive Formatierung der Daten in eine übergeordnete Struktur, indem quasi folgende sprachlich formulierte Aussage C-kryptisch umgesetzt wird:
Falls das erste Wort einer Zeile "ATOM" lautet, sollen die Einträge 2-9 dieser Zeile in die spezifischen Einträge der Struktur "Molecule" geschrieben werden...
Ansatz:
... dazu dachte ich wäre fscanf erstmal sehr nützlich. Das Ganze habe ich mit zwei unendlichen While-Schleifen verknüpft, wobei die erste nur dazu dient "numcount" zu bestimmen. Das wäre dann die Anzahl an ATOM-Zeilen, die dann für die erste For-Schleife wichitg wäre. Diese befindet sich in der zweiten While-Schleife.
Den Kot den man bis jetzt produziert hat sieht so aus:
C++:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<time.h>
#define NATOM 500
/*================================================================*/
typedef struct
{
int line;
int num;
char ATOM[NATOM];
int serialnum[NATOM];
char recname[NATOM];
char residue[NATOM];
char chain[NATOM];
int residueserialnum[NATOM];
double xyz[NATOM][3];
}Molecule;
/*================================================================*/
void check_args(int argc)
{
if(argc != 2)
{
printf("Vorgegebene Eingabestruktur:\n");
printf("[Programmname] [Inputdatei]\n\n");
}
}
/*================================================================*/
void read_molecule(Molecule *mol, char *fname) {
FILE *fpin;
char buff[5];
int i, numcount;
if ( (fpin=fopen(fname, "r")) == NULL) {
printf("Datei %s konnte nicht aufgerufen werden. ABBRUCH.\n\n", fname);
exit(EXIT_FAILURE);
};
while(1){
fscanf(fpin, "%s", buff);
if (buff == "ATOM"){
numcount++;
}
if(buff == "END"){
break;
}
printf("%d", numcount);
}
while (1){
fscanf(fpin, "%s", (*mol).ATOM);
if ((*mol).ATOM == "ATOM"){
for(i=0; i<=(numcount+1); i++){ /*numcount+1, da die Auflistung der Atome durch eine TER-Zeile (line 482) getrennt wird*/
fscanf(fpin, "%s","%d","%s","%s","%s","%d","%d","%d","%d", (*mol).ATOM[i], &(*mol).serialnum[i], (*mol).recname[i], (*mol).residue[i], (*mol).chain[i], &(*mol).residueserialnum[i], &(*mol).xyz[i][0], &(*mol).xyz[i][1], &(*mol).xyz[i][2]);
if((*mol).ATOM == "END"){
break;
}
}
}
break;
}
fclose(fpin);
}
/*================================================================*/
int main(int argc, char *argv[])
{
Molecule mol;
check_args (argc);
read_molecule (&mol, argv[1]);
return 0;
}
Problem:
Auf Compilerisch:
warning: writing into constant object (argument 3) [-Wformat=]
fscanf(fpin, "%s","%d","%s","%s","%s","%d","%d","%d","%d", (*mol).ATOM, &(*mol).serialnum, (*mol).
^
warning: too many arguments for format [-Wformat-extra-args]
fscanf(fpin, "%s","%d","%s","%s","%s","%d","%d","%d","%d", (*mol).ATOM, &(*mol).serialnum, (*mol).
--> Wobei es bereits schön wäre wenn das Programm in seiner Ausführung soweit kommen würde, denn es hängt in der ersten While - Schleife fest, was man mit dem printf (line 54) prüfte.
Erkenntnisse:
Wie es so ist; während man das Problem erklärt fällt einem Einiges auf:
--> line 48-53:
C++:
if (buff == "ATOM"){
numcount++;
}
if(buff == "END"){
break;
}
Jetzt lese ich gerade, dass es an dem Unterschied zwischen String ("ATOM") und Char (buff) liegen könnte. Des Weiteren funktioniert der break in der while Schleife nicht, "return 0" hingegen schon, was mich dann halt nur aus der ganzen Funktion wirft, was natürlich zu vermeiden wäre.
--> Da Kette A und B in der PDB-Datei durch eine TER-Zeile (ln 482) getrennt sind könnte das bestimmt Probleme mit fscanf in der While - Schleife geben, da diese Schleife den ATOM-Block ja wie eine kontinuierliche Liste behandeln sollte.
An Euch:
Für jede Art von Hilfe, Inspiration, Tipps oder Erfahrungsaustausch wäre ich sehr dankbar, da ich mit meinem Latein adhuc am Ende bin.
Herzliche Grüße,
JuK