Hier ist mein Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main (void) {
struct addrinfo hints;
memset (&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_CANONNAME;
struct addrinfo *res;
getaddrinfo ("example.com", "http", &hints, &res);
printf ("Host: %s\n", "example.com");
void *ptr;
while (res != NULL) {
printf("AI Family for current addrinfo: %i\n", res->ai_family);
switch (res->ai_family) {
case AF_INET:
ptr = (struct sockaddr_in *) res->ai_addr;
struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr;
break;
}
res = res->ai_next;
}
return 0;
}
was gut kompiliert.
Wenn ich jedoch diese Zeile auskommentiere:
//ptr = (struct sockaddr_in *) res->ai_addr;
Ich werde bekommen:
$ gcc ex4.c
ex4.c:30:9: error: expected expression
struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr;
^
1 error generated.
Was vermisse ich?
Jeder Fall in einer switch-Anweisung ist technisch gesehen ein Label. Aus einigen obskuren und alten Gründen dürfen Sie keine Variablendeklaration als erste Zeile nach einem Label haben. Indem Sie die Aufgabe auskommentieren
ptr = (struct sockaddr_in *) res->ai_addr;
die Linie
struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr;
wird zur ersten Zeile nach dem Label AF_INET:
was, wie gesagt, in C illegal ist.
Die Lösung besteht darin, alle Ihre Case-Anweisungen wie folgt in geschweifte Klammern einzuschließen:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main (void) {
struct addrinfo hints;
memset (&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_CANONNAME;
struct addrinfo *res;
getaddrinfo ("example.com", "http", &hints, &res);
printf ("Host: %s\n", "example.com");
void *ptr;
while (res != NULL) {
printf("AI Family for current addrinfo: %i\n", res->ai_family);
switch (res->ai_family) {
case AF_INET:
{
ptr = (struct sockaddr_in *) res->ai_addr;
struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr;
break;
}
}
res = res->ai_next;
}
return 0;
}
Jedenfalls denke ich, dass dies eine bessere Codierungspraxis ist.
Als Ergänzung zur akzeptierten Antwort können Sie Ihre Variablen vor den Fallbezeichnungen deklarieren.
switch(a) {
int b; //can't initialize variable here
case 0:
...
}
Oder verwenden Sie einfach eine leere Anweisung.
Vielleicht sollte der Titel dieser Frage bearbeitet werden? Kann das jemand mit mehr Erfahrung tun, wenn er damit einverstanden ist?
– Koray Tugay
9. Juni 2015 um 13:58 Uhr
Sie sollten in der Lage sein, es selbst zu bearbeiten, wenn Sie möchten. Aber ich stimme zu, der Titel könnte besser sein.
– FrageC
9. Juni 2015 um 15:28 Uhr
@KorayTugay, ich habe es versucht.
– Paul Tucher
9. Juni 2015 um 16:32 Uhr
Eine Variablendeklaration innerhalb von a
case
(ohne umgebende Klammern, wie in der obersten Antwort vorgeschlagen) ist eine schlechte Idee, da dann der Name der Variablen später sichtbar wirdcase
s, aber es wird nicht initialisiert (es sei denn, Sie sind heruntergefallen).– MM
9. Juni 2015 um 23:56 Uhr