如何在“之后删除换行符”;ctime“;在C程序中?

如何在“之后删除换行符”;ctime“;在C程序中?,c,C,请容忍我,因为我对C编程还是个新手。当我运行此代码时: #include <time.h> #include <stdio.h> #include <unistd.h> int main(void) { while (1) { time_t mytime; mytime = time(NULL); printf("%s Hello world\n", ctime(&mytime));

请容忍我,因为我对C编程还是个新手。当我运行此代码时:

#include <time.h>
#include <stdio.h>
#include <unistd.h>

int main(void)
{
    while (1) {
        time_t mytime;
        mytime = time(NULL);
        printf("%s Hello world\n", ctime(&mytime));
        sleep(1);
    }
    return 0;
}
我想要的是这样的:

Wed Jan 18 02:32:32 2017
 Hello world
Wed Jan 18 02:32:33 2017
 Hello world
Wed Jan 18 02:32:34 2017
 Hello world
Wed Jan 18 02:32:32 2017 Hello world
Wed Jan 18 02:32:33 2017 Hello world
Wed Jan 18 02:32:34 2017 Hello world
Wed Jan 18 02:38:29 2017
 Hello worldWed Jan 18 02:38:30 2017
 Hello worldWed Jan 18 02:38:31 2017
 Hello worldWed Jan 18 02:38:32 2017
 Hello worldWed Jan 18 02:38:33 2017
我该怎么做

注: 如果我从
printf(“%s Hello world\n”,ctime(&mytime))中删除
\n
结果如下:

Wed Jan 18 02:32:32 2017
 Hello world
Wed Jan 18 02:32:33 2017
 Hello world
Wed Jan 18 02:32:34 2017
 Hello world
Wed Jan 18 02:32:32 2017 Hello world
Wed Jan 18 02:32:33 2017 Hello world
Wed Jan 18 02:32:34 2017 Hello world
Wed Jan 18 02:38:29 2017
 Hello worldWed Jan 18 02:38:30 2017
 Hello worldWed Jan 18 02:38:31 2017
 Hello worldWed Jan 18 02:38:32 2017
 Hello worldWed Jan 18 02:38:33 2017

ctime
函数将返回指向以换行符结尾的字符串的指针

从:

调用
ctime(t)
相当于
asctime(localtime(t))
。它转化为 将日历时间t转换为以null结尾的表单字符串 “1993年6月30日星期三21:49:08\n”

如果不需要换行符,则需要保存指针并在打印前删除换行符

char *t = ctime(&mytime);
if (t[strlen(t)-1] == '\n') t[strlen(t)-1] = '\0';
printf("%s Hello world\n", t);
用于格式化您自己的字符串:

#include <stdio.h>
#include <time.h>

int main(void)
{
    char buf[100];
    strftime(buf, 100, "%a %b %d %T %Y", localtime(&(time_t){time(NULL)}));
    printf("%s Hello world\n", buf);
}

您还应该检查strftime的返回值,零可能表示失败。

按照
fgets()之后建议的流行方式关闭
'\n'
。如果缺少
“\n”
,它甚至没有问题

char * ct = ctime(&mytime));
ct[strcspn(ct, "\n")] = '\0';
printf("%s Hello world\n", ct);

ctime()
名义上返回指向
static char some_name[26]的指针以下面的示例形式显示

Sun Sep 16 01:03:52 1973\n\0

C规范有一个限定符,用于限定
struct tm
字段值是否在其正常范围内,否则结果为UB。基于年份可能超出1000-9999范围的想法,这使得
'\n'
的固定位置有问题。

以下是两个简单的解决方案:

  • 存储由
    ctime()
    返回的指针,并用以下内容覆盖尾随的换行符:
#包括
#包括
#包括
内部主(空){
而(1){
时间是我的时间;
mytime=时间(空);
char*p=ctime(&mytime);
p[strcspn(p,“\n”)]='\0';
printf(“%s Hello world\n”,p);
睡眠(1);
}
返回0;
}
  • 更简单的是:只需打印
    ctime()
    返回的字符串的前24个字符:
#包括
#包括
#包括
内部主(空){
而(1){
时间是我的时间;
mytime=时间(空);
printf(“%.24s Hello world\n”,ctime(&mytime));
睡眠(1);
}
返回0;
}

我遇到了同样的问题,所以我想解决的办法是在
string.h
库中使用
strtok()
。这将省略
“\n”
,并在其前面存储整个令牌:

char *p = strtok(ctime(&mytime), '\n');

OP不希望在Hello World
之前换行;所需的输出包括它后面的输出。使用
strftime
而不是
ctime
。各位,你搞错了,请再看我的帖子。你必须将
ctime
的输出复制到某个字符串中,并将最后一个字符替换为
\0
@EugeneSh.:我明白了。
ctime
的格式定义良好;只需删除尾随的换行符。(这确实是一个愚蠢的添加
asctime
;换行符应该留给用户)但是它是否保证在不同的系统中是
\n
而不是
\r\n
,C标准还规定了
ctime
asctime
之间的上述等价性,以及
asctime
的输出格式。但是为什么测试
t[strlen(t)-1]='\n'
?如果代码不确信
'\n
结束了缓冲区,那么它就不应该确信
'\n'
甚至存在,并且坏字符串可能以
'\0'
开头,这导致UB带有
t[strlen(t)-1]
。更简单的解决方案,在所有情况下都有效:
t[strcspn(t,“\r\n”)]='\0'
它看起来确实比摆弄
ctime()
的静态缓冲区更合适。@Havenard
%a%b%d%T%Y
依赖于区域设置,
ctime()
不依赖于区域设置。@chux:具体来说,
%a
%b
依赖于区域设置;其他部分不是。@KerrekSB很好地使用了C99复合文本
(time\u t){time(NULL)}
,为
time()
返回的
time\u t
提供地址。ctime生成的日期格式是“Www-Mmm dd hh:mm:ss-yyyy”因此,您需要使用
%.24s
删除新行和结尾的空字符。@MattK:这一点很好!答案经修正。