c - 挣扎于 C 字符串和 printf %s
问题描述
因此,很长一段时间以来,我一直在为 C 中的字符串(我猜很简单)问题而苦苦挣扎。
我想创建一个指针列表char
并为每个指针分配malloc()
一些内存以填充单个随机字符。最后我想对它们进行排序并用strcat()
.
所以在这段代码中,只有第一部分显示了一些测试函数:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("Error, too few arguments!\n");
return 0;
}
// initialize random generator
srand((unsigned int)time(NULL));
const int a = atoi(argv[1]);
char *array[a];
//--------------- generate random characters ----------------------------------------
for (int i = 0; i < a; i++) {
int r = rand() % 30 + 1;
printf("%d ", r);
array[i] = (char*)malloc(a + 1 * sizeof(char));
sprintf(array[i], "%ls", &r);
*(array[i] + 1) = '\0';
}
putchar('\n');
printf("%d %d %d \n", *array[0], *array[1], *array[2]);
char *array_2 = (char*) malloc(a * sizeof(char));
strcat(array_2, *array);
strcat(array_2, *(array + 1));
strcat(array_2, *(array + 2));
printf("Address array_2[0] : %p , value: %d \n", array_2, *array_2);
printf("Address array_2[1] : %p , value: %d \n", &array_2[1], array_2[1]);
printf("Address array_2[1] : %p , value: %d \n", &array_2[2], array_2[2]);
// produces a lot a garbage and crap
printf("array_2 with string : %s :\n", array_2);
// rest of the code omitted because it is irrelevant to the issue
return 0;
}
所以,我不明白的是:单独打印字符可以正常工作。如果我想将整个内容打印为字符串,我只会得到一个嘈杂的字符串。我怎样才能实现这个想法?
老实说,我不明白这个问题 - 如果我创建一个像char array[4] = {'a','b','c', '\0'}
我可以用“%s”打印整个内容的字符数组......但在我的程序中它几乎相同但不起作用。
如果有人能给我一个提示,我会很高兴!
解决方案
您的代码有几个问题:
- 数组的尺寸是错误的。中的
a
字符串array
将包含一个从 0 到 30 的随机数,因此每个字符串最多需要 3 个字节(两位数和空字符),但您分配a
字节。这些数字是不相关的。array_2
必须包含所有array
字符串的串联,因此它最多为2*a
字节长,并且最后需要一个额外的字节用于空字符。 - 你
sprintf
错了:sprintf(array[i], "%ls", &r)
试图将整数r
的地址解释为宽字符数组的地址。(这看起来好像你一直在摆弄格式和参数,直到编译器保持沉默。)要将数字打印r
到字符串,请使用sprintf(array[i], "%d", r)
. sprintf
将已经以空值终止您的字符串,因此无需明确执行此操作。- 正如鲁斯兰已经指出的那样,您
array_2
指向未初始化的内存。该函数strcat
需要一个以 null 结尾的字符串。您可以array_2
通过将第一个 char 设置为 null char 来生成有效的空字符串'\0'
。
为了修复您的代码,我建议以下内容:
- 做
array
一个大小为3的字符串数组。不要在堆上分配,而是在栈上做自动变量,这样更容易管理。 - 创建数字字符串时,请跟踪它们的长度。这些
*printf
函数有一个有用的返回值,即打印或写入字符串/文件的字符数。使用该长度为array_2
. - 初始化
array_2
为有效的空字符串,然后将strcat
所有array
字符串初始化为array_2
. array_2
用, 然后free
分配的内存做有趣的事情。
这是代码:
int a = 8;
char array[a][3];
int len = 0;
for (int i = 0; i < a; i++) {
int r = rand() % 30 + 1;
printf("%d\n", r);
len += sprintf(array[i], "%d", r);
}
char *array_2 = malloc(len + 1);
*array_2 = '\0';
for (int i = 0; i < a; i++) {
strcat(array_2, array[i]);
}
printf("\"%s\"\n", array_2);
free(array_2);
推荐阅读
- javascript - 如何在 Chrome 中加载下一页之前断开 websocket
- java - 使用 MediaStore.ACTION_IMAGE_CAPTURE 要求用户按 OK 或 RETRY
- r - 如何从 R 中的 for 循环返回绘图?
- acumatica - 复制到变量
- php - laravel 5.6 在资源响应中保留数组自定义键
- shell - 我可以在目录中删除 shell 中的文件,但是我从目录外部收到 File not found 错误
- java - 列计数与第 1 行 java 的值计数不匹配
- c++ - 从 input1 中查找 input2 中字符的位置
- elasticsearch - 使用运算符 AND 对多个单词进行多匹配查询
- angular - 如何使用 angular2 和 typescript 发送肥皂请求