【问题标题】:Why am I getting strange characters leading my substring?为什么我的子字符串前面有奇怪的字符?
【发布时间】:2015-06-16 22:12:31
【问题描述】:

我正在尝试在 C 中创建一个函数,该函数返回任何给定 char 数组的子字符串。它给了我大部分正确的输出,但我也在字符串的开头得到了一些奇怪的字符。例如,当给定输入“abcdefg”并要求输入 3 到 5 个字符时,它给了我“ÀvWdef”。所以看起来我正确地切断了 g ,但它只是对前 3 个字符做一些奇怪的事情,而不是忽略它们。我的代码如下:

typedef char * String;
String subStr(String src, int start, int end){

   if ((start > (strLen(src)-1)) || start < 0 || end < start ||
        (end > (strLen(src) - 1)) ){
       return NULL;
   }
   int s = start, e = end;
   String r = (String)malloc((e - s + 1) * sizeof(char));

   while(s <= e){
       r[s] = src[s];
       s++;
   }
   r[s] = '\0';

   return r;
} 

【问题讨论】:

  • 关于这一行:'String r = (String)malloc((e - s + 1) * sizeof(char));' 1) 在 C 中,不要从 malloc(和函数系列)中转换返回值 2) 在使用返回值之前始终检查 (!=NULL) 以确保操作成功。 3) sizeof(char) 总是1,所以乘以1是浪费代码。建议删除 '*sizeof(char)'
  • 如果 start == end,那么 malloc 显然是 1 个字符太短了。无论开始和结束之间的距离如何,这都适用。当 's' 最后一次递增,然后将 '\0' 分配到 's' 指向的当前位置,即超过分配缓冲区的末尾。这会导致未定义的行为,并且可能/将导致段错误事件
  • 使用's'作为'r[]'的偏移量意味着复制的数据将写入'r[]'数组的末尾,除非'start = 0'

标签: c arrays char substring


【解决方案1】:

你有一个逻辑错误:

while(s <= e){
   r[s] = src[s];
   s++;
}

src 的索引是正确的。但r 的索引不是。你需要另一个索引。

i = 0;
while(s <= e){
   r[i] = src[s];
   s++;
   i++
}

在循环之后,而不是:

r[s] = '\0';

使用:

r[i] = '\0';

使用malloc分配的字符数也有逻辑错误。

给定s = 3e = 5,您将返回一个由src[3]src[4]src[5] 组成的字符串。那是3个字符。添加终止空字符时,需要 4 个字符。 (e - s + 1) 只给你3。请改用(e - s + 2)

【讨论】:

  • 除了'R Sahu'指出的错误之外,如果您打算将startend 设为/inclusive/ 范围,那么您的malloc 将分配给一个字符/小于/比需要的。或者,如果您打算将其设为半开放范围(这是“标准”方式),那么您的 while 循环条件应为 while(s &lt; e),即严格不等式。
【解决方案2】:

我认为问题可能在这里:

r[s] = src[s];

改成

r[i++] = src[s];

其中i 跟踪字符串r 的索引,并初始化为0

【讨论】:

    【解决方案3】:

    当你用 malloc 分配一块内存时,它可以被任何东西填充,所以你最初应该向它写入零。

    bzero(r,e-s+1);
    

    此外,您还想从索引 0 而不是索引 s 开始复制到 r。你不应该同时使用 s。

    编辑更正

    for(i =0; i <= e-s;i++)
        r[i] = src[s + i];
    r[i] = '\0';
    

    【讨论】:

    • 这将复制要提取的字节数的 1 短。 (如果 start == end 则仍然需要复制一个字节。由于 'r[]' 中的每个字节都将被写入,因此无需初始化它(除了使调试更容易)和 malloc 的字节数太短了,因为后面的 '\0' 字节需要留出空间
    猜你喜欢
    • 2017-08-27
    • 1970-01-01
    • 2017-10-12
    • 2014-08-12
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    相关资源
    最近更新 更多