C API String Parsing/Returning
Gerhard Häring
gh at ghaering.de
Mon Apr 6 08:57:01 EDT 2009
k3xji wrote:
> Hi all,
>
> This might be a newbie question. I am trying to implement a simple
> string decoder/encoder algorithm. Just suppose I am substrcating some
> values from the string passed as a parameter to the function and I
> want the function to return encoded/decoded version of the string.
>
> Here is the call:
> ss= esauth.penc('s')
> st = esauth.pdec(ss)
>
> static PyObject *
> pdec(PyObject *self, PyObject *args)
> {
> unsigned char *s= NULL;
>
> unsigned int v,len,i = 0;
>
> if (!PyArg_ParseTuple(args, "s", &s))
> return NULL;
> if (!s)
> return NULL;
These two lines are superfluous. s now points to the contents of the
Python string (which must not contain any 0 characters, else a TypeError
is raised instead). Python strings are immutable, so you should *not
modify this C string*.
> len = strlen(s);
>
> for(i=0;i<len;i++) {
> if (s[i] > 10)
> s[i] = s[i] - 10;
> }
>
> return Py_BuildValue("s",s);
> }
>
>
> This is returning the original string. I mean the parameter is changed
> but the Py_BuildValue is returning the original string passed in as
> param. [...]
Yes, that's because you're returning a Python string from the string
passed in ;-)
You should do something else instead:
char* buf = strdup(s);
if (!buf) {
PyErr_SetString(PyExc_MemoryError, "Out of memory: strdup failed");
return NULL;
}
/* TODO: your string manipulation */
return PyString_FromString(buf); /* return Py_BuildValue("s", buf); */
If you want to cope with Python strings that may contain 0 bytes, parse
them with "s#" instead. This should normally be better because you avoid
the strlen() this way.
HTH
-- Gerhard
More information about the Python-list
mailing list