【问题标题】:Normalizing a char array and removing extra characters (truncating)规范化 char 数组并删除多余的字符(截断)
【发布时间】:2014-03-19 00:34:35
【问题描述】:

我有以下代码用于规范化 char 数组。在该过程结束时,规范化文件最后会保留一些旧的输出。这是为了ij 之前到达数组末尾。这是有道理的,但是如何删除多余的字符?我来自java,所以如果我犯了看似简单的错误,我深表歉意。我有以下代码:

/* The normalize procedure normalizes a character array of size len 
   according to the following rules:
     1) turn all upper case letters into lower case ones
     2) turn any white-space character into a space character and, 
        shrink any n>1 consecutive whitespace characters to exactly 1 whitespace

     When the procedure returns, the character array buf contains the newly 
     normalized string and the return value is the new length of the normalized string.

     hint: you may want to use C library function isupper, isspace, tolower
     do "man isupper"
*/
int
normalize(unsigned char *buf,   /* The character array contains the string to be normalized*/
                    int len     /* the size of the original character array */)
{
    /* use a for loop to cycle through each character and the built in c funstions to analyze it */
    int i = 0;
    int j = 0;
    int k = len;

    if(isspace(buf[0])){
        i++;
        k--;
    }
    if(isspace(buf[len-1])){
        i++;
        k--;
    }
    for(i;i < len;i++){
        if(islower(buf[i])) {
            buf[j]=buf[i];
            j++;
        }
        if(isupper(buf[i])) {
            buf[j]=tolower(buf[i]);
            j++;
        }
        if(isspace(buf[i]) && !isspace(buf[j-1])) {
            buf[j]=' ';
            j++;
        }
        if(isspace(buf[i]) && isspace(buf[i+1])){
            i++;
            k--;
        }
    }

   return k;

}

这是一些示例输出:

halb mwqcnfuokuqhuhy ja mdqu nzskzkdkywqsfbs zwb lyvli HALB MwQcnfuOKuQhuhy Ja mDQU nZSkZkDkYWqsfBS ZWb lyVLi

如您所见,结尾部分正在重复。结果中同时存在新的标准化数据和剩余的旧未标准化数据。我该如何解决这个问题?

【问题讨论】:

  • 看到(a)一个样本输入,(b)对应的样本输出,(c)正确样本输出,以及 (d) 所有这些数据只有这里提供的数据的 1/10,仍然会产生相同的问题,这将是非常可取的。如果您可以使用上述所有功能, 也可以轻松进行调试。
  • @WhozCraig 我将输出编辑得更短,以便更容易看到问题。在归一化部分之后,非归一化部分重复。
  • 谢谢。只是出于好奇,当这个作业发布时,您是否正在研究指针及其许多用途,因为 可以 在某种程度上是一种练习,可以让其中两个指针沿着缓冲区走下去。只是好奇。
  • @WhozCraig 我们在这个作业发布前几周研究了指针。虽然使用指针在某种程度上是赋值的一部分,但这不是赋值的目的。
  • 关于你的问题,可能和赋值参数本身一样简单。它没有说明终止字符串(即设置 nulchar 终止符);它只是说完成后返回最终长度。事实上,不能保证 input 被终止;为什么输出会这样?简而言之,您的代码可能已经正确,而您只是错误地显示了结果。这部分作业显然缺乏恕我直言。

标签: c arrays normalization truncate


【解决方案1】:

添加一个空终止符

k[newLength]='\0';
return k;

【讨论】:

  • 我相信你的意思是buf[j+1] = '\0' 这似乎确实实现了一个目标,但在数组的末尾添加了一个额外的字符(打印出来时末尾有一个 X)。我是不是加错了指针?
  • 注意:如果传递的缓冲区不是终止的字符串,并且缓冲区中的last字符不是双空格后缀,则可以调用 UB。
  • 这意味着如果一个没有空格并且以两个空格字符以外的任何字符结尾的打包缓冲区(因此后一个被修剪)将导致您写入 buf[len] 作为终止符。可寻址区域为buf[0...(len-1)]。将长度传递给此函数并非偶然。分配中没有关于任何被终止的内容。老实说,我认为问题出在 reporting 代码中,而不是算法(虽然我没有仔细审查算法,诚然)。请参阅我在一般评论中的链接了解我的意思。
  • 我很困惑...除了某些格式之外,我不熟悉任何需要 2 个空格字符的域。 http 标头等。如果将字符串“dog”复制到 char[4] 缓冲区中会有什么危险
  • 我显然没有说对。将字符串 dog 复制到长度为 4 的 char 缓冲区没有任何问题。在长度为 4 的字符缓冲区中 终止字符串 dog 存在重要问题3。这个函数可以给出。 char buf[3] = { 'd', 'o', 'g' }; normalize(buf,3); 分配中没有任何关于字符串终止的信息,您对缓冲区的了解是您需要处理 len 字符并返回 after 有多少个字符标准化(可能仍然是len)。老实说,我不能说得比这更清楚了。
【解决方案2】:

这样修复

int normalize(unsigned char *buf, int len) {
    int i, j;

    for(j=i=0 ;i < len; ++i){
        if(isupper(buf[i])) {
            buf[j++]=tolower(buf[i]);
            continue ;
        }
        if(isspace(buf[i])){
            if(!j || j && buf[j-1] != ' ')
                buf[j++]=' ';
            continue ;
        }
        buf[j++] = buf[i];
    }
    buf[j] = '\0';

    return j;
}

【讨论】:

    【解决方案3】:

    还是?添加空终止符

        k[newLength] = NULL;
        return k;
    

    【讨论】:

      猜你喜欢
      • 2015-01-12
      • 2013-02-13
      • 2012-01-12
      • 1970-01-01
      • 2019-04-19
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多