简体   繁体   English

用C构造String

[英]Construct String in C

Here is the demo code I am using to construct string from char arrays, Is there any better way to construct String *RV200# *FV200# ?? 这是我用来从char数组构造字符串的演示代码,有没有更好的方法来构造String *RV200# *FV200# ??

int main()
{    
char String4H1[10] = "*FV";
char String4H3[10] = "*RV";
char String4H2[10] = "#";

char data1[10];
char data2[10];

snprintf(data1,4, "%03d", 200); //Convert integer to string function
snprintf(data2,4, "%03d", 200); //Convert integer to string function

ConvertToString(String4H1,data1, 3);     //*FV200
ConvertToString(String4H3,data2, 3);     //*RV200

ConvertToString(String4H1,String4H2,6);   //*FV200#
ConvertToString(String4H3,String4H2,6);   //*RV200#

//Display String4H1 And String 4H3 

}


void ConvertToString(char subject[], const char insert[], int pos) 
{
char buf[100] = {};  
strncpy(buf, subject, pos);               // copy at most first pos characters
int len = strlen(buf);
strcpy(buf+len, insert);                 // copy all of insert[] at the end
len += strlen(insert);                  // increase the length by length of insert[]
strcpy(buf+len, subject+pos);          // copy the rest

strcpy(subject, buf);                 // copy it back to subject
                                 // deallocate buf[] here, if used malloc()
}

The number 200 is not known at the start of the program, it is fetched from memory using the IDE function to get value from particular memory address. 数字200在程序开始时是未知的,它是使用IDE函数从内存中获取的,以从特定内存地址获取值。 like this :- 像这样 :-

unsigned short BUF = GetWord(@FrontVIB@,0);    
unsigned short BUF1 = GetWord(@RearVIB@,0);

//BUF and BUF1 stores the value of address @FrontVIB@ and @RearVIB@ respectively

**structure** :-
unsigned short GetWord( @Address Alias@, Address Offset );

That's a simple example. 这是一个简单的例子。 Probably I'll be down-voted :) 可能我会被投票:)

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

bool concatenateString(char **dest, size_t *size, char *stringToAdd)
{
    bool retVal = true;
    char *dest_old = *dest;

    *size += strlen(stringToAdd);

    if (*dest == NULL)
    {
        *size += 1; // to add null terminator of string
        *dest = calloc(1, size);
    }
    else
    {
        *dest = realloc(*dest, size);
    }

    if (dest == NULL)
    {
        free(dest_old);
        retVal = false;
    }
    else
    {
        strcat(*dest, stringToAdd);
    }

    return retVal;
}

int main()
{
    char newString[32] = {0};
    int number;
    size_t size = 0;

    char *data1 = NULL;

    printf("Insert a string:");
    scanf(" %s", newString);
    if (concatenateString(&data1, &size, newString))
    {
        printf("Insert a number:");
        scanf(" %d", &number);
        sprintf(newString, "%03d", number);
        if (concatenateString(&data1, &size, newString) )
        {
            printf("Insert a string:");
            scanf(" %s", newString);
            if (concatenateString(&data1, &size, newString))
               printf("%s\n", data1);
        }
    }

    free(data1);
}

Without using dynamic allocation 不使用动态分配

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

bool concatenateString(char *dest, size_t size_of_dest, char *stringToAdd)
{
    bool retVal = true;

    size_t new_size = strlen(dest) + strlen(stringToAdd);

    if (new_size < size_of_dest)    
    {
        strcat(dest, stringToAdd);
    } 
    else
    {
        retVal = false;
    }
    return retVal;
}

int main()
{
    char result[128] = {0};
    char newString[32] = {0};
    int number;

    printf("Insert a string:");
    scanf(" %s", newString);
    printf("%s\n", newString);
    if (concatenateString(result, sizeof(result), newString))
    {
        printf("Insert a number:");
        scanf(" %d", &number);
        sprintf(newString, "%03d", number);
        if (concatenateString(result, sizeof(result), newString) )
        {
            printf("Insert a string:");
            scanf(" %s", newString);
            if (concatenateString(result, sizeof(result), newString))
               printf("%s\n", result);
        }
    }
}

INPUT INPUT

Insert a string: *RV
Insert a number: 200
Insert a string: #

OUTPUT OUTPUT

*RV200#

A number of issues, I am only tackling ConvertToString() 一些问题,我只处理ConvertToString()


Although some attempts made at coping with string buffer issues, too many holes exist in OP's code. 尽管在处理字符串缓冲区问题方面做了一些尝试,但OP代码中存在太多漏洞。 Consider the following. 考虑以下。

void ConvertToString(char subject[], const char insert[], int pos) {
  char buf[100] = {};  
  strncpy(buf, subject, pos);               // copy at most first pos characters
  int len = strlen(buf);
  ...

What is the impact of pos == 100 ? pos == 100什么影响?
strlen(buf) may attempt to find the length of a character array with no null character --> UB. strlen(buf)可能会尝试查找没有空字符的字符数组的长度 - > UB。

What is the impact of pos > 100 ? pos > 100的影响是什么?
strncpy() attempts to write data outside the bonds of buf . strncpy()尝试在buf的键之外写入数据。

Pedantic: What is the impact of pos < 0 ? 迂腐: pos < 0的影响是什么?
strncpy() attempts to write data outside the bonds of buf as pos is converted into an excessive large unsigned number. strncpy()尝试在buf的键之外写入数据,因为pos被转换为过大的无符号数。


Concerning strcpy(buf+len, subject+pos); 关于strcpy(buf+len, subject+pos);

What is the impact if pos exceeds strlen(subject) 如果pos超过strlen(subject)什么影响
UB as code attempts to read outside subject . UB作为代码试图读取外部subject


Re-write attempt. 重写尝试。 The key elements: include the size available for the expanded subject is passed in and determine string lengths. 关键元素:包括可用于扩展subject的大小并确定字符串长度。 Then test for acceptability. 然后测试可接受性。 After all that, shift the end of subject to make room for insert . 毕竟,移动subject的末尾为insert腾出空间。

void ConvertToString(char subject[], size_t subject_size, const char *insert,
    size_t pos) {

  size_t insert_length = strlen(insert);
  size_t subject_length = strlen(subject);
  // Insure pos does not exceed subject_length, 
  // this critical part missing in OP code 
  if (pos > subject_length) {
    pos = subject_length;
  }

  // Insure we have enough space
  size_t buf_size = subject_length + insert_length + 1;
  if (buf_size > subject_size) {
    Handle_Insufficent_subject_size();
    return;
  }
  // Move end portion of `subject` over to the right `insert_length` places.
  memmove(subject + pos + insert_length, subject + pos, subject_length - pos + 1);
  memcpy(subject + pos, insert, insert_length); // copy insert
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM