嗨,我在初学者级别,我正在使用变量参数函数的概念来连接字符串。对不同数量的字符串调用相同的函数。
我无法计算连接字符串的长度,这反过来意味着我没有正确分配内存。亲爱的同行们,请帮忙!
/* Program to do string concatenation using the concept of variable arguments */
/********************************************************************************
* REQUIRED HEADER FILES
*********************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdarg.h>
/********************************************************************************
* REQUIRED MACROS DEFINED
*********************************************************************************/
#define ERROR_CHECKER(result)\
if(result == FAILURE)\
{\
printf("\n CONCATENATION FAILED");\
}
typedef enum {SUCCESS = 0, FAILURE = 1} return_type;
/********************************************************************************
* REQUIRED FUNCTION PROTOTYPES
*********************************************************************************/
return_type string_concat(char* string_pointer, ...);
/********************************************************************************
*
* FUNCTION_NAME : STRING_CONCAT
*
* DESCRIPTION : concatenates incoming strings and displays the result
*
* RETURNS : SUCCESS OR FAILURE
*
*********************************************************************************/
return_type string_concat(
char* string_pointer,
...)
{
/********************************************************************************
* REQUIRED DECLARATIONS
*********************************************************************************/
// 1. arg_list that will point to variable number of arguments
va_list arg_list;
// 2. pointer to concatenated string
char* concatenated_string;
// 3. character pointer to point to an individual element in the argument list
char* individual_string_pointer;
// 4. amount of memory required to be allocated
int length;
/*********************************************************************************
* REQUIRED INITIALIZATIONS
*********************************************************************************/
va_start(arg_list, string_pointer);
concatenated_string = NULL;
individual_string_pointer = string_pointer;
length = 0;
/*********************************************************************************
* PERFORMING REQUIRED TASKS
**********************************************************************************/
// 1. calculate length till you reach quit
while(strcmp(individual_string_pointer,"quit") == 0)
{
individual_string_pointer = va_arg(arg_list, char*);
length = length + strlen(individual_string_pointer);
}
// individual_string_pointer reinitialized to be used for concatenation
individual_string_pointer = string_pointer;
printf("\nlength of concatenated string : %d", length);
// 2. allocate memory for the concatenated string
concatenated_string = (char*) malloc(sizeof(char) * length + 1);
// 3. use strncpy to copy first string and then use strncat to concatenate others
strncpy(concatenated_string, string_pointer, sizeof(*(string_pointer)));
while(strcmp(individual_string_pointer, "quit") == 0)
{
individual_string_pointer = va_arg(arg_list, char*);
strncat(concatenated_string, individual_string_pointer, sizeof(*(individual_string_pointer)));
}
printf("\n concatenated string : %s",concatenated_string);
va_end(arg_list);
return SUCCESS;
}
/********************************************************************************
*
* FUNCTION_NAME : MAIN
*
* DESCRIPTION : CALLS STRING_CONCAT FUNCTION
*
* RETURNS : SUCCESS
*********************************************************************************/
int main(void)
{
/********************************************************************************
* REQUIRED DECLARATIONS
*********************************************************************************/
// 1. character array as the first argument
char string_one[5] = "hello" ;
// 2. variable to store result from the string_concat function.
int result;
/*********************************************************************************
* REQUIRED INITIALIZATIONS
**********************************************************************************/
result = 0;
/*********************************************************************************
* PERFORMING REQUIRED TASKS
**********************************************************************************/
// 1. call string_concat function with 2 arguments
result = string_concat(string_one, "my", "name","is","amninder","quit");
// handle error from string_concat
ERROR_CHECKER(result);
// 2. call string_concat function with 3 arguments
result = string_concat(string_one, "I", "Like","fruits","quit");
// handle error from string_concat
ERROR_CHECKER(result);
// 3. call string_concat function with 4 arguments
result = string_concat(string_one, "awesome","quit");
// handle error from string_concat
ERROR_CHECKER(result);
/* doubt: do I need to send my first argument as same always " */
return SUCCESS;
}
答案 0 :(得分:2)
除了其他问题:此sizeof(*(individual_string_pointer)));
会返回individual_string_pointer
指向的大小,即char
,因此返回1.
使用strlen(ndividual_string_pointer)
代替,或者只是切换到使用strcat()
,如下所示:
strcat(concatenated_string, individual_string_pointer)
答案 1 :(得分:0)
您的第一个问题是您没有对数据做任何事情。你的第二个是一个循环规则,防止迭代参数列表两次。
将连接的字符串作为malloced内存返回,或者在失败时返回0
class InterfaceController2: WKInterfaceController, WCSessionDelegate{
var session: WCSession!
override func awake(withContext context: Any?) {
super.awake(withContext: context)
if (WCSession.isSupported()) {
session = WCSession.default()
session.delegate = self
session.activate()
}
}
func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
/// Capture data from ViewContorller 2
let engineFromPhone = message["engine"] as? String
// do something with engineFromPhone
}
}
答案 2 :(得分:0)
不是迭代va_list
两次,而是考虑realloc()
并附加每个子字符串。评论中的其他想法。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdarg.h>
#define return_type int
#define FAILURE -1
#define SUCCESS 0
// use const
return_type string_concat(const char* string_pointer, ...) {
va_list arg_list;
va_start(arg_list, string_pointer);
char* concatenated_string = NULL;
size_t length = 0; // Use type size_t, not int
const char* individual_string_pointer = string_pointer;
while (strcmp(individual_string_pointer, "quit")) {
// Find sub-string length _once_
size_t individual_length = strlen(individual_string_pointer);
size_t new_length = length + individual_length;
char *new_ptr = realloc(concatenated_string, new_length + 1);
if (new_ptr == NULL) {
free(concatenated_string); // do not forget to free old string
printf("\n MALLOC FALIED");
return FAILURE;
}
concatenated_string = new_ptr;
// or use memcpy(concatenated_string + length,
// individual_string_pointer, individual_length+1)
strcpy(concatenated_string + length, individual_string_pointer);
length = new_length;
individual_string_pointer = va_arg(arg_list, const char*);
}
va_end(arg_list);
// Add <> to detect leading/trailing white-space
printf("Concatenated string : <%s>\n", concatenated_string);
free(concatenated_string);
return SUCCESS;
}
int main(void) {
// not [5], let compiler size it to include the null character
char string_one[] = "hello";
string_concat(string_one, "my", "name", "is", "amninder", "quit");
string_concat(string_one, "I", "Like", "fruits", "quit");
return 0;
}
输出继电器
Concatenated string : <hellomynameisamninder>
Concatenated string : <helloILikefruits>
答案 3 :(得分:0)
你的方法不错,但可以改进,“退出”标记va_list结束不是很安全,NULL
是更好的选择。因为用户可以像“qui”,“qit”或其他什么一样“退出”。以及如何“退出”?如果你使用string_concat
而不知道当其中一个字符串“退出”时函数内部可能会提前停止:
char *string1 = "foo";
char *string2 = "quit";
char *string3 = "bar";
string_concat(string1, string2, string3, "quit");
仅使用“foo”。
您不会返回字符串generate,因此您的函数不是很有用。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#define END_STRING_CONCAT ((char const *)NULL)
char *string_concat(char const *first, ...);
char *string_concat(char const *first, ...) {
va_list ap;
va_start(ap, first);
va_list cp_ap;
va_copy(cp_ap, ap); // copy for future use
size_t size = 1; // need the size of the future string
for (char const *ptr = first; ptr != NULL; ptr = va_arg(ap, char const *)) {
size += strlen(ptr);
}
va_end(ap);
char *result = malloc(size);
if (result == NULL) {
va_end(cp_ap);
return NULL;
}
size_t used = 0;
for (char const *ptr = first; ptr != NULL; ptr = va_arg(cp_ap, char const *)) {
size_t len = strlen(ptr);
if (size < used || size - used < len) {
free(result);
va_end(cp_ap);
return NULL;
}
memcpy(result + used, ptr, len); // use memcpy because it's faster in this case
used += len;
}
va_end(cp_ap);
if (size < used || size - used != 1) {
free(result);
return NULL;
}
result[used] = '\0'; // don't forget
return result;
}
int main(void) {
char hello[] = "hello, ";
char *result1 = string_concat(hello, "my ", "name ", "is ", "amninder",
END_STRING_CONCAT);
if (result1 != NULL) {
printf("%s\n", result1);
free(result1);
}
char *result2 = string_concat(hello, "I ", "Like ", "fruits", END_STRING_CONCAT);
if (result2 != NULL) {
printf("%s\n", result2);
free(result2);
}
char *result3 = string_concat(hello, "awesome", END_STRING_CONCAT);
if (result3 != NULL) {
printf("%s\n", result3);
free(result3);
}
return 0;
}