我需要构建一个投币器应用程序。我已经写了取款和存款部分,但在项目库存创建中我无法创建解决方案。项目名称应作为字符串从键盘中获取。对应于商品的商品价格应作为 unsigned int
从键盘获取。
数组应该是可变大小的,也就是 VLA。我用谷歌搜索并找到了一些关于创建 VLA 的资源,我认为我应该使用 malloc
动态地为它们分配内存。我做不到,所以我基本上使用 BUFSIZ
创建了有限大小的数组。
在这种情况下如何使用 VLA,以及如何用字符串填充它们?
我还应该防止缓冲区溢出。这将是第二种情况。
宏和代码块:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUMBER_OF_COINS 5
#define ITEM_NAME_LEN 9
...
void editorMain(void)
{
printf("Please enter the number of items: ");
scanf("%u", &itemQuantity);
printf("\n\n");
char ** itemNames[BUFSIZ] = {0};
unsigned int itemPrices[BUFSIZ] = {0};
printf("Please enter the names of items: \n");
for (int i = 0; i < itemQuantity; ++i) {
printf("#%d: ", i + 1);
gets(** itemNames[i]);
puts("");
}
printf("Please enter the prices of items: \n");
for (int i = 0; i < itemQuantity; ++i) {
printf("#%d: ", i + 1);
scanf("%u", &itemPrices[i]);
puts("");
}
dispenserMain(*itemNames, itemPrices);
return;
}
此外,程序应将项目名称和价格作为列表输出。函数 dispenserMain
执行以下操作:
void dispenserMain(char * itemNames[], unsigned int itemPrices[]) {
...
for (counterItemNames = 1; counterItemNames <= itemQuantity; ++counterItemNames) { //the for loop will print out the item name and prices with their correspondence.
printf("%10u.%14s%12.2f TL\n", counterItemNames, itemNames[counterItemNames - 1], currencyConverter(itemPrices[counterItemNames - 1]));
}
...
}
编辑(新代码):
void editorMain(void)
{
printf("Please enter the number of items: ");
scanf("%u", &itemQuantity);
printf("\n\n");
char itemNames[itemQuantity][ITEM_NAME_LEN+1];
memset(&itemNames, 0, sizeof(itemNames));
printf("Please enter the names of items: \n");
char line[ITEM_NAME_LEN+1];
for (int i = 0; i < itemQuantity; ++i) {
printf("#%d: ", i + 1);
if (! fgets(line, sizeof(line), stdin) || !line[0])
// abort...
// fgets leaves the trailing newline in the input
if (line[strlen(line)-1] == '\n') {
line[strlen(line)-1] = 0;
}
snprintf(itemNames[i], ITEM_NAME_LEN+1, "%s", line);
puts("");
}
unsigned int itemPrices[] = {0};
printf("Please enter the prices of items: \n");
for (int i = 0; i < itemQuantity; ++i) {
printf("#%d: ", i + 1);
scanf("%u", &itemPrices[i]);
puts("");
}
dispenserMain(itemNames, itemPrices);
return;
} //end globalMenuOut
输出:
Welcome to CoinedDispenser!
Author: Buğra Ekuklu
Contact: bugraekuklu [at] hotmail.de
1. Dispenser
2. Editing variables
3. Readme
Please make a choice: 2
Please enter the number of items: 3
Please enter the names of items:
#1:
#2: blabla
#3: glagla
Please enter the prices of items:
#1: 45
#2: 65
#3: 75
................... AVAILABLE ITEMS oo
# Item Name Price
= ========= ======
1.
0.45 TL
2. blabla
0.65 TL
3. glagla
0.75 TL
Enter your item selection:
分配器功能:
void dispenserMain(char (*itemNames)[ITEM_NAME_LEN+1], unsigned int itemPrices[])
{
printf("%s\n\n", " ................... AVAILABLE ITEMS oo");
printf("%10s%15s %14s\n", "#", "Item Name", "Price");
printf("%10s%15s %14s\n", "=", "=========", "======");
puts("");
unsigned int counterItemNames = 0; //initializing counter
for (counterItemNames = 1; counterItemNames <= itemQuantity; ++counterItemNames) { //the for loop will be print out the item name and prices with their correspondence.
printf("%10u.%12s%12.2f TL\n", counterItemNames, itemNames[counterItemNames - 1], currencyConverter(itemPrices[counterItemNames - 1]));
}
puts("");
...
}
最佳答案
你在哪里写 char ** itemNames[BUFSIZ] = {0};
应该是:
char itemNames[itemQuantity][ITEM_NAME_LEN+1];
这是一个 VLA,因为它有一个维度为已知的数组
运行。通过 malloc
分配的空间不是 VLA。
不幸的是,VLA 不能有初始值设定项,所以你也会有 写:
memset(&itemNames, 0, sizeof itemNames);
如果你想动态分配这个数组,它会是:
char (*itemNames)[ITEM_NAME_LEN+1];
itemNames = calloc( itemQuantity, sizeof *itemNames );
在这两种情况下,用法都是相同的。 itemNames[i]
指定您分配的数组。
您的代码 gets(** itemNames[i]);
有两个问题;它解引用空指针,并使用 gets
函数,允许用户导致缓冲区溢出。您应该读取数组 itemNames[i]
,在使用我上面的建议后,它指定了您分配的存储空间。
不幸的是,在 C 中只输入一个固定长度的字符串是很尴尬的。您必须担心如果用户键入的内容超过您的行长会发生什么。如果您不太关心这些,那么:
char line[BUFSIZ];
if ( ! fgets(line, sizeof line, stdin) || !line[0] )
// abort...
// fgets leaves the trailing newline in the input
if ( line[strlen(line)-1] == '\n' )
line[strlen(line)-1] = 0;
snprintf(itemNames[i], ITEM_NAME_LEN+1, "%s", line);
要调用您的函数,请执行以下操作:
dispenserMain(itemNames, itemPrices);
函数必须是
void dispenserMain(char (*itemNames)[ITEM_NAME_LEN+1], unsigned int itemPrices[]);
如果您想使用 dispenserMain
的原始语法,那么您必须分配一个指针数组,而不是像我所描述的那样使用二维数组。在这种情况下,您将使用 char **itemNames = malloc(itemQuantity * sizeof *itemNames);
并循环遍历和 malloc
每个指针指向更多的长度存储ITEM_NAME_LEN+1
。
关于c - 如何填充字符串可变大小数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23198981/