将char数组中的单词转换为具有单个空格的行

时间:2019-01-27 16:35:16

标签: c arrays

将给定的char *input[]转换为具有单个空格的行

输入

int n =3;
char *result;
char *input[]= {"one", "two", "three" };
result = convertToLine(n, input)

代码

char *convertToLine(int n, char *input[]) {
    int size = n* 2;
    char* string = (char*)malloc(sizeof(char)*size);        
    int i = 0;
    int k = 0;
    while (i <size){
        string[i] = *input[k];         
        string[i+1] = ' ';
        i++;
        k++;
     }
   string[n] = '\0';
   return string;
}

我的输出:

预期产量

result = "one two three"

7 个答案:

答案 0 :(得分:1)

您的代码中有几个错误

  

int大小= n * 2;   char *字符串=(char *)malloc(sizeof(char)* size);

所需的 size 必须是最终大小,因此要合并更多空格位置和最终空字符的字符串长度的总和。 n *2只是字符串数的两倍,不一样

  

string [i] = * input [k];

不复制字符串,而仅复制其第一个字符

您可以这样做:

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

char *convertToLine(int n, char *input[]) {
  /* compute the needed size,
     of course can also use malloc then realloc to avoid that */
  int size = 0;
  int i;

  for (i = 0; i != n; ++i)
    size += strlen(input[i]) + 1;

  /* copy the strings */
  char * string = (char*)malloc(size); /* sizeof(char) is 1 by definition */
  char * p = string;

  for (i = 0; i != n; ++i) {
    strcpy(p, input[i]);
    p += strlen(p);
    *p++ = ' ';
  }
  p[-1] = 0;

  return string;
}


int main()
{
  char *input[]= {"one", "two", "three" };
  char * result = convertToLine(3, input);
  puts(result);

  free(result);
}

执行:

one two three

在valgrind下执行:

pi@raspberrypi:/tmp $ valgrind ./a.out
==14749== Memcheck, a memory error detector
==14749== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==14749== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==14749== Command: ./a.out
==14749== 
one two three
==14749== 
==14749== HEAP SUMMARY:
==14749==     in use at exit: 0 bytes in 0 blocks
==14749==   total heap usage: 2 allocs, 2 frees, 1,038 bytes allocated
==14749== 
==14749== All heap blocks were freed -- no leaks are possible
==14749== 
==14749== For counts of detected and suppressed errors, rerun with: -v
==14749== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

答案 1 :(得分:0)

每次迭代都需要将i增加2,因为如果将i增加1,您将继续覆盖空格并最终复制单词,并最终读取未初始化的内存。祝你好运:)

答案 2 :(得分:0)

如果我理解您的问题,那么您的问题是您无法分配字符串,例如

string[i] = *input[k];

以上,您尝试将第k个 指针的第一个字符分配给string[i],该字符的读取范围将超出input的结尾。等效于:

*(input[k] + 0)

input[k][0]

请参阅:C Operator Precedence

相反,您需要调用strcpy或简单地使用附加循环来复制每个所需的字符,例如

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

char *convertToLine (size_t n, char *input[])
{
    size_t  ndx = 0,        /* string index */
            len = 0;        /* length of combined strings */
    char *string = NULL;    /* pointer to string */

    for (size_t i = 0; i < n; i++)  /* length of all in input */
        len += strlen (input[i]);

    string = malloc (len + n);      /* allocate len + n-1 space + 1 */
    if (!string) {                  /* validate allocation */
        perror ("malloc-string");
        return NULL;
    }
    for (size_t i = 0; i < n; i++) {        /* for each string */
        if (i)                              /* if not 1st */
            string[ndx++] = ' ';            /* add space */
        for (int j = 0; input[i][j]; j++)   /* copy input string */
            string[ndx++] = input[i][j];
    }
    string[ndx] = '\0';     /* nul-terminate */
    return string;
}

在您的input上添加一个简短示例,您将具有:

int main (void) {
    char *input[]= {"one", "two", "three" },
        *result = NULL;
    size_t n = sizeof input / sizeof *input;

    result = convertToLine (n, input);
    if (result) {
        printf ("result: '%s'\n", result);
        free (result);
    }
}

使用/输出示例

$ ./bin/str_combind
result: 'one two three'

答案 3 :(得分:0)

char *arr_to_sentece(char **arr, size_t len)
{
    size_t mems = 0;
    char *sentence, *saveds; 

    for(size_t index = 0; index < len; index++)
        mems += strlen(arr[index]);
    mems += len - 1;
    sentence = malloc(mems + 1);
    if(sentence)
    {
        size_t wlen;

        saveds = sentence;
        while(len--)
        {
            wlen = strlen(*arr);

            strcpy(sentence, *arr++);
            sentence[wlen] = ' ';
            sentence += wlen + 1;
        }
        *sentence = 0;
    }
    return saveds;
}

答案 4 :(得分:0)

我接受了您的代码并进行了一些更改,一些先前的答案很好用,但是如果您想在不使用任何第三个lib函数的情况下实现此目的,这就是我的方法

#include <iostream>
using namespace std;

int getWordLength(const char input[]) {
    int cont = 0;
    int i = 0;
    //count the characters of the word, the last defining char always is '\0'
    while (input[i] != '\0') {
        cont++;
        i++;
    }
    return cont;
}

int getSentenceLength(int n, const char *input[]) {
    int sentenceLength = 0;
    //add the word length to the total sentence length
    for (int i = 0; i < n; i++) {
        sentenceLength += getWordLength(input[i]);
    }
    //add the spaces length
    sentenceLength += n;
    return sentenceLength;
}

void addWordToSentence(char* string, const char input[]) {
    int length = getWordLength(input); //get the word length

    //add the word to tha final sentence char by char
    int i = 0;
    int j = getWordLength(string);
    for ( ; i < length; i++, j++) {
        string[j] = input[i];
    }

    //add one space after the added word
    string[j] = ' ';
}

void cleanString(char* string, int size) {
    for (int i = 0; i < size; i++) {
        string[i] = '\0';
    }
}

char *convertToLine(int n, const char *input[]) {
    //get the total size
    int size = getSentenceLength(n, input);
    char* string = (char*)malloc(sizeof(char)*size);

    //clean the string with '\0'
    cleanString(string, size);

    int i = 0;
    while (i < n) {
        addWordToSentence(string, input[i]);
        i++;
    }

    string[size - 1] = '\0';
    return string;
}

int main() {
    int n = 3;
    char *result;
    const char *input[] = { "one", "two", "three" };
    result = convertToLine(n, input);
    cout << result;

    getchar();
    return 0;
}

经过测试并可以正常工作

enter image description here

答案 5 :(得分:0)

char *convertToLine(int size, char *input[]) {

   char *string = NULL;
   for(int i =0; i<size; i++)
   {

        int size_to_allocate = string != NULL ? strlen(string)+ strlen(input[i]) +2 : strlen(input[i]) +2;
        string = (char*)realloc(string, sizeof(char) * size_to_allocate);
        strcat(string, input[i]);
        if(i< size -1)strcat(string, " ");
   }
   return string;
}

答案 6 :(得分:-1)

您可以在需要时使用realloc来重新分配记忆,并连接需要的单词。

    char *convertToLine(int size, char *input[]) {

   char *string = NULL;
   for(int i =0; i<size; i++)
   {
        int size_to_allocate = string != NULL ? strlen(string)+ strlen(input[i]) : strlen(input[i]);
        string = (char*)realloc(string, sizeof(char) * size_to_allocate);
        strcat(string, input[i]);
        if(i< size -1)strcat(string, " ");
   }
   return string;
}