web-dev-qa-db-ja.com

sprintfを使用して文字列を追加する方法は?

私はsprintfで深刻な問題に直面しています。

私のコードスニペットは次のとおりだと仮定します:

sprintf(Buffer,"Hello World");
sprintf(Buffer,"Good Morning");
sprintf(Buffer,"Good Afternoon");
.
.
.

数百のスプリント....

これが好きなら、上書きされます。

Sprintfを使用して上書きを回避するにはどうすればよいですか。最後にprintfを指定すると、すべての行が表示されます。

56
user46646

必要なもの:

sprintf(Buffer,"Hello World");
sprintf(Buffer + strlen(Buffer),"Good Morning");
sprintf(Buffer + strlen(Buffer),"Good Afternoon");

そしてもちろん、バッファを十分に大きくする必要があります。

96
anon
int length = 0;
length += sprintf(Buffer+length, "Hello World");
length += sprintf(Buffer+length, "Good Morning");
length += sprintf(Buffer+length, "Good Afternoon");

これは、エラーに対する耐性を備えたバージョンです。エラーが発生したときに陽気な方法で続行できる限り、エラーが発生したときに気にしない場合に役立ちます。

int bytes_added( int result_of_sprintf )
{
    return (result_of_sprintf > 0) ? result_of_sprintf : 0;
}

int length = 0;
length += bytes_added(sprintf(Buffer+length, "Hello World"));
length += bytes_added(sprintf(Buffer+length, "Good Morning"));
length += bytes_added(sprintf(Buffer+length, "Good Afternoon"));
64

安全のため(バッファーオーバーフロー)、snprintf()を使用することをお勧めします

 const int MAX_BUF = 1000; 
 char *バッファー= malloc(MAX_BUF); 
 
 int length = 0; 
 length + = snprintf(バッファ+長さ、MAX_BUF-長さ、「Hello World」); 
 length + = snprintf(バッファ+長さ、MAX_BUF-length、「おはよう」); 
 length + = snprintf(Buffer +長さ、MAX_BUF-length、「Good Afternoon」); 
29
Oleg Razgulyaev

snprintfcat()snprintf()ラッパー:

size_t 
snprintfcat(
    char* buf,
    size_t bufSize,
    char const* fmt,
    ...)
{
    size_t result;
    va_list args;
    size_t len = strnlen( buf, bufSize);

    va_start( args, fmt);
    result = vsnprintf( buf + len, bufSize - len, fmt, args);
    va_end( args);

    return result + len;
}
12
Michael Burr

sprintf()の戻り値を使用します

Buffer += sprintf(Buffer,"Hello World");
Buffer += sprintf(Buffer,"Good Morning");
Buffer += sprintf(Buffer,"Good Afternoon");
7
Jeegar Patel

sprintfstrcat など、必要なものに特化したメソッドがあるときに、文字列の連結にstrncatを使用する理由=?

6
SergGr

単に文字列リテラルを追加していますか?または、さまざまなデータ型(int、floatなど)を追加しますか?

これを独自の関数に抽象化する方が簡単かもしれません(以下ではC99を想定しています):

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

int appendToStr(char *target, size_t targetSize, const char * restrict format, ...)
{
  va_list args;
  char temp[targetSize];
  int result;

  va_start(args, format);
  result = vsnprintf(temp, targetSize, format, args);
  if (result != EOF)
  {
    if (strlen(temp) + strlen(target) > targetSize)
    {
      fprintf(stderr, "appendToStr: target buffer not large enough to hold additional string");
      return 0;
    }
    strcat(target, temp);
  }
  va_end(args);
  return result;
}

そして、あなたはそれを次のように使用します:

char target[100] = {0};
...
appendToStr(target, sizeof target, "%s %d %f\n", "This is a test", 42, 3.14159);
appendToStr(target, sizeof target, "blah blah blah");

等.

この関数はvsprintfから値を返します。これはほとんどの実装では、宛先に書き込まれたバイト数です。この実装にはいくつかの穴がありますが、いくつかのアイデアが得られるはずです。

3
John Bode

fmemopen(3)を探していると思います:

_#include <assert.h>
#include <stdio.h>

int main(void)
{
    char buf[128] = { 0 };
    FILE *fp = fmemopen(buf, sizeof(buf), "w");

    assert(fp);

    fprintf(fp, "Hello World!\n");
    fprintf(fp, "%s also work, of course.\n", "Format specifiers");
    fclose(fp);

    puts(buf);
    return 0;
}
_

動的ストレージがユースケースにより適している場合は、open_memstream(3)の使用に関するLiamの優れた提案に従うことができます。

_#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char *buf;
    size_t size;
    FILE *fp = open_memstream(&buf, &size);

    assert(fp);

    fprintf(fp, "Hello World!\n");
    fprintf(fp, "%s also work, of course.\n", "Format specifiers");
    fclose(fp);

    puts(buf);
    free(buf);
    return 0;
}
_
3
wkz

次の方法がうまく機能することがわかりました。

sprintf(Buffer,"Hello World");
sprintf(&Buffer[strlen[Buffer]],"Good Morning");
sprintf(&Buffer[strlen[Buffer]],"Good Afternoon");
2
McBartok

Strcatを使用 http://www.cplusplus.com/reference/cstring/strcat/

int main ()
    {
      char str[80];
      strcpy (str,"these ");
      strcat (str,"strings ");
      strcat (str,"are ");
      strcat (str,"concatenated.");
      puts (str);
      return 0;
    }




    Output:


    these strings are concatenated. 
1
arun pal

以下に示す単純な行を使用して、1つのバッファーに文字列を追加できます。

sprintf(Buffer,"%s %s %s","Hello World","Good Morning","Good Afternoon");
1
ravibhuva9955

小さな完全なコード例

フラットプレーンの使用stdio標準ライブラリのみ

#include <stdio.h>
int main()
    {
    char c[1024];
    int  i=0;

    i+=sprintf(c+i,"We "   );
    i+=sprintf(c+i,"Love " );
       sprintf(c+i,"Coding");

    printf("%s",c);
    }

出力:We Love Coding

0
PYK

PHP str append:str。str。.. etc.

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

int str_append(char **json, const char *format, ...)
{
    char *str = NULL;
    char *old_json = NULL, *new_json = NULL;

    va_list arg_ptr;
    va_start(arg_ptr, format);
    vasprintf(&str, format, arg_ptr);

    // save old json
    asprintf(&old_json, "%s", (*json == NULL ? "" : *json));

    // calloc new json memory
    new_json = (char *)calloc(strlen(old_json) + strlen(str) + 1, sizeof(char));

    strcat(new_json, old_json);
    strcat(new_json, str);

    if (*json) free(*json);
    *json = new_json;

    free(old_json);
    free(str);

    return 0;
}

int main(int argc, char *argv[])
{
    char *json = NULL;

    /*
    str_append(&json, "name: %d, %d, %d", 1, 2, 3);
    str_append(&json, "sex: %s", "male");
    str_append(&json, "end");
    str_append(&json, "");
    str_append(&json, "{\"ret\":true}");
    */

    int i;
    for (i = 0; i < 100; i++) {
        str_append(&json, "id-%d", i);
    }

    printf("%s\n", json);

    if (json) free(json);

    return 0;
}
0
Wei