分配一个未知大小的数组

3

背景:我想制作一个程序,它可以将文本作为输入并将其存储在字符数组中。然后我会将数组的每个元素打印成十进制数。例如,“Hello World”将被转换为72、101等。我将使用它作为快速的ASCII2DEC转换器。我知道有在线转换器,但我想自己制作一个。

问题:如何分配一个大小未知的数组,并使它与我输入的文本完全相同的大小?所以当我输入“Hello World”时,它会动态地创建一个确切大小的数组,只能存储“Hello World”。我已经搜索了网路,但找不到任何我可以利用的东西。


2
什么编程语言? :) - undefined
我正在尝试用C语言来做这个 :) - undefined
很高兴你的问题已解决!现在你应该接受一个正确的答案,并根据需要选择投票赞成或反对。更多信息请参考http://meta.stackexchange.com/a/5235和http://stackoverflow.com/faq#howtoask。 - undefined
4个回答

2

我看到你在使用C语言。你可以像这样做:

 #define INC_SIZE 10

 char *buf = (char*) malloc(INC_SIZE),*temp;
 int size = INC_SIZE,len = 0;
 char c;

 while ((c = getchar()) != '\n') { // I assume you want to read a line of input
   if (len == size) {
     size += INC_SIZE;
     temp = (char*) realloc(buf,size);
     if (temp == NULL) {
       // not enough memory probably, handle it yourself
     }
     buf = temp;
   }
   buf[len++] = c;
 }
 // done, note that the character array has no '\0' terminator and the length is represented by `len` variable

但是如果我输入的文本长度为7个字符,而缓冲区分配了10个字符,那该如何创建一个与你输入文本长度相同的数组呢? - undefined
1
真的吗?之后再简化一下。你以前做过编程吗?这是作业吗? - undefined
如果文件末尾没有'\n'会怎么样? - undefined
我没有从文件中读取。我只是输入一些文本,当我按下回车键(\n)时,while循环停止。 :) 希望现在清楚了。 - undefined
@wildplasser:这就是为什么我将其写作一个假设,需要根据实际情况进行调整。 - undefined
显示剩余3条评论

0
通常,在像个人电脑这样没有太大内存限制的环境中,我会动态分配一个数组/字符串/其他数据结构,比如64K,并保持一个指向当前末尾位置加一的索引/指针/其他变量,即下一个可以放置新数据的位置。

你能给我一个在C语言中如何做这个的例子吗?我真的很迷茫。:/ - undefined

0
如果你使用C++语言,你可以使用字符串来存储输入的字符,并通过operator[]访问字符,就像下面的代码一样:
std::string input;
cin >> input; 

我最初是从C++开始编程的,对于在C++中如何做这样的事情我比较熟悉,但现在我开始学习C,它有些不同。你会如何在C中实现这个? - undefined

0
我猜你指的是C语言,因为这是一种最常见的编译语言,你可能会遇到这个问题。
在函数中声明的变量存储在堆栈中。这样做既高效,而且在函数退出时会被清理掉等等。唯一的问题是,每个函数的堆栈槽大小是固定的,在函数运行时无法更改。
你可以分配内存的第二个地方是堆。这是一个自由区域,你可以在运行时分配和释放内存。你可以使用malloc()进行分配,完成后调用free()来释放它(这很重要,以避免内存泄漏)。
在堆分配中,你必须在分配时知道大小,但这比将其存储在固定的堆栈空间中更好,如果需要的话无法扩展。
这是一个简单而愚蠢的函数,使用动态分配的缓冲区将字符串解码为其ASCII代码:
char* str_to_ascii_codes(char* str)
{
    size_t i;
    size_t str_length = strlen(str);
    char* ascii_codes = malloc(str_length*4+1);
    for(i = 0; i<str_length; i++)
        snprintf(ascii_codes+i*4, 5, "%03d ", str[i]);
    return ascii_codes;
}

编辑:你在评论中提到希望将缓冲区调整到最佳状态。我在上面的示例中采取了捷径,通过使字符串中的每个条目具有已知长度,并且不修剪结果中多余的空格字符。这是一个更智能的版本,修复了这两个问题:

char* str_to_ascii_codes(char* str)
{
    size_t i;
    int written;
    size_t str_length = strlen(str), ascii_codes_length = 0;
    char* ascii_codes = malloc(str_length*4+1);
    for(i = 0; i<str_length; i++)
    {
        snprintf(ascii_codes+ascii_codes_length, 5, "%d %n", str[i], &written);
        ascii_codes_length = ascii_codes_length + written;
    }
    /* This is intentionally one byte short, to trim the trailing space char */
    ascii_codes = realloc(ascii_codes, ascii_codes_length);
    /* Add new end-of-string marker */
    ascii_codes[ascii_codes_length-1] = '\0';
    return ascii_codes;
}

1
谢谢。:) 在调用malloc()之后,是否真的需要将其转换为char*类型?这与你的示例无关,我只是想知道是否真的需要。:) 再次感谢! - undefined
不需要对void*进行强制转换,有些人甚至反对这样做。维基百科详细介绍了关于对malloc的类型安全性的争论:https://en.wikipedia.org/wiki/Malloc#Type_safety - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接