我尝试制作一个获取用户输入(行)的程序,并打印长度超过80个字符的最长行。我制作了这个程序,但是当我运行它时,它输出了一些非常奇怪的符号。你能告诉我我的代码可能有什么问题吗?
#include <stdio.h>
#define MINLINE 80
#define MAXLINE 1000
int getline(char current[]);
void copy(char from[], char to[]);
int main(void)
{
int len; // current input line lenght
int max; // the lenght of a longest line that's over 80 characters
char current[MAXLINE]; // current input line
char over80[MAXLINE]; // input line that's over 80 characters long
while (len = (getline(current)) > 0) {
if (len > MINLINE) {
max = len;
copy(current, over80);
}
}
if (max > 0) {
printf("%s", over80);
}
else {
printf("No input line was over 80 characters long");
}
return 0;
}
int getline(char current[]) {
int i = 0, c;
while (((c = getchar()) != EOF) && c != '\n') {
current[i] = c;
++i;
}
if (i == '\n') {
current[i] = c;
++i;
}
current[i] = '\0';
return i;
}
void copy(char from[], char to[]) {
int i = 0;
while ((to[i] = from[i]) != '\0') {
++i;
}
}
非常感谢你的帮助!
答案 0 :(得分:2)
max
。在if (max > 0)
中使用它是未定义的行为。
答案 1 :(得分:2)
这一行:
while (len = (getline(current)) > 0) {
将(getline(current)) > 0)
的值分配给len
,这不是您想要的(之后len将为0或1。
编辑:刚看到AusCBloke的评论,您还应检查len > max
和 len > MINLINE
,否则您将获得超过80个字符的最新行,而不是最长的整线。
您还应该将max
初始化为0,因此它应该是
max = 0;
while ((len = getline(current)) > 0) {
if ((len > MINLINE) && (len > max)) {
其他小错误/提示:
答案 2 :(得分:1)
假设这是一个家庭作业,这里有一个提示:这段代码看起来很可疑:
if (i == '\n') {
current[i] = c;
++i;
}
由于i
代表一个位置并且永远不会分配一个字符,因此您有效地检查位置是否等于'\n'
的ASCII代码。
答案 3 :(得分:1)
您的复制方法不会终止字符串:
void copy(char from[], char to[]) {
int i = 0;
while ((to[i] = from[i]) != '\0') {
++i;
}
to[i] = '\0'
}
这可能解释了正在打印的奇怪字符。
您可以使用内置strcpy()来简化生活。
答案 4 :(得分:0)
如果您提供的输入数据包含超过1000个字符的行,则会溢出固定大小的缓冲区。通过输入这样的输入,我能够实现以下输出:
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
答案 5 :(得分:0)
我现在无法测试您的代码,但可能是因为字符数组未被清除。尝试将char数组memset为0。
答案 6 :(得分:0)
您的代码存在许多问题。大多数情况下,他们都是轮胎改造。
int getline(char current[]);
您无需定义自己的getline()
,stdio.h
中已有一个。
void copy(char from[], char to[]);
在string.h
中还有许多复制字符串的功能。
初始化所有变量也是一个好主意,如下所示:
int len = 0; // current input line length
...这可以防止以后出现问题,例如在您未初始化问题时与max
进行比较。
如果你这样初始化max
......
int max = MINLINE; // the length of a longest line that's over 80 characters
...之后更容易进行长度比较。
char* current = NULL;
size_t allocated = 0;
如果current
为NULL
,则getline()
将分配一个缓冲区来存储该行,用户程序应为free
d。 getline()
还会指向size_t
,其中包含存储该行所需的字节数。
while (len = (getline(current)) > 0) {
应替换为以下内容......
while ((len = getline(¤t, &allocated, stdin)) > 0) {
...更新并将len
与0
进行比较。
现在,而不是......
if (len > MINLINE) {
...你需要与我们之前初步确定的最后一条线进行比较......
if (len > max) {
...然后你很高兴像你一样更新max
......
max = len;
您调用copy()
使用strncpy()
的地方,这会阻止您在分配的缓冲区中写入超过1,000个字符:
strncpy(over80, current, MAXLINE);
由于我们初始化了max
,因此您需要将结果从if (max > 0)
更改为if (max > MINLINE)
。
再提示一下,改变以下行......
printf("No input line was over 80 characters long");
...到...
printf("No input line was over %d characters long", MINLINE);
...意味着您只需更改文件顶部的#define
即可增加或减少最小长度。
别忘了......
free(current);
...防止内存泄漏!