在C中构造String

这是我用于从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() } 

数字200在程序开始时是未知的,它是使用IDE函数从内存中获取的,以从特定内存地址获取值。 像这样 :-

 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 ); 

这是一个简单的例子。 可能我会被投票:)

 #include  #include  #include  #include  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); } 

不使用动态分配

 #include  #include  #include  #include  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

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

OUTPUT

 *RV200# 

一些问题,我只处理ConvertToString()


尽管在处理字符串缓冲区问题方面做了一些尝试,但OP代码中存在太多漏洞。 考虑以下。

 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); ... 

pos == 100什么影响?
strlen(buf)可能会尝试查找没有空字符的字符数组的长度 – > UB。

pos > 100的影响是什么?
strncpy()尝试在buf的键之外写入数据。

迂腐: pos < 0的影响是什么?
strncpy()尝试在buf的键之外写入数据,因为pos被转换为过大的无符号数。


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

如果pos超过strlen(subject)什么影响
UB作为代码试图读取外部subject


重写尝试。 关键元素:包括传入扩展subject可用大小并确定字符串长度。 然后测试可接受性。 毕竟,移动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 }