通过指针的字符串(数组)容量

时间:2012-08-13 08:41:35

标签: c arrays string pointers size

我想创建一个将字符串插入另一个字符串的子例程。我想检查主机字符串是否有足够的容量来容纳所有字符,如果没有返回错误整数。这需要使用像sizeof这样的东西,但可以使用指针调用。我的代码在下面,我会非常乐于助人。

#include<stdio.h>
#include<conio.h>
//#include "string.h"

int string_into_string(char* host_string, char* guest_string, int insertion_point);

int main(void) {
    char string_one[21] = "Hello mother";    //12 characters
    char string_two[21] = "dearest ";        //8 characters
    int c;

    c = string_into_string(string_one, string_two, 6);
    printf("Sub-routine string_into_string returned %d and creates the string: %s\n", c, string_one);
    getch();
    return 0;
}

int string_into_string(char* host_string, char* guest_string, int insertion_point) {
    int i, starting_length_of_host_string;
    //check host_string is long enough
    if(strlen(host_string) + strlen(guest_string) >= sizeof(host_string) + 1) {
        //host_string is too short
        sprintf(host_string, "String too short(%d)!", sizeof(host_string));
        return -1;
    }

    starting_length_of_host_string = strlen(host_string);
    for(i = starting_length_of_host_string; i >= insertion_point; i--) {    //make room
         host_string[i + strlen(guest_string)] = host_string[i];
    }
    //i++;
    //host_string[i] = '\0';
    for(i = 1; i <= strlen(guest_string); i++) {    //insert
         host_string[i + insertion_point - 1] = guest_string[i - 1];
    }
    i = strlen(guest_string) + starting_length_of_host_string;
    host_string[i] = '\0';

    return strlen(host_string);
}

3 个答案:

答案 0 :(得分:1)

C不允许您将数组作为函数参数传递,因此类型T[N]的所有数组都会衰减为T*类型的指针。您必须手动传递大小信息。但是,您可以在呼叫站点使用sizeof来确定阵列的大小:

int string_into_string(char * dst, size_t dstlen, char const * src, size_t srclen, size_t offset, size_t len);

char string_one[21] = "Hello mother";
char string_two[21] = "dearest ";

string_into_string(string_one, sizeof string_one,   // gives 21
                   string_two, strlen(string_two),  // gives 8
                   6, strlen(string_two));

如果您使用malloc创建动态数组,则无论如何都必须将大小信息存储在某处,因此这个习惯用法仍然适用。

(请注意sizeof(T[N]) == N * sizeof(T),并且我已使用sizeof(char) == 1来简化代码的事实。)

答案 1 :(得分:0)

这段代码需要更多的错误处理,但应该做你需要的而不需要任何模糊的循环。为了加快速度,您还可以将源字符串的大小作为参数传递,因此该函数不需要在运行时计算它。

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

signed int string_into_string (char*       dest_buf, 
                               int         dest_size,
                               const char* source_str,
                               int         insert_index)
{
  int   source_str_size;
  char* dest_buf_backup;

  if (insert_index >= dest_size) // sanity check of parameters
  {
    return -1;
  }

  // save data from the original buffer into temporary backup buffer
  dest_buf_backup = malloc (dest_size - insert_index);
  memcpy (dest_buf_backup, 
          &dest_buf[insert_index], 
          dest_size - insert_index);

  source_str_size = strlen(source_str);

  // copy new data into the destination buffer
  strncpy (&dest_buf[insert_index], 
           source_str, 
           source_str_size);

  // restore old data at the end
  strcpy(&dest_buf[insert_index + source_str_size],
         dest_buf_backup);

  // delete temporary buffer
  free(dest_buf_backup);
}


int main()
{
  char string_one[21] = "Hello mother";    //12 characters
  char string_two[21] = "dearest ";        //8 characters

  (void) string_into_string (string_one,
                             sizeof(string_one),
                             string_two,
                             6);

  puts(string_one);

  return 0;
}

答案 2 :(得分:0)

我尝试使用宏并更改string_into_string以包含size参数的要求,但是当我从另一个函数中调用该函数时,我仍然会发现。我尝试使用以下宏:

#define   STRING_INTO_STRING( a, b, c) (string_into_string2(a, sizeof(a), b, c))

导致失败的另一个功能如下。这会失败,因为字符串已经成为指针,因此大小为4:

int string_replace(char* string, char* string_remove, char* string_add) {
    int start_point;
    int c;

    start_point = string_find_and_remove(string, string_remove);
    if(start_point < 0) {
        printf("string not found: %s\n    ABORTING!\n", string_remove);
        while(1);
    }
    c = STRING_INTO_STRING(string, string_add, start_point);
    return c;
}

看起来这个功能必须继续冒险。看着strcat它也会冒险,因为它不会检查你要附加的字符串是否足以容纳其预期内容(可能是出于同样的原因)。

感谢大家的帮助。