从文件中删除结尾和开头的空格

问题描述 投票:0回答:1

我正在尝试从长度未知的文本文件中读取行。在该行中可以有前导和尾随空格,直到出现字符串为止。因此,我的第一步是逐行读取并为字符串分配内存。然后删除所有前导和尾随空格。之后,我要检查字符串中是否包含空白字符,这是无效字符。例如,字符串看起来不能像这样"bad string",但是可以看起来像这样"goodstring"。但是,当我调用该函数删除前导空格和尾随空格时,它还会删除空格前后的字符。

有人可以告诉我我在做什么错吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NCHAR 64

char *readline (FILE *fp, char **buffer);
char *strstrip(char *s);


int main (int argc, char **argv) {

    char *line = NULL;
    size_t idx = 0;
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
    if (!fp) {
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    while (readline (fp, &line)) {  /* read each line in 'fp' */
        printf (" line[%2zu] : %s\n", idx++, line);
        free (line);
        line = NULL;
    }
    if (fp != stdin) fclose (fp);

    return  0;
}

/* read line from 'fp' allocate *buffer NCHAR in size
 * realloc as necessary. Returns a pointer to *buffer
 * on success, NULL otherwise.
 */
char *readline (FILE *fp, char **buffer) 
{
    int ch;
    size_t buflen = 0, nchar = NCHAR;
    size_t n;
    char *invalid_character = " ";

    *buffer = malloc (nchar);    /* allocate buffer nchar in length */
    if (!*buffer) {
        fprintf (stderr, "readline() error: virtual memory exhausted.\n");
        return NULL;
    }

    while ((ch = fgetc(fp)) != '\n' && ch != EOF) 
    {
        (*buffer)[buflen++] = ch;

        if (buflen + 1 >= nchar) {  /* realloc */
            char *tmp = realloc (*buffer, nchar * 2);
            if (!tmp) {
                fprintf (stderr, "error: realloc failed, "
                                "returning partial buffer.\n");
                (*buffer)[buflen] = 0;
                return *buffer;
            }
            *buffer = tmp;
            nchar *= 2;
        }
        strstrip(*buffer); //remove traiing/leading spaces
    }
    (*buffer)[buflen] = 0;           /* nul-terminate */


   if (invalid_character[n = strspn(invalid_character, *buffer)] == '\0') //check if a string has invalid character ' ' in it
    {
        puts(" invalid characters");

    } 

    if (buflen == 0 && ch == EOF) {  /* return NULL if nothing read */
        free (*buffer);
        *buffer = NULL;
    }

    return *buffer;
}
char *strstrip(char *s)
{
    size_t size;
    char *end;

    size = strlen(s);

    if (!size)
        return s;

    end = s + size - 1;
    while (end >= s && isspace(*end))
        end--;
    *(end + 1) = '\0';

    while (*s && isspace(*s))
        s++;

    return s;
}
c string malloc whitespace
1个回答
0
投票

您无需担心传递给strstrip()的字符串的长度,只需遍历字符串中的所有字符即可删除空格字符,例如以下版本从s中删除ALL空格:

/** remove ALL leading, interleaved and trailing whitespace, in place.
 *  the original start address is preserved but due to reindexing,
 *  the contents of the original are not preserved. returns pointer
 *  to 's'. (ctype.h required)
 */
char *strstrip (char *s)
{
    if (!s) return NULL;             /* valdiate string not NULL */
    if (!*s) return s;                    /* handle empty string */

    char *p = s, *wp = s;            /* pointer and write-pointer */

    while (*p) {                      /* loop over each character */
        while (isspace (*p))         /* if whitespace advance ptr */
            p++;
        *wp++ = *p;                            /* use non-ws char */
        if (*p)
            p++;
    }
    *wp = 0;    /* nul-terminate */

    return s;
}

仅删除多余的空格

以下版本删除前导和尾随空格,并将多个空格序列折叠为一个空格:

/** remove excess leading, interleaved and trailing whitespace, in place.
 *  the original start address is preserved but due to reindexing,
 *  the contents of the original are not preserved. returns pointer
 *  to 's'. (ctype.h required) NOTE: LATEST
 */
char *strstrip (char *s)
{
    if (!s) return NULL;             /* valdiate string not NULL */
    if (!*s) return s;                    /* handle empty string */

    char *p = s, *wp = s;            /* pointer and write-pointer */

    while (*p) {
        if (isspace(*p)) {                         /* test for ws */
            if (wp > s)               /* ignore leading ws, while */
                *wp++ = *p;         /* preserving 1 between words */
            while (*p && isspace (*p))         /* skip remainder  */
                p++;
            if (!*p)                     /* bail on end-of-string */
                break;
        }
        if (*p == '.')       /* handle space between word and '.' */
            while (wp > s && isspace (*(wp - 1)))
                wp--;
        *wp++ = *p;                            /* use non-ws char */
        p++;
    }
    while (wp > s && isspace (*(wp - 1)))     /* trim trailing ws */
        wp--;
    *wp = 0;    /* nul-terminate */

    return s;
}

note: s必须为mutable,因此不能为string-literal)] >>

© www.soinside.com 2019 - 2024. All rights reserved.