Arrays 如何在C中删除数组中的字符串
我正在尝试使用下面的代码从数组中删除字符串(名称)。Arrays 如何在C中删除数组中的字符串,arrays,c,string,Arrays,C,String,我正在尝试使用下面的代码从数组中删除字符串(名称)。 AddArray是从用户处获取数组,而RemoveArray是删除字符串 #include <stdio.h> #include <stdlib.h> #define LENGTH 5 unsigned char num = 0; unsigned char numact = 0; #include <string.h> #define STR_MAX_SIZE 255 #define Names 5 #d
AddArray
是从用户处获取数组,而RemoveArray
是删除字符串
#include <stdio.h>
#include <stdlib.h>
#define LENGTH 5
unsigned char num = 0;
unsigned char numact = 0;
#include <string.h>
#define STR_MAX_SIZE 255
#define Names 5
#define Groups 5
void AddArray() {
int i = 0;
char word[Names][30] = {""};
char word2[Groups][50] = {""};
for (i = 0; i < Names; i++) {
printf("--Input Name = ");
if (!fgets(word[i], sizeof word[i], stdin))
break;
size_t len = strlen(word[i]);
if (word[i][len - 1] == '\n')
word[i][--len] = 0;
printf("--Input Group = ");
if (!fgets(word2[i], sizeof word2[i], stdin))
break;
size_t len2 = strlen(word2[i]);
if (word2[i][len2 - 1] == '\n')
word2[i][--len2] = 0;
}
putchar('\n');
}
void RemoveArray() {
int position, i = 0, n = 5;
char word[Names][30];
char word2[Groups][50];
printf("Enter the location where you wish to delete name\n");
scanf("%d", &position);
if (position >= n + 1)
printf("Deletion not possible.\n");
else
{
for (i = position - 1; i < n - 1; i++)
{
word[Names][i] == word[Names][i + 1];
word2[Groups][i] == word2[Groups][i + 1];
printf("Resultant array:\n");
for (i = 0; i < n - 1; i++)
printf("%d, %s, %s\n", i, word[i], word2[i]);
}
}
}
不起作用(可能这不起作用),我的结果只删除最后一个字符串,因为(i=position-1;iif(strcmp(word[Names][i], word[Names][i+1]) == 0);
if(strcmp(word2[Groups][i], word2[Groups][i+1]) == 0);
“如何从C中的数组中删除字符串?”
以您提议的方式,这可能是不可能的。例如,从字符串数组中删除字符串意味着从该内存区域中删除所有字符内容。i、 e.将字符串的第一个字符设置为
NULL
,或将整个数组元素设置为NULL
,例如:memset(数组,0,数组大小)代码>。因为将null
字符串传递给printf将调用,所以这种方法将不起作用。
例如,以下代码可能看起来有效,但也可能起作用:
如果您真的想从字符串集合中删除一个字符串,那么可以这样做。执行此操作的一些步骤(带有链接)如下所示:
- ()
这种管理字符串的方法很难。因为您使用的是静态分配的数组,所以与现代编程方法相比,这是一种简单的方法。您最好使用动态内存分配和指针,以便能够在列表中添加和删除元组或行。您还可以实现LinkedList结构,因为它很容易管理节点,但实现起来有点困难。
但是如果您坚持使用这种基本方式,则必须逐个字符删除一行字符串,并对列表使用一些行计数,并对每行使用行可用性标志。对于两个都具有自动存储持续时间的2D数组,您有两个固定的内存块,在程序运行期间必须保持有效。不能在调用的函数中声明数组,因为在函数返回后,数组的存储将不再有效。(存储将在用于设置函数调用、函数堆栈帧的内存中创建,该内存将在函数返回时释放以供重用)相反,您需要在
main()
中声明数组,并将数组作为参数传递给需要它们的函数
至于是否可以使用2D数组,然后添加和删除字符串,当然可以。数组只是内存块,您可以根据需要有效地使用它们。要添加到数组中,只需将数组中包含的元素数作为附加参数传递给函数,以检查它们是否已满(传递一个指针,以便在函数中更新该地址处的值,并使更改在调用函数中可见——或者返回更新后的值并将其分配回调用方)
现在,您不希望在大型数据集上使用这种方法,因为每次删除时复制到阵列大小或行数是非常低效的。但是,如果用作少于几百行的so的学习练习,就可以了。阵列是否具有自动存储持续时间,或者是否使用分配的storag创建,都无关紧要在这段时间内,处理内存块中的内容基本上是相同的。验证并保护正在使用的内存的边界
要从数组中删除,只需检查要删除的索引是否为有效索引,并且是否在当前存储的元素中。如果是,只需将上面的每一行向下复制一行,并相应地更新存储的元素数。数组只是存储,供您使用
在了解如何执行此操作之前,让我们先了解一下定义。通常宏名称都是以大写形式定义的。您不需要接近现有的数量(除非您出于未显示的原因使用它们)。您可以修复此情况并将其缩小到所需的范围,类似于以下内容:
#define NROWS 5 /* simplify your constants */
#define MAXLEN 32 /* all upper-case */
#define LINLEN 1024
int addarray (char (*names)[MAXLEN], char (*groups)[MAXLEN], size_t *nmemb)
{
if (*nmemb == NROWS) { /* check array full */
puts ("\n(arrays full)\n");
return 0;
}
char line[LINLEN]; /* buffer to hold input */
size_t len; /* length of input */
fputs ("\n--Input Name = ", stdout); /* prompt for name */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
line[(len = strcspn(line, "\n"))] = 0; /* trim \n, save length */
if (len >= MAXLEN) { /* validate name fits */
fputs (" error: name exceeds storage\n", stderr);
return 0;
}
memcpy (names[*nmemb], line, len + 1); /* copy to names */
fputs ("--Input Group = ", stdout); /* prompt for group */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
line[(len = strcspn(line, "\n"))] = 0; /* trim \n, save length */
if (len >= MAXLEN) { /* validate name fits */
fputs (" error: group exceeds storage\n", stderr);
return 0;
}
memcpy (groups[(*nmemb)++], line, len + 1); /* copy to groups,
* increment nmemb */
return 1; /* return success */
}
虽然不是一个错误,但C通常避免使用camelCase
或MixedCase
变量和函数名,而是使用所有小写。这是风格问题,完全取决于您
您的addarray()
函数的编写方式与以下类似:
#define NROWS 5 /* simplify your constants */
#define MAXLEN 32 /* all upper-case */
#define LINLEN 1024
int addarray (char (*names)[MAXLEN], char (*groups)[MAXLEN], size_t *nmemb)
{
if (*nmemb == NROWS) { /* check array full */
puts ("\n(arrays full)\n");
return 0;
}
char line[LINLEN]; /* buffer to hold input */
size_t len; /* length of input */
fputs ("\n--Input Name = ", stdout); /* prompt for name */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
line[(len = strcspn(line, "\n"))] = 0; /* trim \n, save length */
if (len >= MAXLEN) { /* validate name fits */
fputs (" error: name exceeds storage\n", stderr);
return 0;
}
memcpy (names[*nmemb], line, len + 1); /* copy to names */
fputs ("--Input Group = ", stdout); /* prompt for group */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
line[(len = strcspn(line, "\n"))] = 0; /* trim \n, save length */
if (len >= MAXLEN) { /* validate name fits */
fputs (" error: group exceeds storage\n", stderr);
return 0;
}
memcpy (groups[(*nmemb)++], line, len + 1); /* copy to groups,
* increment nmemb */
return 1; /* return success */
}
(注意:大多数函数只是验证。您必须验证所有输入,并确保不会尝试写入超出数组边界的内容)
由于只有一个输入验证,removearray()
稍短。您可以编写类似以下内容的函数:
int removearray (char (*names)[MAXLEN], char (*groups)[MAXLEN], size_t *nmemb)
{
size_t loc, i;
char line[LINLEN]; /* buffer to hold input */
fputs ("enter location to remove: ", stdout); /* request idx to remove */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
if (sscanf (line, "%zu", &loc) != 1) { /* convert/VALIDATE! */
fputs (" error: invalid location input.\n", stderr);
return 0;
}
if (NROWS - 1 < loc || *nmemb <= loc) { /* validate location */
fputs (" error: position requested out of range.\n", stderr);
return 0;
}
for (i = loc + 1; i < *nmemb; i++) { /* loop from index above until end */
strcpy (names[i - 1], names[i]); /* overwrite row to remove */
strcpy (groups[i - 1], groups[i]); /* ditto */
}
(*nmemb)--; /* decrement no. of members in array */
return 1; /* return success */
}
示例使用/输出
练习代码时,您可以执行以下操作(使用任一输入完成时,只需在空行上按Enter键即可在该点停止输入):
或者,只需重复删除第一行,直到阵列为空,即可执行以下操作:
$ ./bin/array_addrem_row
--Input Name = my
--Input Group = pronoun
--Input Name = dog
--Input Group = animal
--Input Name = has
--Input Group = being-verb
--Input Name = fleas
--Input Group = insect
--Input Name = bummer!
--Input Group = adverb
(arrays full)
my pronoun
dog animal
has being-verb
fleas insect
bummer! adverb
enter location to remove: 0
enter location to remove: 0
enter location to remove: 0
enter location to remove: 0
enter location to remove: 0
enter location to remove: 0
error: position requested out of range.
(arrays empty)
这只是将数组操作保持在有效范围内所需的算法。包括prnarrays()
函数在内的完整代码如下所示:
#include <stdio.h>
#include <string.h>
#define NROWS 5 /* simplify your constants */
#define MAXLEN 32 /* all upper-case */
#define LINLEN 1024
int addarray (char (*names)[MAXLEN], char (*groups)[MAXLEN], size_t *nmemb)
{
if (*nmemb == NROWS) { /* check array full */
puts ("\n(arrays full)\n");
return 0;
}
char line[LINLEN]; /* buffer to hold input */
size_t len; /* length of input */
fputs ("\n--Input Name = ", stdout); /* prompt for name */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
line[(len = strcspn(line, "\n"))] = 0; /* trim \n, save length */
if (len >= MAXLEN) { /* validate name fits */
fputs (" error: name exceeds storage\n", stderr);
return 0;
}
memcpy (names[*nmemb], line, len + 1); /* copy to names */
fputs ("--Input Group = ", stdout); /* prompt for group */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
line[(len = strcspn(line, "\n"))] = 0; /* trim \n, save length */
if (len >= MAXLEN) { /* validate name fits */
fputs (" error: group exceeds storage\n", stderr);
return 0;
}
memcpy (groups[(*nmemb)++], line, len + 1); /* copy to groups,
* increment nmemb */
return 1; /* return success */
}
int removearray (char (*names)[MAXLEN], char (*groups)[MAXLEN], size_t *nmemb)
{
size_t loc, i;
char line[LINLEN]; /* buffer to hold input */
fputs ("enter location to remove: ", stdout); /* request idx to remove */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
if (sscanf (line, "%zu", &loc) != 1) { /* convert/VALIDATE! */
fputs (" error: invalid location input.\n", stderr);
return 0;
}
if (NROWS - 1 < loc || *nmemb <= loc) { /* validate location */
fputs (" error: position requested out of range.\n", stderr);
return 0;
}
for (i = loc + 1; i < *nmemb; i++) { /* loop from index above until end */
strcpy (names[i - 1], names[i]); /* overwrite row to remove */
strcpy (groups[i - 1], groups[i]); /* ditto */
}
(*nmemb)--; /* decrement no. of members in array */
return 1; /* return success */
}
void prnarrays (char (*names)[MAXLEN], char (*groups)[MAXLEN], size_t nmemb)
{
if (nmemb == 0) {
puts ("\n(arrays empty)\n");
return;
}
for (size_t i = 0; i < nmemb; i++)
printf ("%-20s %s\n", names[i], groups[i]);
}
int main (void) {
char names[NROWS][MAXLEN] = {""}, /* names */
groups[NROWS][MAXLEN] = {""}; /* groups */
size_t nmemb = 0; /* no. members in each */
while (addarray (names, groups, &nmemb)) {} /* add to both */
prnarrays (names, groups, nmemb); /* output both */
putchar ('\n');
while (removearray (names, groups, &nmemb)) {} /* remove from both */
prnarrays (names, groups, nmemb); /* output both */
}
#包括
#包括
#定义NROWS 5/*简化常数*/
#定义MAXLEN 32/*全大写*/
#定义LINLEN1024
int addarray(字符(*名称)[MAXLEN],字符(*组)[MAXLEN],大小\u t*nmemb)
{
如果(*nmemb==NROWS){/*检查数组已满*/
放置(“\n(数组已满)\n”);
返回0;
}
字符行[LINLEN];/*用于保存输入的缓冲区*/
大小\u t len;/*输入长度*/
fputs(“\n--Input Name=,stdout);/*提示输入名称*/
如果(!fgets)(第行,第行,
$ ./bin/array_addrem_row
--Input Name = my
--Input Group = pronoun
--Input Name = dog
--Input Group = animal
--Input Name = has
--Input Group = being-verb
--Input Name = fleas
--Input Group = insect
--Input Name = bummer!
--Input Group = adverb
(arrays full)
my pronoun
dog animal
has being-verb
fleas insect
bummer! adverb
enter location to remove: 4
enter location to remove: 0
enter location to remove:
(user canceled input)
dog animal
has being-verb
fleas insect
$ ./bin/array_addrem_row
--Input Name = my
--Input Group = pronoun
--Input Name = dog
--Input Group = animal
--Input Name = has
--Input Group = being-verb
--Input Name = fleas
--Input Group = insect
--Input Name = bummer!
--Input Group = adverb
(arrays full)
my pronoun
dog animal
has being-verb
fleas insect
bummer! adverb
enter location to remove: 0
enter location to remove: 0
enter location to remove: 0
enter location to remove: 0
enter location to remove: 0
enter location to remove: 0
error: position requested out of range.
(arrays empty)
#include <stdio.h>
#include <string.h>
#define NROWS 5 /* simplify your constants */
#define MAXLEN 32 /* all upper-case */
#define LINLEN 1024
int addarray (char (*names)[MAXLEN], char (*groups)[MAXLEN], size_t *nmemb)
{
if (*nmemb == NROWS) { /* check array full */
puts ("\n(arrays full)\n");
return 0;
}
char line[LINLEN]; /* buffer to hold input */
size_t len; /* length of input */
fputs ("\n--Input Name = ", stdout); /* prompt for name */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
line[(len = strcspn(line, "\n"))] = 0; /* trim \n, save length */
if (len >= MAXLEN) { /* validate name fits */
fputs (" error: name exceeds storage\n", stderr);
return 0;
}
memcpy (names[*nmemb], line, len + 1); /* copy to names */
fputs ("--Input Group = ", stdout); /* prompt for group */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
line[(len = strcspn(line, "\n"))] = 0; /* trim \n, save length */
if (len >= MAXLEN) { /* validate name fits */
fputs (" error: group exceeds storage\n", stderr);
return 0;
}
memcpy (groups[(*nmemb)++], line, len + 1); /* copy to groups,
* increment nmemb */
return 1; /* return success */
}
int removearray (char (*names)[MAXLEN], char (*groups)[MAXLEN], size_t *nmemb)
{
size_t loc, i;
char line[LINLEN]; /* buffer to hold input */
fputs ("enter location to remove: ", stdout); /* request idx to remove */
if (!fgets (line, LINLEN, stdin) || *line == '\n') { /* VALIDATE!, handle EOF */
puts ("\n(user canceled input)\n");
return 0;
}
if (sscanf (line, "%zu", &loc) != 1) { /* convert/VALIDATE! */
fputs (" error: invalid location input.\n", stderr);
return 0;
}
if (NROWS - 1 < loc || *nmemb <= loc) { /* validate location */
fputs (" error: position requested out of range.\n", stderr);
return 0;
}
for (i = loc + 1; i < *nmemb; i++) { /* loop from index above until end */
strcpy (names[i - 1], names[i]); /* overwrite row to remove */
strcpy (groups[i - 1], groups[i]); /* ditto */
}
(*nmemb)--; /* decrement no. of members in array */
return 1; /* return success */
}
void prnarrays (char (*names)[MAXLEN], char (*groups)[MAXLEN], size_t nmemb)
{
if (nmemb == 0) {
puts ("\n(arrays empty)\n");
return;
}
for (size_t i = 0; i < nmemb; i++)
printf ("%-20s %s\n", names[i], groups[i]);
}
int main (void) {
char names[NROWS][MAXLEN] = {""}, /* names */
groups[NROWS][MAXLEN] = {""}; /* groups */
size_t nmemb = 0; /* no. members in each */
while (addarray (names, groups, &nmemb)) {} /* add to both */
prnarrays (names, groups, nmemb); /* output both */
putchar ('\n');
while (removearray (names, groups, &nmemb)) {} /* remove from both */
prnarrays (names, groups, nmemb); /* output both */
}