Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Fucking C

Name: Anonymous 2012-11-03 14:43

Why it doesn't show me strings like "  a"?
Why is the while loop in the trim function bugged (if I input 2 chars the next input length can't be less than 2)?

#include <stdio.h>

#define MAX 1001

int getLine(char s[], int length){ // returns 1 or 0

    int i, qttWord = 0; //qttWord = counter of letters for s[]
    int c; // c = getchar()

    /*Reads the input and puts it into s[], then, verifies if the input is just \n,
    * if so, returns 0(i), if not, puts '\0' at the end of the string.
    */
    for (i = 0; i < length-1 && (c = getchar()) != EOF && c != '\n'; ++i){
            s[i] = c;
            ++qttWord;

    }
    if (i == 0){
        return 0;
    } else if (c == '\n'){
        ++i;
        s[i] = '\0';

    }
    /*Verifies if the string is just ' ' or '\t'
    * if so, returns 0
    */
    char flag = '\0';
    for (i = 0; i < qttWord && flag != '1'; ++i){
        if (s[i] == ' ' || s[i] == '\t'){
            flag = '0';
        } else{
            flag = '1';
        }
    }
    if (flag == '0')
        return 0;

    return qttWord;
}
void trim(char s[], int length){

    char s2[MAX];
    int i, qttWord = 0;

    /*while (s[length] != '\0'){
        ++length;
    }
    printf("length:%d\n", length);*/
    for (i = 0; i < length; ++i){
        if (i < length-1){
            if (s[i] == ' ' && s[i+1] != ' '){
                s2[i] = s[i];
                ++qttWord;
                printf("1:%d\n", s2[i]);// if true prints "1" and the character(' ')
            }
        }
        if (s[i] != ' '){
            s2[i] = s[i];
            ++qttWord;
            printf("0:%d\n", s2[i]);//if true prints "0" and the character
        }
    }
    s[0] = '\0';
    s2[qttWord] = '\0';

    for (i = 0; i < qttWord; ++i){
        s[i] = s2[i];
    }
    s2[0] = '\0';
}

int main(){
    char line[MAX];
    int lgh = 0;

    while ((lgh = getLine(line, MAX)) != 0){
        trim(line, lgh);
        printf("%s\n", line);
        line[0] = '\0';
        lgh = 0;
    }
    return 0;
}

Name: Anonymous 2012-11-03 22:38

/**************************************************************************
Routine to get next line using platform fgets().

Under MSVC 6:

+ MS threadsafe getc is very slow (multiple layers of function calls before+
  after each character, to lock+unlock the stream).
+ The stream-locking functions are MS-internal -- can't access them from user
  code.
+ There's nothing Tim could find in the MS C or platform SDK libraries that
  can worm around this.
+ MS fgets locks/unlocks only once per line; it's the only hook we have.

So we use fgets for speed(!), despite that it's painful.

MS realloc is also slow.

Reports from other platforms on this method vs getc_unlocked (which MS doesn't
have):
    Linux               a wash
    Solaris             a wash
    Tru64 Unix          getline_via_fgets significantly faster

CAUTION:  The C std isn't clear about this:  in those cases where fgets
writes something into the buffer, can it write into any position beyond the
required trailing null byte?  MSVC 6 fgets does not, and no platform is (yet)
known on which it does; and it would be a strange way to code fgets. Still,
getline_via_fgets may not work correctly if it does.  The std test
test_bufio.py should fail if platform fgets() routinely writes beyond the
trailing null byte.  #define DONT_USE_FGETS_IN_GETLINE to disable this code.
**************************************************************************/

/* Use this routine if told to, or by default on non-get_unlocked()
 * platforms unless told not to.  Yikes!  Let's spell that out:
 * On a platform with getc_unlocked():
 *     By default, use getc_unlocked().
 *     If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
 * On a platform without getc_unlocked():
 *     By default, use fgets().
 *     If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
 */
#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
#define USE_FGETS_IN_GETLINE
#endif

#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
#undef USE_FGETS_IN_GETLINE
#endif

#ifdef USE_FGETS_IN_GETLINE
static PyObject*
getline_via_fgets(PyFileObject *f, FILE *fp)
{
/* INITBUFSIZE is the maximum line length that lets us get away with the fast
 * no-realloc, one-fgets()-call path.  Boosting it isn't free, because we have
 * to fill this much of the buffer with a known value in order to figure out
 * how much of the buffer fgets() overwrites.  So if INITBUFSIZE is larger
 * than "most" lines, we waste time filling unused buffer slots.  100 is
 * surely adequate for most peoples' email archives, chewing over source code,
 * etc -- "regular old text files".
 * MAXBUFSIZE is the maximum line length that lets us get away with the less
 * fast (but still zippy) no-realloc, two-fgets()-call path.  See above for
 * cautions about boosting that.  300 was chosen because the worst real-life
 * text-crunching job reported on Python-Dev was a mail-log crawler where over
 * half the lines were 254 chars.
 */
#define INITBUFSIZE 100
#define MAXBUFSIZE 300
    char* p;            /* temp */
    char buf[MAXBUFSIZE];
    PyObject* v;        /* the string object result */
    char* pvfree;       /* address of next free slot */
    char* pvend;    /* address one beyond last free slot */
    size_t nfree;       /* # of free buffer slots; pvend-pvfree */
    size_t total_v_size;  /* total # of slots in buffer */
    size_t increment;           /* amount to increment the buffer */
    size_t prev_v_size;

    /* Optimize for normal case:  avoid _PyString_Resize if at all
     * possible via first reading into stack buffer "buf".
     */
    total_v_size = INITBUFSIZE;         /* start small and pray */
    pvfree = buf;
    for (;;) {
        FILE_BEGIN_ALLOW_THREADS(f)
        pvend = buf + total_v_size;
        nfree = pvend - pvfree;
        memset(pvfree, '\n', nfree);
        assert(nfree < INT_MAX); /* Should be atmost MAXBUFSIZE */
        p = fgets(pvfree, (int)nfree, fp);
        FILE_END_ALLOW_THREADS(f)

        if (p == NULL) {
            clearerr(fp);
            if (PyErr_CheckSignals())
                return NULL;
            v = PyString_FromStringAndSize(buf, pvfree - buf);
            return v;
        }
        /* fgets read *something* */
        p = memchr(pvfree, '\n', nfree);
        if (p != NULL) {
            /* Did the \n come from fgets or from us?
             * Since fgets stops at the first \n, and then writes
             * \0, if it's from fgets a \0 must be next.  But if
             * that's so, it could not have come from us, since
             * the \n's we filled the buffer with have only more
             * \n's to the right.
             */
            if (p+1 < pvend && *(p+1) == '\0') {
                /* It's from fgets:  we win!  In particular,
                 * we haven't done any mallocs yet, and can
                 * build the final result on the first try.
                 */
                ++p;                    /* include \n from fgets */
            }
            else {
                /* Must be from us:  fgets didn't fill the
                 * buffer and didn't find a newline, so it
                 * must be the last and newline-free line of
                 * the file.
                 */
                assert(p > pvfree && *(p-1) == '\0');
                --p;                    /* don't include \0 from fgets */
            }
            v = PyString_FromStringAndSize(buf, p - buf);
            return v;
        }
        /* yuck:  fgets overwrote all the newlines, i.e. the entire
         * buffer.  So this line isn't over yet, or maybe it is but
         * we're exactly at EOF.  If we haven't already, try using the
         * rest of the stack buffer.
         */
        assert(*(pvend-1) == '\0');
        if (pvfree == buf) {
            pvfree = pvend - 1;                 /* overwrite trailing null */
            total_v_size = MAXBUFSIZE;
        }
        else
            break;
    }

    /* The stack buffer isn't big enough; malloc a string object and read
     * into its buffer.
     */
    total_v_size = MAXBUFSIZE << 1;
    v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
    if (v == NULL)
        return v;
    /* copy over everything except the last null byte */
    memcpy(BUF(v), buf, MAXBUFSIZE-1);
    pvfree = BUF(v) + MAXBUFSIZE - 1;

    /* Keep reading stuff into v; if it ever ends successfully, break
     * after setting p one beyond the end of the line.  The code here is
     * very much like the code above, except reads into v's buffer; see
     * the code above for detailed comments about the logic.
     */
    for (;;) {
        FILE_BEGIN_ALLOW_THREADS(f)
        pvend = BUF(v) + total_v_size;
        nfree = pvend - pvfree;
        memset(pvfree, '\n', nfree);
        assert(nfree < INT_MAX);
        p = fgets(pvfree, (int)nfree, fp);
        FILE_END_ALLOW_THREADS(f)

        if (p == NULL) {
            clearerr(fp);
            if (PyErr_CheckSignals()) {
                Py_DECREF(v);
                return NULL;
            }
            p = pvfree;
            break;
        }
        p = memchr(pvfree, '\n', nfree);
        if (p != NULL) {
            if (p+1 < pvend && *(p+1) == '\0') {
                /* \n came from fgets */
                ++p;
                break;
            }
            /* \n came from us; last line of file, no newline */
            assert(p > pvfree && *(p-1) == '\0');
            --p;
            break;
        }
        /* expand buffer and try again */
        assert(*(pvend-1) == '\0');
        increment = total_v_size >> 2;          /* mild exponential growth */
        prev_v_size = total_v_size;
        total_v_size += increment;
        /* check for overflow */
        if (total_v_size <= prev_v_size ||
            total_v_size > PY_SSIZE_T_MAX) {
            PyErr_SetString(PyExc_OverflowError,
                "line is longer than a Python string can hold");
            Py_DECREF(v);
            return NULL;
        }
        if (_PyString_Resize(&v, (int)total_v_size) < 0)
            return NULL;
        /* overwrite the trailing null byte */
        pvfree = BUF(v) + (prev_v_size - 1);
    }
    if (BUF(v) + total_v_size != p && _PyString_Resize(&v, p - BUF(v)))
        return NULL;
    return v;
#undef INITBUFSIZE
#undef MAXBUFSIZE
}
#endif  /* ifdef USE_FGETS_IN_GETLINE */

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List