简体   繁体   English

C 将每个字符添加到数组中

[英]C Adding each char into array

For C++ - I can add each char to each index in string array:对于 C++ - 我可以将每个char添加到string数组中的每个索引:

   string *x=new string[10];
    x[0] += "a";
    x[0] += "b";
    x[0] += "c";
    x[1] += "x";
    x[1] += "y";
    x[1] += "z";
    cout << "x[0]=" << x[0] << endl; // would be "abc"
    cout << "x[1]=" << x[1] << endl; // would be "xyz"

How can I do same functionality in C?如何在 C 中执行相同的功能? I have buff2 pointer to a char array and am trying to add char value from each index of buf .我有一个指向char数组的buff2指针,并试图从buf的每个索引添加char值。 I keep getting weird values when I print out buff2 value.当我打印出buff2值时,我不断得到奇怪的值。

char buf[255];
char *buff2;
int i=0, count=0;
buff2=(char*)malloc(512*sizeof(char));

  while((n = read(fd, buf, sizeof(buf[g]))) > 0){
    for(i=0; i<n; i++){
      if(buf[i] == '\n'){
        l++;
        count2++;
      }
       else
     {   
       buff2[count2]+=buf[i];
     }
  }

There are several problems in your C code你的C代码有几个问题

  • buff is an array for nothing because you only use buff[0] buff是一个空数组,因为你只使用buff[0]
  • the variable l seems never defined/initialized, and you modify it for nothing变量l似乎从未定义/初始化过,而您却白白修改了它
  • buff2[count2]+=buf[i]; always modify the same buff2[count2] until a newline because you do not increase buff2 in that case but only when reading a newline, are you sure you want that?总是修改相同的buff2[count2]直到换行,因为在这种情况下你不会增加buff2但只有在阅读换行时,你确定你想要那个吗?
  • you do not end buff2 with a null character, that probably explain I keep getting weird values when I print out buff2 value.你没有以 null 字符结束buff2 ,这可能解释了当我打印出 buff2 值时我总是得到奇怪的值。
  • you do not have a protection in case you write out of buff2 producing an undefined behavior你没有保护,以防你写出buff2产生未定义的行为

string *x=new string[10];

can be in C可以在C

char ** x = calloc(10, sizeof(char *));

I use calloc to initialize with null pointers我使用calloc来初始化 null 个指针

and an equivalent of:相当于:

 x[0] += "a";

can be

 strCat(&x[0], "a");

with:和:

char * const strCat(char ** p, const char * s)
{
   if (s != NULL) {
     if (*p == NULL)
       *p = strdup(s);
     else { 
       size_t len = strlen(*p);

       *p = realloc(*p, len + strlen(s) + 1); /* may be detect realloc returns NULL on error */
       strcpy(*p + len, s);
     }
   }

   return *p;
}

So for instance:例如:

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

char * const strCat(char ** p, const char * s)
{
   if (s != NULL) {
     if (*p == NULL)
       *p = strdup(s);
     else { 
       size_t len = strlen(*p);

       *p = realloc(*p, len + strlen(s) + 1); /* may be detect realloc returns NULL on error */
       strcpy(*p + len, s);
     }
   }

   return *p;
}

int main()
{
  char ** x = calloc(10, sizeof(char *));

  strCat(&x[0], "a");
  strCat(&x[0], "b");
  strCat(&x[0], "c");
  
  strCat(&x[1], "x");
  strCat(&x[1], "y");
  strCat(&x[1], "z");
  
  printf("x[0]=%s\n", x[0]);
  printf("x[1]=%s\n", x[1]);
  
  free(x[0]);
  free(x[1]);
  free(x);
  
  return 0;
}

Compilation and execution:编译执行:

% gcc -Wall a.c
% ./a.out
x[0]=abc
x[1]=xyz
%

Running under valgrind :valgrind下运行:

% valgrind ./a.out
==113490== Memcheck, a memory error detector
==113490== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==113490== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==113490== Command: ./a.out
==113490== 
x[0]=abc
x[1]=xyz
==113490== 
==113490== HEAP SUMMARY:
==113490==     in use at exit: 0 bytes in 0 blocks
==113490==   total heap usage: 7 allocs, 7 frees, 98 bytes allocated
==113490== 
==113490== All heap blocks were freed -- no leaks are possible
==113490== 
==113490== For counts of detected and suppressed errors, rerun with: -v
==113490== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
%

Note however each time you concatenate a new string it is needed to go through the current string to know its length, this is not done by std::string whose knows the used length whatever the way for that, as this is the case in the answer of KamilCuk但是请注意,每次连接一个新字符串时,都需要通过当前字符串到 go 才能知道它的长度,这不是由std::string完成的,它无论如何都知道使用的长度,因为这就是这种情况KamilCuk 的回答

How can I do same functionality in C?如何在 C 中执行相同的功能?

First implement/invent a "string".首先实现/发明一个“字符串”。

After that you can implement the functionality.之后,您可以实现该功能。 Remember about proper error handling.记住正确的错误处理。 I just used abort() for brevity below, in normal code destructors should be run.为了简洁起见,我只是在下面使用了abort() ,在正常的代码析构函数中应该运行。

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

typedef struct string {
    char *begin;
    char *end;
    size_t free;
} string;
void string_init(string *t) {
   t->begin = t->end = NULL;
   t->free = 0;
}
void string_fini(string *t) {
   free(t->begin);
}
// iadd convention from python
int string_iadd_cstr(string *t, const char *str) {
   const size_t addlen = strlen(str);
   if (t->free < addlen + 1) {
       const size_t curlen = t->end - t->begin;
       const size_t newlen = curlen + 1 + addlen;
       void *tmp = realloc(t->begin, newlen);
       if (tmp == NULL) {
           return -1;
       }
       t->begin = tmp;
       t->end = t->begin + curlen;
       t->free = newlen - curlen;
   }
   memcpy(t->end, str, addlen + 1);
   t->end += addlen;
   t->free -= addlen;
   return 0;
}
int string_print(string *t) {
    return printf("%s", t->begin);
}

int main() {
    // string *x=new string[10];
    string *x = malloc(10 * sizeof(*x));
    if (x == NULL) abort();
    for (size_t i = 0; i < 10; ++i) {
        string_init(&x[i]);
    }

    if (string_iadd_cstr(&x[0], "a")) abort();
    if (string_iadd_cstr(&x[0], "b")) abort();
    if (string_iadd_cstr(&x[0], "c")) abort();
    if (string_iadd_cstr(&x[1], "x")) abort();
    if (string_iadd_cstr(&x[1], "y")) abort();
    if (string_iadd_cstr(&x[1], "z")) abort();

    // cout << "x[0]=" << x[0] << endl;
    printf("%s", "x[0]=");
    string_print(&x[0]);
    printf("\n");
    fflush(stdout);

    // cout << "x[1]=" << x[1] << endl;
    printf("%s", "x[1]=");
    string_print(&x[1]);
    printf("\n");
    fflush(stdout);

    // run destructors
    for (size_t i = 0; i < 10; ++i) {
        string_fini(&x[i]);
    }
    free(x);
}

Here is a simple example if you do not want to use strcat .如果您不想使用strcat ,这是一个简单的示例。 This is a minimal example to demonstrate how one could concatenate strings, things like reallocation of memory have not been implemented.这是一个演示如何连接字符串的最小示例,尚未实现 memory 的重新分配等操作。

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

int main(void) {

    char buf[30] = "LOREM \n IPSUM DOLOR SIT AMET\0";
    char *buff2;
    int i = 0, n = 30;
    buff2 = (char*)malloc(512 * sizeof(char));

    //set first element of buff2 to be terminating null char
    buff2[0] = '\0';
    
    for(i = 0; i < n; i++) {
        if(buf[i] != '\n') {    
            buff2[i + 1] = '\0'; // shift terminating null char forward
            buff2[i] = buf[i];
        } else {
            buff2[i + 1] = '\0'; // shift terminating null char forward
            buff2[i] = 'n';
        }
    }
    
    printf("%s\n",buff2);
    
    return EXIT_SUCCESS;
}

It replaces newlines with an "n" character;它用“n”字符替换换行符; you can change this if you want.如果你愿意,你可以改变这个。 Of course, you want to be careful only to address elements which have actually been allocated.当然,您只想注意实际分配的地址元素。 Does not include function to read from file because we don't have the file;不包括 function 以从文件中读取,因为我们没有该文件; this is easily implemented.这很容易实现。 I suggest you look into fgetc .我建议你看看fgetc

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

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