2016-06-21 8 views
2

Ich möchte ganze Zahlen aus einer Zeichenfolge extrahieren, z. Ich möchte 0 als Gruppenbezeichner und 1 als mdev-Bezeichner aus der Zeichenfolge "/ dev/nkdev/group0/mdev1" extrahieren.Wie extrahiere ich Integer aus String im Linux-Kernel?

In der obigen Zeichenfolge "/ dev/nkdev/group" ist ein festes Muster in der Eingabe, Gruppen-ID kann eine ganze Zahl zwischen 0-9 sein und "mdev" ist auch nicht festgelegt, es kann eine beliebige Zeichenfolge folgen eine ganze Zahl.

verwendet I-Code folgende

#define NO_INTEGER "%0[^0-9]" 

res = sscanf(dev_name_p, NO_INTEGER "%u" NO_INTEGER "%u", 
      &group_id, &mdev_id); 

Aber ich fand Sprungsequenz nicht in Kernel unterstützt wird. Kann irgendjemand sagen, ob es eine Kernel-Library-Funktion gibt, die den Job erledigt?

+0

Ist es nicht möglich, das Format '/ dev/zu verwenden nkdev/group% u/mdev% u'? – bzeaman

+0

Danke, es hätte möglich sein können, wenn mdev ein festes Muster wäre, in meinem Fall ist mdev auch kein fixed. Es kann eine beliebige Zeichenfolge sein. – iGRJ

+2

Was ist dann mit '/ dev/nkdev/group% u /% * s% u'? – bzeaman

Antwort

-1

Diese Lösung läuft im Userspace, aber alle Funktionen sind hier im Kernel-Raum mit dem gleichen Ergebnis gebrauchten

Schmutzig, aber es wird funktionieren:

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

int main(int argc, char **argv) 
{ 
    char string[] = "/dev/nkdev/group4/mdev12"; 
    char *stringp = (char *)&string; 
    const char delimiters[] = "/"; 
    char *token; 
    int num1, num2; 

    token = strsep (&stringp, delimiters);  /* token => "" */ 
    token = strsep (&stringp, delimiters);  /* token => "dev" */ 
    token = strsep (&stringp, delimiters);  /* token => "nkdev" */ 
    token = strsep (&stringp, delimiters);  /* token => "group0" */ 
    while (*token != 0 && (*token < '0' || *token > '9')) 
     token++; 
    num1 = strtol(token, NULL, 10); 
    token = strsep (&stringp, delimiters);  /* token => "mdev1" */ 
    while (*token != 0 && (*token < '0' || *token > '9')) 
     token++; 
    num2 = strtol(token, NULL, 10); 
    printf("num1: %d\nnum2: %d\n", num1, num2); 
} 
+0

Lieber Down-Wähler, ich würde gerne Ihre Meinung zu diesem Problem mit dieser Lösung hören. –

+0

@AndyShevchenko Sehr konstruktiv, markiert –

+0

Ich weiß nicht, was kann ich mehr tun, damit Sie die Frage vor der Beantwortung lesen. – 0andriy

2

kstrtoint() - konvertiert ein string zu einem int.

kstrtol() - konvertieren Sie eine Zeichenfolge in eine lange.

Check-Deklaration in Linux-Kernel soruce Baum /include/linux/kernel.h .Sie wird diese Headerdatei # include < linux/kernel.h> vor der Verwendung dieses fuction müssen umfassen.

Example : 

    const char *buf = "123"; 
    long value; 
    if(kstrtoint(buf, 10, &value) != 0) 
     return -1; 
    printk("%d",value); 
+0

Dies funktioniert nicht für Strings, die nicht ausschließlich aus Ziffern bestehen, testen Sie Ihre Lösung mit "/ dev/nkdev/group1/mdev2" –

+0

Dies funktioniert in der Tat nicht und beantwortet die Frage nicht. – bzeaman

2

Ein String-Format, wie ich in diesem Beispiel verwenden, funktionieren sollte:

#include <stdio.h> 

int main(void) 
{ 
     unsigned a = 38, b = 38; // Default magic value 
     int n = sscanf("/dev/nkdev/group0/abc1", "/dev/nkdev/group%u/%*[a-z]%u", &a, &b); 

     printf("n: %i, a: %u, b: %u\n", n, a, b); 

     return 0; 
} 

Es diesen Ausgang ergibt:

n: 2, a: 0, b: 1 
+0

Dies sollte die akzeptierte Antwort sein, schnell, einfach und funktioniert in allen Fällen –

+0

Es funktioniert nicht im Linux Kernel-Bereich, da '% * [a-z]' Sequenz-Formatierung im Kernel-Bereich nicht unterstützt wird. Ich habe einen ähnlichen Ansatz in meinem Code verwendet, der mit libc funktioniert, aber nicht im Kernel-Bereich funktioniert. – iGRJ