![](/img/trans.png)
[英]Problem when reversing a string, it does not output the full reversed string
[英]Reversing a string in C does not output the reversed line
我试图在C中反转字符串。reverse函数只是将给定位置(在for循环中)的字符分配给temp对象。 我在程序中看不到任何逻辑错误,并且使用以下命令在gcc 4.7.2下成功编译了程序:
gcc -Wall -std=c99 reverse.c
重新创建问题:
1.)运行程序,然后在外壳中输入一个字符串
2.)输入完毕后,按Enter /和或EOF信号。
问题是既没有打印原始字符串,也没有反转字符串。 这也是K&R第二版的练习,如果您已经完成了该练习,则不胜感激。
我认为该错误是由于缺少null字符引起的,著名的printf需要以null结尾的字符串将输入输出到cin。 getline函数将一个空字符分配给数组的末尾,确保该空字符将是字符串中以printf结尾的第一个字符(因此不会打印任何字符/文字)。
#include <stdio.h>
#define MAXLINE 1000
int geline(char s[], int lim);
void reverse(char line[], int length);
int main()
{
char s[MAXLINE];
char t[MAXLINE];
int k, len;
while ((len = getline(s, MAXLINE)) > 0) {
if (len > 1)
reverse(s, len);
}
printf("%s", s);
return 0;
}
void reverse (char input[], int length)
{
char temp[MAXLINE];
int j = length;
for (int i = 0; i < length; ++i, --j) {
temp[i] = input[i];
input[i] = input[j];
input[j] = temp;
}
}
int getline(char s[], int lim)
{
int c, i;
for (i=0; (c=getchar()) != EOF && c!='\n'; ++i)
s[i] = c;
if (c== '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
有两个逻辑错误:
int j = length;
应该是int j = length - 1;
temp[i] = input[i] ... input[j] = temp;
对于最后一个错误,有两种方法:
temp
定义为单个char: char temp; ... temp = input[i]; input[i] = input[j]; input[j] = temp;
char temp; ... temp = input[i]; input[i] = input[j]; input[j] = temp;
temp
使用正确的索引: temp[i] = input[i]; input[i] = input[j]; input[j] = temp[i]
temp[i] = input[i]; input[i] = input[j]; input[j] = temp[i]
试试这个代码:
#include <stdio.h>
#define MAXLINE 1000
int geline(char s[], int lim);
void reverse(char line[], int length);
int main () {
char s[MAXLINE];
char t[MAXLINE];
int k, len;
while ((len = getline(s, MAXLINE)) > 0) {
if (len > 1)
reverse(s, len);
}
printf("%s", s);
return 0;
}
void reverse (char input[], int length) {
char temp;
int j = length - 1;
for (int i = 0; i < j; ++i, --j) {
temp = input[i];
input[i] = input[j];
input[j] = temp;
}
}
int getline (char s[], int lim) {
int c, i;
for (i=0; (c=getchar()) != EOF && c!='\n'; ++i)
s[i] = c;
if (c== '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
int j = length - 1; // Thanks to @chux
for (int i = 0; i < j; ++i, --j) { // or <= length / 2
char temp = input[i];
input[i] = input[j];
input[j] = temp;
temp是不需要的,并且不是完全正确使用的。
您两次交换值,这将在循环的后半部分恢复交换。 :)
您的原型geline
“ t”( geline
)。 因此,也许
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
被采取?
您可以使用此快速功能:
inline char * reverse(char *p)
{
char *save=p;
char *q = p;
while(q && *q) ++q;
for(--q; p < q; ++p, --q)
*p = *p ^ *q,
*q = *p ^ *q,
*p = *p ^ *q;
return save ;
}
(我使用-Wall -std=c99 -O3 -g
进行了编译, -g
允许使用gdb
)
这是我注意到的事情以及解决这些问题的一些方法。 我尝试过与您开始使用的样式非常接近(例如,我会将原型中的数组decls转换为指针,但这不是必须的)。
您的getline
原型缺少t
。
int getline(char s[], int lim);
在main
,实际上并不需要k
, t[MAXLINE]
,并且printf
应该在循环中,因此您会看到每个单词都被反转了。 请注意, printf
选择一个\\n
,因为下面的getline
将换行和EOF终止的行都转换为同一行(没有换行):
int main()
{
char s[MAXLINE];
int len;
while ((len = getline(s, MAXLINE)) > 0) {
if (len > 0)
reverse(s, len);
printf("%s\n", s);
}
return 0;
}
在上面, getline(s, MAXLINE)
可能是getline(s, sizeof(s) / sizeof(*s) - 1)
尽管再次注意栅栏错误(请注意- 1
)。
可以极大地改善reverse
功能,而不必担心xor跳过具有变量的疯狂(尽管Daffra的示例很有趣,尤其是它正确地停在中间)。 取而代之的是,有意识地索引到中间点才是明显的胜利。 在这与删除将temp
数组简化为一个临时字符之间,将保留您的常规样式。
void reverse (char input[], int length)
{
int max = length - 1; /* keep the final NUL in place */
for (int i = 0; i <= max / 2; ++i) {
char ch = input[i];
input[i] = input[max - i];
input[max - i] = ch;
}
}
在上面的代码中, gcc -O3
可以对代码进行认真的检查,因此没有真正的理由担心在每个循环测试中都要进行长除法等。例如, gdb
报告说i
本身已经自动优化,这很有趣。 首先编写良好的,易读的代码,对您的编译器有所信心,然后再进行优化。
最后, getline
受益于针对lim
测试(CRITICAL!),并将换行符转换为NUL。
int getline(char s[], int lim)
{
int i, c;
for (i=0; (i <= lim) && ((c=getchar()) != EOF) && (c != '\n'); ++i)
s[i] = c;
s[i] = '\0';
return i; /* return the index to the final NUL, same as length w/o it */
}
将MAXLINE
设置为10暂时表明该版本可以正常处理超长行,将它们分成两个单独的行而不会丢失任何字符。
请小心使用字符串,以非常清楚地决定您是要使用长度来描述它们,还是要使用结尾处的NUL索引来描述它们。 这会影响您如何表达循环,限制,变量名称等的方式,并且很明显地使它们混淆是栅栏错误的经典来源。
希望这可以帮助。
请看下面的代码:
#include <stdio.h>
#define MAXLINE 1000
int geline(char s[], int lim);
void reverse(char line[], int length);
int main()
{
char s[MAXLINE];
int len;
while ((len = geline(s, MAXLINE)) > 1) {
if (len > 1) {
reverse(s, len);
printf("%s", s);
}
}
return 0;
}
void reverse (char input[], int length)
{
char temp;
int j = length-1;
for (int i = 0; i < j; ++i, --j) {
temp = input[i];
input[i] = input[j];
input[j] = temp;
}
}
int geline(char s[], int lim)
{
int c, i;
for (i=0; (c=getchar()) != EOF && c!='\n'; ++i)
s[i] = c;
if (c== '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
此处仅需要进行2次更改,它将起到相反的作用。 内部功能反向只是这样做
int j = --length;
代替这个:
input[j] = temp; //you should use
input[j] = temp[i];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.