0

文字列を別の文字列に挿入するサブルーチンを作成しようとしています。ホスト文字列にすべての文字を保持するのに十分な容量があることを確認し、そうでない場合はエラー整数を返します。これには 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);
}
4

3 に答える 3

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コードを単純化するためにそれを使用しました。)

于 2012-08-13T08:46:18.840 に答える
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;
}
于 2012-08-13T09:29:03.260 に答える
0

マクロを使用し、string_into_string を変更してサイズ引数の要件を含めようとしましたが、別の関数内から関数を呼び出すと、まだ三振になります。次のマクロを使用してみました。

#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追加する文字列が意図した内容を保持するのに十分な大きさであることを確認しないという点で、それを見ることも危険にさらされます(おそらくまったく同じ理由で)。

みんなの助けに感謝します。

于 2012-08-13T13:33:43.147 に答える