如何从 char 数组中清除单个字符?
Posted
技术标签:
【中文标题】如何从 char 数组中清除单个字符?【英文标题】:How can I clear a single character from a char array? 【发布时间】:2020-01-10 07:17:05 【问题描述】:我正在尝试从数组中删除单个字符,而不使用 strcpy 等标准库函数。我该怎么办?
我想用制表符替换一组连续的空格,虽然我可以用制表符替换其中一个空格,但我不知道如何摆脱数组中的其余空格。我可以将“”类型转换为一个字符,这将删除它们,但 gcc 会引发一个关于“从指针转换为不同大小的整数”的警告。它运行良好,但警告让我认为有更好的方法来做到这一点。使用 '' 不起作用,因为 gcc 会抛出“空字符常量”错误。
使用空字符的示例代码
#include <stdio.h>
int main()
char str[10] = "gay\n\0";
str[1] = '';
printf("%s", str);
使用空字符串的示例代码,转换为字符
#include <stdio.h>
int main()
char str[10] = "gay\n\0";
str[1] = (char) "";
printf("%s", str);
第一个例子抛出错误“空字符常量”
第二个例子有效,但抛出警告“从指针转换为不同大小的整数”
【问题讨论】:
您不需要包含\0
。字符串文字已经以空值结尾。此外,您可能想要选择不同的测试字符串。
您需要将该字符后面的所有字符移到前面一个字符。你不能“删除”内存。
str[1] = (char) "";
无效,因为它尝试从 ""
(它是空字符串,char*
)到 char
的转换。如果您想在索引1
处nul-terminate,只需使用str[1] = 0;
(或者如果您喜欢字符表示,请使用str[1] = '\0';
)。记住双引号表示一个字符串,单引号表示一个字符。
【参考方案1】:
由于您决定在不使用标准库函数的情况下执行此操作,因此用 tab
字符 ('\t'
) 替换所有空格系列(包括一系列 1)的最简单方法是循环您的字符串使用一个变量来跟踪您当前是 in 还是 out 的一系列空格。
使用简单的int
作为标志变量(例如int in;
)并在读取空格时设置in = 1;
(真),然后每当您读取非空格的内容时设置in = 0;
(假)为指示您在字符串中读取的当前“状态”(例如,在空格中或不在空格中)然后当您在读取一系列空格后遇到第一个非空格字符时(例如,当您更改从in = 1;
到in = 0;
)。
当您遍历字符串中的每个字符时,只需保留两个指针,一个指向您当前的读取位置(例如p
),一个指向您当前的写入位置(例如wp
)。所以你有一个读指针和写指针。将两者都初始化到字符串的开头,然后在每次迭代时推进读取指针,如果不是空格,则写入每个字符不变,或者当in
从1
更改时,禁止写入所有空格字符并写入'\t'
到0
。看到它会有所帮助。
你可以这样做:
/** spaces2tab will convert all series of spaces in s to a '\t'.
* s must be mutable (writeable) and not const or a string-literal.
*/
void spaces2tab (char *s)
char *p = s, /* pointer to s -- for reading */
*wp = s; /* pointer to s -- for writing */
int in = 0; /* flag -- in/out series of spaces */
while (*p) /* loop over each char in s */
if (*p == ' ') /* if char is ' ' set in to 'true' */
in = 1;
else /* if other than space */
if (in) /* if was series of spaces */
*wp++ = '\t'; /* write a tab */
in = 0; /* set in 'false' */
*wp++ = *p; /* write current char */
p++; /* advance to next char */
if (in) /* if was in series of spaces at end */
*wp++ = '\t'; /* add tab at end */
*wp = *p; /* nul-terminate at current char */
(注意:以上内容会将所有前导空格转换为tab
,并将所有尾随空格转换为tab
。如果您愿意,可以根据需要进行修改以更改该行为去掉前导和尾随空格——留给你)
花时间研究逻辑并了解其工作原理。最好的方法是将要转换的字符串写在一张纸上,然后在每次迭代中跟踪 p
和 wp
点。 (没有捷径,不要在屏幕上做,拿出一张8.5x11的纸和铅笔写出来)
将要转换的字符串作为程序的第一个参数(或使用简单的默认字符串 " this is a test "
,如果没有给出参数)的完整示例可能类似于以下内容(注意手册 strcpy
是编写(scopy
)以符合您将字符复制到要转换的字符串的无库函数要求):
#include <stdio.h>
#define MAXC 128
/** spaces2tab will convert all series of spaces in s to a '\t'.
* s must be mutable (writeable) and not const or a string-literal.
*/
void spaces2tab (char *s)
char *p = s, /* pointer to s -- for reading */
*wp = s; /* pointer to s -- for writing */
int in = 0; /* flag -- in/out series of spaces */
while (*p) /* loop over each char in s */
if (*p == ' ') /* if char is ' ' set in to 'true' */
in = 1;
else /* if other than space */
if (in) /* if was series of spaces */
*wp++ = '\t'; /* write a tab */
in = 0; /* set in 'false' */
*wp++ = *p; /* write current char */
p++; /* advance to next char */
if (in) /* if was in series of spaces at end */
*wp++ = '\t'; /* add tab at end */
*wp = *p; /* nul-terminate at current char */
char *scopy (char *dest, const char *src)
char *p = dest; /* pointer to dest */
*dest = 0; /* set dest to empty-string */
if (!src) /* valdiate src not NULL or return NULL */
return NULL;
do /* loop copying chars from src to p */
*p++ = *src; /* (it will copy the nul-termining char) */
while (*src++);
return dest; /* return pointer to indicate success */
int main (int argc, char **argv)
char str[MAXC] = "",
*p = argc > 1 ? argv[1] : " this is a test ";
if (!scopy (str, p))
return 1;
spaces2tab (str);
printf ("original : '%s'\nconverted : '%s'\n", p, str);
使用/输出示例
$ ./bin/spaces2tab
original : ' this is a test '
converted : ' this is a test '
验证'\t'
转换
要验证正确的转换,请通过 hex-dump 程序运行您的输出,例如 hexdump
或 od
(每个操作系统都有类似的东西)
$ ./bin/spaces2tab | hexdump -Cv
00000000 6f 72 69 67 69 6e 61 6c 20 20 3a 20 27 20 20 74 |original : ' t|
00000010 68 69 73 20 20 20 69 73 20 61 20 20 20 20 20 20 |his is a |
00000020 74 65 73 74 20 20 20 20 27 0a 63 6f 6e 76 65 72 |test '.conver|
00000030 74 65 64 20 3a 20 27 09 74 68 69 73 09 69 73 09 |ted : '.this.is.|
00000040 61 09 74 65 73 74 09 27 0a |a.test.'.|
00000049
您可以在上面确认所有系列的空格(十六进制20
)已转换为单个tab
字符(十六进制09
)。
如果您还有其他问题,请告诉我。
【讨论】:
以上是关于如何从 char 数组中清除单个字符?的主要内容,如果未能解决你的问题,请参考以下文章