使用 C 在文本数组中插入和删除空格



我设法从一个程序创建了以下输出:

7.86 ( 8Hm,),  6.82 ( 4Hm,),12.1 ( 1Hs,).

我想添加一个空格或删除一个空格,具体取决于我指向的字符。sscanf会允许你这样做吗?

我只是想知道在此文本中插入和删除空格的最简单方法是什么。例如,我想删除 ( 和"num"(例如 8(之间的空格,但在 H 和"字母"之间提供一个空格,例如 m 。到目前为止,我的代码看起来像这样:

typedef struct node {
    int i;
    char array[SIZE];
    struct node* link;
} node;
node* format(void)
{      
    int count = 0;
    int size = list_size(data, sizeof(data)) / 4;
    for (node* ptr = head; ptr != NULL; ptr = ptr->link)
    {
        int i;
        int j; 
        for (i = 0, j = 0; i < sizeof(ptr->array); i++, j++)
        {             
            if (ptr->array[0] == ' ' && count == 0)
            {                
                count++;
                j--;               
            } 

            else if (ptr->array[i] == ' ' && ptr->array[i-1] == '.')
            {                
                j--;
                ptr->array[i] = ','; 
            }    

            else if (ptr->array[i] == ',' && ptr->array[i-1] == ')')
            {
                if (count == size)
                {                                   
                    ptr->array[i] = '.';
                }
            }        

            ptr->array[j] = ptr->array[i];
        }  
        count++;  

    } 
    return head; 
}

请注意,上面目前是一个大小为 3 的链表,我创建了后者以启用字符"组"的交换,然后以特定方式颠倒顺序。如果我先将所有内容传递回单个数组,格式化会更容易吗?

任何提示/建议将不胜感激!

最简单的方法是使用 sscanf 正确解析字符串,然后将其打印到另一个字符串。以您正在执行的方式手动解析字符串不会给您带来可观察到的速度/内存增益,只会添加大量代码。

#include<stdio.h>
int main(){
    char str[]= "7.86 ( 8Hm,),  6.82 ( 4Hm,),12.1 ( 1Hs,).";
    float f1, f2, f3;
    int i1, i2, i3;
    sscanf(str, "%f ( %dHm,),  %f ( %dHm,),%f ( %dHs,).", &f1, &i1, &f2, &i2, &f3, &i3);
    printf("%f ( %dHm,),  %f ( %dHm,),%f ( %dHs,).n", f1, i1, f2, i2, f3, i3);
    return 0;
}

scanf函数功能强大,如您所见,您可以使用它们来解析格式化的字符串。运行此示例中的代码时,它会打印以下内容:

7.860000 ( 8Hm,),  6.820000 ( 4Hm,),12.100000 ( 1Hs,).

它的工作方式是scanf可以忽略字符。因此,它读取第一个浮点数,然后忽略空格,忽略括号,读取整数,忽略 Hm 等等。

我的printf是按照与输入相同的方式格式化字符串。您可以对其进行调整以满足您的要求。您还应该四处搜索并限制十进制数字。但基本思想是,您可以从字符串中获取所需的数据,然后可以按照所需的方式打印该数据。

尽最大努力了解您当前在ptr-array中的内容,然后如何完成重新格式化,您似乎想要这样做in-place简单地更新ptr->array以保持更新的格式化字符串,然后您可以构建一个格式正确的缓冲区来替换当前ptr->array

注意:更好的解决方案是将ptr->array中的值分成实际的单独值,并将其作为链表的一部分,您可以在其中静态声明一个结构数组来保存您的valuesunits(这是我对7.86 (8Hm,)的最佳猜测。这将允许您以任何需要的方式格式化值,而不是停留在array中的内容。例如:

#define USIZE 8
typedef struct values {
    double value;
    char[USIZE];
} values;
typedef struct node {
    int i;
    char array[SIZE];
    values *vals;
    struct node* link;
} node;

或者,例如:

typedef struct node {
    int i;
    char array[SIZE];
    values vals[3];
    struct node* link;
} node;

无论如何,您最初的问题是如何重新格式化现有ptr->array删除'('后面的空格并将'8Hm'分隔到以下示例数据中'8H m'

7.86 ( 8Hm,),  6.82 ( 4Hm,),12.1 ( 1Hs,).

假设您正在迭代列表中的每个节点,则此重新格式化可能仅在收集/存储所有节点后运行一次。一种方法是以新格式构造一个新的缓冲区保存array,然后将新array替换为格式正确的buffer

是的,

有很多方法可以做到这一点,但是如果您的重新格式化条件有限,只需使用久经考验的英寸蠕虫方法用指针向下走array,用所需格式的字符填充新缓冲区就像其他任何东西一样简单和灵活。

下面,该示例创建一个新的缓冲区(buf[SIZE](从ptr->array中复制/替换/删除字符,然后将ptr->array替换为buf的内容。

注意:我没有在任何数据上运行它,所以您可能需要稍微调整一下逻辑。这只是为了向您展示一种可以使用的方法,并使其尽可能接近您的问题的解决方案(据我所知(。

注2:如果您不限于特定的标头,则可以将下面的大写/小写条件替换为isupperislower from ctype.h。此外,下面的memcpy将需要string.h,但如果这是一个问题,可以重写以简单地在没有它的情况下进行复制。

node* format(void)
{      
    /* for each node in list */
    for (node* ptr = head; ptr != NULL; ptr = ptr->link)
    {
        /* declare a pointer to `ptr->array` and `buf` */
        char *p = ptr->array;
        char *pend = p + SIZE;
        char buf[SIZE] = {0};
        char *bp = buf;
        /* for each char in ptr->array */
        while (p < pend)
        {
            /* if not the first char */
            if (p > ptr->array)
            {
                /* if current char is ' ' */
                if (*p == ' ')
                {
                    /* if previous char is one of the following */
                    if (*(p - 1) == '.') *bp++ = ',';
                    if (*(p - 1) == ')') *bp++ = '.';
                    if (*(p - 1) == '(') { p++; continue; } /* remove ' ' after '(' */
                }
                /* if current is lower case & prior is upper, separate */
                else if (('a' <= *(p - 1) && *(p - 1) <= 'z') && ('A' <= *p && *p <= 'Z'))
                {
                    *bp++ = ' ';
                    *bp++ = *p;
                }
                /* default - copy current to buf */
                else
                    *bp++ = *p;
            }
            p++;    /* advance to next char */
        }
        /* copy formatted string to ptr->array */
        memcpy (ptr->array, buf, SIZE);
    } 
    return head; 
}

注3:如果SIZE是全局#define,则将sizeof (ptr->array)替换为SIZE

相关内容

  • 没有找到相关文章

最新更新