我正在对返回数组的函数进行一些测试,通过一些读取,我附带了以下内容:
#include <stdio.h>
#include <stdlib.h>
int i;
char * askData() {
static char data[5];
for(i = 0; i < 5; i++)
scanf("%s", &data[i]);
return data;
}
int main() {
char* data = askData();
printf("Flag 1\n");
for(i = 0; i < 5; i++)
printf("Loop %i: %s\n", i, &data[i]);
printf("Flag 2\n");
}我想要做的是分别从指针中打印每个元素(非常像数组,但我没有使用它,因为C函数单独不能返回数组)。
输入:
Harry
Hermione
Ronald
Draco
Voldemort预期产出:
Flag 1
Loop 0: Harry
Loop 1: Hermione
Loop 2: Ronald
Loop 3: Draco
Loop 4: Voldemort
Flag 2当前产出:
Flag 1
Loop 0: HHRDVoldemort
Loop 1: HRDVoldemort
Loop 2: RDVoldemort
Loop 3: DVoldemort
Loop 4: Voldemort
Flag 2发布于 2022-02-14 16:45:12
在printf("Loop %i: %s\n", i, %data[i]);中
您正在打印一个字符,这就是为什么%c是必需的,而不需要打印%。
printf("Loop %i: %c\n", i, data[i]); #include <stdio.h>
#include <stdlib.h>
char * askData() {
static char data[5];
for(i = 0; i < 5; i++)
scanf("%s", &data[i]);
return data;
}
int main() {
char* data = askData();
int i; //its better here
printf("Flag 1\n");
for(i = 0; i < 5; i++)
printf("Loop %i: %c\n", i, data[i]);
printf("Flag 2\n");
}发布于 2022-02-14 17:13:02
data是一个char的数组,只能容纳一个4char长的字符串。循环遍历每个试图在其中存储字符串的char of data是不正确的。您应该去掉askData中的循环,而是在循环中调用该函数,类似于下面的内容。
#include <stdio.h>
#include <stdlib.h>
#define NUM_NAMES 5
// no point in making i global
char * askData() {
// 5 chars can only hold a string of 4, not big enough for the names
// you indicated. Memory is cheap, use some
static char data[256];
// limit scanf to read one less than the size of data, so as not to overflow
scanf("%255s", data);
return data;
}
int main(void) {
printf("Flag 1\n");
// better practice to use size_t types when working with sizes
for(size_t i = 0; i < NUM_NAMES; i++){
// call askData in a loop. Each call will overwrite the data there from the previous call
char* data = askData();
// %zu is the correct format specifier for printing size_t type
printf("Loop %zu: %s\n", i, data);
}
printf("Flag 2\n");
}注意,如果您想保存每个输入而不是覆盖,您将需要一个2D数组,类似于data[NUM_NAMES][256];,那么您可以调用askData一次并在该函数中恢复循环,或者继续在循环中调用askData并作为参数传递字符串索引。
发布于 2022-02-14 17:24:06
所以你是对的,C不会像你所说的那样返回数组,但是我们在C中这样做的方式是将两种想法结合起来:
malloc,然后必须使用free调用来释放该内存区域。结合这些想法,我们可以得到数组:
因此,例如,如果您有一个由五个整数组成的数组,那么您将分配一个区域,即5 * sizeof(int);假设一个现代系统,sizeof(int)将是32位(或4个字节);所以您将得到一个20字节的内存区域,可以用这些值填充它。
#include <stdio.h>
#include <stdlib.h>
int * get_numbers(size_t count) {
int *data = malloc(count * sizeof(int));
if (!data) {
return NULL; // could not allocate memory
}
// notice that we are increasing the index i by 1
// data[i] shifts properly in memory by 4 bytes
// to store the value of the next input.
for(int i=0; i < count; i++) {
scanf("%d", &data[i]);
}
}
int main() {
int *data = get_numbers(5);
if (data == NULL) {
fprintf(stderr, "Could not allocate memory\n");
exit(-1);
}
for(int i = 0; i < 5; i++) {
printf("data[%d] = %d\n", i, data[i]);
}
free(data);
}现在,在您的例子中,您有一些复杂的(但不是真正的),您希望能够在名称中读取,这些名称是“字符串”,在C中除了作为字符数组之外,这些字符串并不真正存在。
因此,要重新表述我们的问题是,需要一个名称数组。每个名称本身都是一个字符数组。问题是,C还可以理解类型指针(是指向指针的指针),并且可以计算出指针算法。
所以我们可以有一个充满不同类型的内存区域;类型指针本身可以在一个内存区域中有一个指针列表;然后确保该列表中的每个指针都指向一个有效的内存区域本身。
#include <stdio.h>
#include <stdlib.h>
char *get_one_name() {
char *name = NULL;
size_t len = 0;
printf("Enter a name:");
// getline takes a pointer, which if it's set to NULL
// will perform a malloc internally that's big enough to
// hold the input value.
getline(&name, &len, stdin);
return name;
}
char ** get_names(size_t count) {
// this time we need memory region enough to hold
// pointers to names
char **data = malloc(count * sizeof(char *));
if (!data) {
return NULL; // could not allocate memory
}
for(int i=0; i < count; i++) {
data[i] = get_one_name();
}
return data;
}
void free_names(char **data, size_t count) {
for(int i = 0; i < count) {
if(data[i] != NULL) {
free(data[i]);
}
}
free(data);
}
int main() {
char **data = get_names(5);
if (data == NULL) {
fprintf(stderr, "Could not allocate memory\n");
exit(-1);
}
for(int i = 0; i < 5; i++) {
printf("data[%d] = %d\n", i, data[i]);
}
free_names(data, 5);
}希望这能给你一些想法。
https://stackoverflow.com/questions/71115196
复制相似问题