Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : Typenbezeichnungen expandieren



Deever
29-11-2004, 18:42
Hey Amigos, wie geht's?

So ich habe zum Bleistift so eine Datei:
[...]
int getc(*fz);
int getchar(v);
char *gets(*cz);
void perror(*cz);
int printf(*cz,...);
int putc(i,*fz);
int putchar(i);
int puts(*cz);
[...]Jetzt möchte ich aus diesen Dingern syntaktisch korrekte Funktionsprototypen machen, also zum Beispiel von "void perror(*cz);" zu "void perror(*char);". Mit awk wäre das auch keine Sache, ich habs aber in C probiert, und das will einfach nicht hinhauen!
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{
char buf[1025]="\0";
FILE *feil;

struct {
char kurz[4];
char lang[10];
} typen[] = {
"i\0", "int\0",
"i1\0", "int\0",
"i2\0", "int\0",
"iz\0", "int\0",
"v\0", "void\0",
"vz\0", "void\0",
"vz1\0","void\0",
"vz2\0","void\0",
"cz\0", "char\0",
"cz1\0","char\0",
"cz2\0","char\0",
"d\0", "double\0",
"d1\0", "double\0",
"d2\0", "double\0",
"dz\0", "double\0",
"l\0", "long\0",
"l1\0", "long\0",
"l2\0", "long\0",
"u\0", "unsigned\0",
"s\0", "size_t\0",
"s1\0", "size_t\0",
"s2\0", "size_t\0",
"k0\0", "time_t\0",
"k1\0", "time_t\0",
"kz\0", "time_t\0",
"j\0", "jmp_buf\0",
"w\0", "va_list\0",
"x\0", "fpos_t\0",
"xz\0", "fpos_t\0",
"y\0", "wchar_t\0",
"yz\0", "wchar_t\0",
"t\0", "struct tm\0",
"t1\0", "struct tm\0",
"t2\0", "struct tm\0",
"tz\0", "struct tm\0",
'\0', '\0'
};

feil = fdopen(0, "r");
while (fgets(buf, 1025, feil)!=NULL) { /* iterate the input */
int ibuf;
for (ibuf=5; ibuf<strlen(buf); ibuf++) { /* iterate the buffer */
int tbuf=0;
while (typen[tbuf].kurz!=NULL) { /* iterate the type list */
if (memcmp(&buf[ibuf],typen[tbuf].kurz,strlen(typen[tbuf].kurz))==0
&& (buf[ibuf-1]=='(' || buf[ibuf-1]==',' || buf[ibuf-1]=='*')
&& (buf[ibuf+strlen(typen[tbuf].kurz)]==',' || buf[ibuf+strlen(typen[tbuf].kurz)]==')')) {
write(1, typen[tbuf].lang, strlen(typen[tbuf].lang)-1);
continue;
} else write(1, &buf[ibuf], 1);
tbuf++;
}
}
}

return 0;
}
Das ergibt
deever@floatkiller:~/bin $ < stdio.h | arguments
cccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccc ccccccccccccccccccccccccccccccccccccccczsh: 3251 done < stdio.h |
zsh: 3252 segmentation fault arguments
Was klappt da nicht?

Vielen Dank für eure Antworten!
Gruß,
/dev

wraith
29-11-2004, 19:53
Jetzt möchte ich aus diesen Dingern syntaktisch korrekte Funktionsprototypen machen, also zum Beispiel von "void perror(*cz);" zu "void perror(*char);".

void perror(char*);

Der entscheidende Fehler ist diese Zeile


while (typen[tbuf].kurz!=NULL)

Das kann nicht hinhauen, weil kurz als char[4] deklariert ist, und du mit deiner Überprüfung fragst, ob die Adresse != 0 ist.Das ist sie sicherlich, auch wenn die Zeichen, die in kurz drinstehen 0 sind.
Du müßtest also prüfen, ob typen[tbuf].kurz[0] != 0 ist.
Ansonsten könntest du auch kurz und lang als (const) char* deklarieren, das ist dann ein Zeiger, der auch auf 0 zeigen kann.

Der rechstliche Code war doch recht unübersichtlich, die Herangehensweise ist suboptimal.
Besser wäre es, den String in Tokens zu zerlegen, also einen kleinen Parser zu bauen.

Und ein "String" ist immer nullterminiert, also ist es unnötig "String\0" zu schreiben.Die Ausnahme char foo[3] = "123"; trifft hier nicht zu.