我正在尝试编写一个函数,将空格的所有跨度(即多个空格,换行符,制表符或上述任何连续序列)转换为单个空格。
例如,以下输入:
!541
都会产生相同的输出: “示例输入字符串”
我目前在Stack Overflow上有类似问题的代码如下(https://stackoverflow.com/a/1217750/6652030,第二个答案)。它正确处理多个空格的序列,但它不会按预期用空格替换制表符和换行符。如果我传递前两个示例输入,我的结果字符串是“exampleinputstring”。关于我哪里出错的任何想法?
"example\tinput\tstring"
"example\ninput\nstring"
"example \tinput \n string"
答案 0 :(得分:1)
您可以对代码进行以下修改:
void removeExtraWhitespace(char *dst, const char *src) {
for(; *src; ++dst, ++src) {
if (isspace(*src)) {
*dst = ' ';
while (isspace(*(src + 1))) {
++src;
}
} else {
*dst = *src;
}
}
*dst = '\0';
}
例如,
char dst[50];
$ removeExtraWhitespace(dst, "\t\t\texample\t\t\n input\nstring\n\n ");
$ printf("%s\n", dst);
example input string
答案 1 :(得分:0)
本质上,您将字符串复制到新位置,同时将所有空格(和换行符)字符折叠为单个字符(如果我理解正确的话)。
在复制时,您有三种可能的“操作模式”:
将其置于伪代码中,如下所示:
bool skipping = false;
for(each char){
if(iswhite(char)){
skipping = true;
continue; // next source char
}
// not a whitespace, let's see if we are done skipping
if(skipping){
// collapse all those skipped whitespaces into one
copy_space_into_dest;
}
skipping = false;
copy_char_into_dest;
}
上面的iswhite()
可能是对isspace()
或您自己的函数的调用,该函数将返回true
以查看它认为是空格的任何内容(例如,如果您确定为{ {1}}是一个“白色空间”)
答案 2 :(得分:0)
我提出的问题代码是:
static
void removeExtraWhiteSpace(char *src, char *dst)
{
while (*src != '\0')
{
if (!isspace((unsigned char)*src))
*dst++ = *src++;
else
{
*dst++ = ' ';
while (isspace((unsigned char)*src))
src++;
}
}
*dst = '\0';
}
对于每个字符,如果它不是来自isspace()
的{{1}}的空格,请将其复制到输出中。如果是空格,请将空格复制到输出,并跳过任何后续空格字符。完成后,添加null终止符。
函数是<ctype.h>
,因为我创建了所有函数static
,除非有一个标题声明函数用于其他文件 - 我使用的编译选项需要这个规则(或者先验static
函数声明 - 但extern void removeExtraWhiteSpace(char *src, char *dst)
更短。
如果你想删除前导和尾随空白,那就不难了:
static
测试代码:
static
void removeExtraWhiteSpace(char *src, char *dst)
{
char *tgt = dst;
while (isspace((unsigned char)*src))
src++;
while (*src != '\0')
{
if (!isspace((unsigned char)*src))
*tgt++ = *src++;
else
{
*tgt++ = ' ';
while (isspace((unsigned char)*src))
src++;
}
}
*tgt = '\0';
if (tgt > dst && tgt[-1] == ' ')
tgt[-1] = '\0';
}
平原输出:
static void test_string(char *buffer1)
{
printf("Before [%s]\n", buffer1);
char buffer2[1024];
removeExtraWhiteSpace(buffer1, buffer2);
printf("After [%s]\n", buffer2);
}
int main(void)
{
test_string("example\tinput\tstring");
test_string("example\ninput\nstring");
test_string("example \tinput \n string");
test_string(" \t spaces\t \tand tabs\tboth before\t\tand \t \t after \t\t ");
#ifdef GO_INTERACTIVE
char buffer[1024];
while (fgets(buffer, sizeof(buffer), stdin) != 0)
{
buffer[strcspn(buffer, "\n")] = '\0';
test_string(buffer);
}
#endif /* GO_INTERACTIVE */
return 0;
}
标记了标签和换行符(^ I表示标签,^ J表示换行符):
Before [example input string]
After [example input string]
Before [example
input
string]
After [example input string]
Before [example input
string]
After [example input string]
Before [ spaces and tabs both before and after ]
After [ spaces and tabs both before and after ]
答案 3 :(得分:0)
如何用C字符串中的单个空格替换空格的跨度?
只需跟踪上一个操作并测试空格。只需要1个紧密循环,一次调用package models;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
public static SessionFactory buildSessionFactory(){
try{
// Create the SessionFactory from hibernate.cfg.xml
System.out.println("creating SessionFactory using HibernateUtil.java");
SessionFactory f = new Configuration().configure().buildSessionFactory();
System.out.println("session created successfully");
return f;
} catch (Throwable ex){
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
。这也处理前导/尾随空格。
isspace()
关于我哪里出错的任何想法?
当OP的代码第一次遇到#include <ctype.h>
#include <stdbool.h>
void removeExtraWhitespace(const char *src, char *dst) {
bool previous_was_whitespace = false;
while (*src) {
if (isspace((unsigned char) *src)) {
if (!previous_was_whitespace) {
*dst++ = ' ';
}
previous_was_whitespace = true;
} else {
*dst++ = *src;
previous_was_whitespace = false;
}
src++;
}
*dst = '\0';
}
'\n'
时,它会更改'\t'
,但永远不会影响src[]
。
同时删除以下代码中的dst[]
。这允许在else
,'\n'
之后消耗连续的空格。然而,这仍然存在其他空白区域的问题,例如'\t'
。
'\r'
此代码使用if (*src == '\n' || *src == '\t') {
*src = ' ';
}
// else if (isspace(*src)) {
if (isspace(*src)) {
而不是isspace((unsigned char) *src)
,因为isspace(*src)
仅针对isspace()
范围和unsigned char
中的值定义。对于学习者计划,遇到EOF
的负值是不常见的,但它们可以存在,并且转换到*src
范围是谨慎的。