Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何填充字符串大小可变的数组?_C_Arrays - Fatal编程技术网

C 如何填充字符串大小可变的数组?

C 如何填充字符串大小可变的数组?,c,arrays,C,Arrays,我需要建立一个硬币分配器应用程序。我已经编写了取款和寄存部分,但在项目库存创建中,我无法创建解决方案。项目名称应作为字符串从键盘中获取。与项目对应的项目价格应从键盘上取为unsigned ints 阵列应该是可变大小的,也称为VLA。我在谷歌上搜索了一下,找到了一些关于创建VLA的资源,我想我应该使用malloc动态地为它们分配内存。我不能这样做,所以我基本上使用BUFSIZ创建了有限大小的数组 在这种情况下,如何使用VLA,以及如何用字符串填充它们 我还应该防止缓冲区溢出。这将是第二种情况 宏

我需要建立一个硬币分配器应用程序。我已经编写了取款和寄存部分,但在项目库存创建中,我无法创建解决方案。项目名称应作为字符串从键盘中获取。与项目对应的项目价格应从键盘上取为
unsigned int
s

阵列应该是可变大小的,也称为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 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("");
...
}
void分发器main(char(*itemNames)[ITEM_NAME_LEN+1],未签名的int itemPrices[]
{
printf(“%s\n\n”,可用项目oo”);
printf(“%10s%15s%14s\n”、“#”、“项目名称”、“价格”);
printf(“%10s%15s%14s\n”、“=”、“================”、“=======”;
认沽权(“”);
unsigned int counterItemNames=0;//初始化计数器

对于(counterItemNames=1;counterItemNames,其中写入
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[]);

如果您想使用原始的
DispenderMain
语法,那么您必须分配一个指针数组,而不是像我所描述的那样使用二维数组。在这种情况下,您将使用
char**itemNames=malloc(itemQuantity*sizeof*itemNames)
和循环通过和
malloc
每个指针指向与您的问题无关的更多长度存储
ITEM\u NAME\u LEN+1

,但是处理数组上循环的通常方法是从零开始,并使用例如
counterItemNames
作为条件。然后您不必从t中减去一他在循环内部建立索引。你在某些地方这样做,但在其他地方不这样做,编程时的一致性很好。这将使代码更易于阅读和理解,特别是在几个月的时间内。你不需要
char**itemNames[BUFSIZ];
,因为它是一个太多级别的指针。你可以使用
char*itemNames[BUFSIZ]
。要获取VLA,您可以使用:
char itemNames[itemQuantity][ITEM_NAME_LEN+1];
未签名itemPrices[itemQuantity];
。根据定义,您不允许为VLA提供初始值设定项。请记住使用
%9s”
用于输入字符串以防止溢出。为什么ItemName是指向字符指针的指针数组?为什么不只是指向字符的指针数组。即使如此,谁分配了这些字符缓冲区?显然没有人…而且从来没有,从来没有,从来没有,从来没有,从来没有,从来没有使用
get()
。没有使用
get()的程序
可以抵御攻击,或保护自身免受溢出。它不再是标准C的一部分。您应该假设它会通过核心转储使您的程序崩溃。现在我已经完成了您所说的操作,但是我也遇到了相同的问题。它传递了第一项的名称。让我澄清一下,当我运行程序时,我可以成功地输入t项目数量、项目价格和项目名称(第一个除外)。此外,它不会以表格格式输出,价格以新行形式输出。还有一件事,程序传递第一个项目名称,它不会从键盘上获取任何字符串,也不会问它。#1来了,它直接去问#2项目名称。在输出第一个项目的名称时是空白的。你对此有何看法?我看你之前没有提到这个问题;你能描述一下你给出了什么输入,发生了什么,以及你预期会发生什么吗?用新代码在你的帖子上发布更新也是一个好主意(在最后做这件事,不要更改原始代码)
char (*itemNames)[ITEM_NAME_LEN+1];
itemNames = calloc( itemQuantity, sizeof *itemNames );
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[]);